증권 거래소 KoTH


23

주식 시장은 지식의 속도에 관한 것입니다. 이전의 도전과 달리 현재 주가는 무작위가 아닙니다. 게임을하는 사람들에 의해 결정됩니다. 다른 사람보다 저렴한 주가를 식별 할 수 있다면 돈 버는 프로그램을 작성한 것입니다.

가격 은 사람들이 주식을 얼마나 거래하고 있는지를 나타내며, Value 는 게임이 끝날 때 주식의 가치를 나타냅니다.

각 플레이어는 각 주식의 1000으로 시작하고 상대적인 순 가치는 0입니다. 각 주식은 비밀 값을 가지며 게임이 끝날 때의 점수는(stockValue for each ownedStock) + netWorth 입니다. 순 가치는 부정적 일 수 있습니다. N- 플레이어 게임에는 N 개의 주식이 있습니다.

단계 :

게임은 다음 단계를 따릅니다.

  1. 단일 주식의 비밀 가치가 부여됩니다.
  2. X의 Y 주식을 $ Z에 판매하겠다고 제안합니다.
  3. 모든 플레이어에게 제안이 주어지며 각 플레이어는 수락 할 것을 선택할 수 있습니다
  4. 모든 플레이어에게 수락 된 오퍼에 대한 정보가 제공됩니다.
  5. 2 단계로 돌아 가기

각 단계는 아래에 자세히 설명되어 있습니다.

  1. void secretValue(int stockType, int value):

    • 배운 가치는 다른 플레이어에게 공개되지 않습니다.
    • 값 사이 01000
    • 낮은 값은 높은 값보다 발생하기 쉽습니다 (제곱 균일 분포)
  2. Offer makeOffer(List<Stock> currentStock)

    • 당신은 null제안을하지 않기 위해 돌아갈 수 있습니다 .
  3. Offer acceptOffer(List<Offer> offers)

    • 당신 null은 그들 중 누구도 받아들이지 않기 위해 돌아갈 수 있습니다
    • 사용 가능한 오퍼가 없으면 호출되지 않습니다.
    • 수락하면 순자산은 $ Z 하락하고 (-가 될 수 있음) X / Y 주식을받습니다. 판매자와는 정반대입니다.
    • 오퍼를 수락하면 즉시 교환이 이루어지고 추가 플레이어가이를 수락 할 수 없도록 오퍼가 제거됩니다.
  4. void acceptedOffers(List<Offer> offers)

    • 수락 된 쿠폰도 포함

정적 변수 또는 파일 쓰기는 허용되지 않습니다. (게임에서 게임으로의 영구적 인 데이터는 없습니다) 심각하지 않은 경쟁자는 허용됩니다.

인터페이스 :

public final class Stock {
    public Stock(int stockType, int amount);
    public int getType();
    public int getAmount();
    public Stock minus(Stock other);
    public Stock plus(Stock other);
    public Stock minus(int amount);
    public Stock plus(int amount);
    public Stock setAmount(int amount);
}
public class Offer {
    public Offer(Stock offer, int payment);
    public Stock getOffer();
    public int getPayment();
}

비 Java 제출 :

  • 모든 통화 개의 라인으로 구성 첫 줄 호출되는 함수이다 : SecretValue, MakeOffer, AcceptOffer, AcceptedOffers, SetRandom, 실제 데이터를 포함하는 두 번째 줄.
  • 주식은 :구분 기호 로 형식화됩니다 stockType:stockAmount.
  • 오퍼는 @구분 기호 로 형식화됩니다 .offer@price
  • 목록은 ;구분자 로 형식화됩니다
  • SecretValue:구분 기호 로 형식이 지정됩니다 .stockType:value
  • RandomSeed제출물을 결정 론적으로 만드는 데 사용됩니다. 제출에서 임의성을 사용하는 경우 시드로 전달 된 정수 값을 사용하십시오!
  • 모든 함수 호출 에는 응답이 필요 합니다. 응답이 null또는 void인 경우 빈 문자열을 반환하십시오.
  • command.txt제출을 실행하기 위해 명령 행 인수를 제공 하는 을 포함 하십시오

채점

1000 턴으로 구성된 게임은 여러 번 실행됩니다. 플레이어는 ELO 시스템 에 따라 점수가 매겨 지며 비슷한 기술 수준의 플레이어와 짝을 이룹니다. 최종 ELO 점수가 가장 높은 플레이어가 승리합니다! (각 게임, ELO 점수가 각 플레이어 쌍에 대해 업데이트되도록 시스템을 수정했습니다)

컨트롤러에는 자동 다운로더가 포함되어 있으므로 헤더를 사용하여 제출을 시작하십시오 Name, Language. 제출물이 Java로 작성되지 않은 경우 각 코드 블록은 파일 이름으로 시작해야합니다. (게시물 파일 제외, 게시물의 첫 번째 블록이어야 함)

달리는

이 프로젝트를 실행하는 방법은 두 가지가 있습니다 :

  1. 소스 코드를 다운로드하고 컴파일하고 실행하십시오. Github 에서 소스를 찾을 수 있습니다 . 운영git clone --recursive https://github.com/nathanmerrill/StockExchange.git

  2. JAR 실행 파일을 다운로드하십시오. 제출물은 /submissions폴더 의 현재 작업 디렉토리에 있어야 합니다. JAR 만, 제출 만 또는 둘 다 다운로드 할 수 있습니다.

에 합격 run프로젝트 (기본 옵션)를 실행, 또는 전달하는 데 download지금까지이 질문에 모든 제출을 다운로드 할 수 있습니다.

스코어 보드

1.  1308.1220497323848  Cheater
2.  1242.0333695640356  InsideTrader
3.  1158.3662658295411  UncleScrooge
4.  1113.8344000358493  BlackMarket
5.  1051.8370015258993  DartMonkey
6.  983.0545446731494   WarGamer
7.  939.457423938002    Spammer
8.  901.4372529538886   DumbBot
9.  859.0519326039137   ShutUpAndTakeMyMoney
10. 852.9448222849587   VincentKasuga
11. 718.2112067329083   Profiteer

stock 속성은 공개되지 않습니다. getter 메서드를 사용하도록 지시하십시오
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython 더 좋습니까?
Nathan Merrill

현재 가격이 이전 가격과 상관 관계가 있습니까?
noɥʇʎԀʎzɐɹƆ

1
대화방에 감사드립니다.
TheNumberOne

답변:


13

사기꾼, 자바

돈을 위해 아무것도 팔려고하지 않습니다.

import java.util.List;
import java.util.Random;
import com.ppcg.stockexchange.*;

public class Cheater extends Player {
    private Random random = new Random();

    public Offer acceptOffer(List<Offer> offers) {
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock){
        Stock stock = randomStock();
        int price = random.nextInt(100) + 1;
        return new Offer(stock.setAmount(0), price);
    }
}

5
그렇게 큰 우울증이 발생합니다! 나는 이것이 싼 것을 사는 많은 봇을 깨는 것을 볼 수 있었다. ..
Socratic Phoenix

축하합니다! 치명적인 버그를 수정했으며 이제이 봇이 처음입니다!
Nathan Merrill

와우, 다른 봇들은 그다지 좋지 않다.이 멍청한 봇이 이길 수있다
justjustf

8

워 게이머, 자바

규칙에 대한 기능 점검을하면서 나는 1 차 승리의 움직임을하지 않기로 결정했습니다. 주식을 팔겠다고 제안하는 사람은 누구나 가격을 알고 판매를 통해 이익을 얻습니다. "농담"오퍼를 사용하여 Integer에 대한 주식을 판매하도록 제안 할 수 있습니다.

import java.util.List;
import com.ppcg.stockexchange.*;
import com.ppcg.kothcomm.game.AbstractPlayer;
import com.ppcg.kothcomm.utils.Tools;

import java.util.List;

public class WarGamer extends Player {
static final boolean FRAUD = false;
    /**
     * @param offers All available offers
     * @return An offer you want to accept, or null if you want to accept neither.
     */
    public Offer acceptOffer(List<Offer> offers){
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock){
    if(FRAUD)
    return new Offer(new Stock(0,1),Integer.MAX_VALUE);
        //defraud shut up and take my money            
    return null;
    }
}

1
아마 약간 높은 값을 가진 항목이있을 것으로 예상하는 것을 제외하고는 아마도 잘 작동 할 것입니다. 보통 있습니다.
Geobits

컴파일되지 않습니다.
Rainbolt

@Rainbolt에는 종속성이 있습니다. 존재하는지 확인해야합니다.
Rohan Jhunjhunwala

@Rainbolt 어떤 컴파일러 오류가 발생합니까
Rohan Jhunjhunwala

1
다른 농담 로봇을 속이는 부분이 올바른 정신에 있는지 잘 모르겠습니다.
Maltysen

5

ShutUpAndTakeMyMoney, Java

import java.util.List;
import com.ppcg.stockexchange.*;

public class ShutUpAndTakeMyMoney extends Player {
    public ShutUpAndTakeMyMoney() {}

    public Offer acceptOffer(List<Offer> offers) {
        try {
            return offers.get(0);
        } catch (Exception ex) {
            return null;
        }
    }
    public Offer makeOffer(List<Stock> stock) {
        return null;
    }
}

모든 제안을 수락합니다.


실제로 로봇에 감사드립니다
Rohan Jhunjhunwala

6
나를 부자로 만드는 +1
Rohan Jhunjhunwala

1
이것은 모든 답변 " 사용중인 우승 기준에 대한 심각한 경쟁자 "라는 요구 사항과 실제로 호환되지 않는 것 같습니다 .
피터 테일러

2
@PeterTaylor 진지하고 리더 보드에서 5 위
TuxCrafting

다른 봇이 주식을 가치보다 더 많이 팔아 실제 가격보다 더 많이 주식을 구입할 수 있기를 기대하는 것이 합리적이므로 이는 아마도 자살 항목 입니다.
Mego

4

덤봇, 자바

직접 만들 때이 봇을 사용하십시오. 비밀 재고를 할인 된 가격으로 제공합니다.

import java.util.List;
import com.ppcg.stockexchange.*;
public class DumbBot extends Player {
    public Offer acceptOffer(List<Offer> offers) {
        return null;
    }
    public Offer makeOffer(List<Stock> currentStock){
        return new Offer(currentStock.get(secretStockType).setAmount(1), Math.max(1, secretStockValue - 5));
    }
    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) {
    }
}

1
내가 돈을 처리하기를 원하는 것 같습니다
Rohan Jhunjhunwala

이 커뮤니티 위키를 만드십시오
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython 왜?
Nathan Merrill

@NathanMerrill이 더미 로봇에서 이익을 얻는 담당자
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython 나는 사람들이 이것을 편집하는 것을 정말로 원하지 않는다. 나는 정말로 담당자에 대해 신경 쓰지 않기 때문에 자유롭게 투표 (또는 downvote)하지 말아라.
Nathan Merrill

3

python_starter, 파이썬 3

파이썬 (또는 다른 언어) 프로그램의 시작점으로 이것을 사용하십시오.

무작위 제안을 수락합니다.

명령 파일 :

python3 starter.py

프로그램:

starter.py
import random
from functools import total_ordering


LIST_DELIMITER = ';'
STOCK_DELIMITER = ':'
OFFER_DELIMITER = '@'


@total_ordering
class Stock:
    @staticmethod
    def parse(string: str):
        return Stock(*map(int, string.split(STOCK_DELIMITER)))

    def __init__(self, stock_type: int, amount: int):
        self.type = stock_type
        self.amount = max(amount, 0)

    def __str__(self):
        return str(self.type)+STOCK_DELIMITER+str(self.amount)

    def __eq__(self, other):
        return self.amount == other.type

    def __lt__(self, other):
        return self.amount < other.amount

    def update(self, amount) -> 'Stock':
        return Stock(self.type, amount)

    def __mul__(self, other: int) -> 'Stock':
        return self.update(self.amount*other)

    def __floordiv__(self, other: int) -> 'Stock':
        return self.update(self.amount//other)

    def __add__(self, other: int) -> 'Stock':
        return self.update(self.amount+other)

    def __sub__(self, other: int) -> 'Stock':
        return self.update(self.amount-other)


class Offer:
    @staticmethod
    def parse(string: str) -> 'Offer':
        try:
            offer, payment = string.split(OFFER_DELIMITER)
        except ValueError:
            raise Exception("Cannot unpack "+string)
        return Offer(Stock.parse(offer), int(payment.strip()))

    def __init__(self, offer: Stock, payment: int):
        self.offer = offer
        self.payment = payment

    def __str__(self):
        return str(self.offer)+OFFER_DELIMITER+str(self.payment)


def read_stock_value(value: str):
    global hidden_price, hidden_stock
    stock, price = value.split(STOCK_DELIMITER)
    hidden_price = float(price)
    hidden_stock = int(stock)


def process_input():
    handlers = {
        "SecretValue": read_stock_value,
        "RandomSeed": read_seed,
        "MakeOffer": make_offer,
        "AcceptOffer": accept_offer,
        "AcceptedOffers": accepted_offers,
    }
    method = input().strip()
    data = input().strip()
    output = handlers[method](data)
    if output is not None:
        print(str(output))
    else:
        print()


def read_seed(seed: str):
    random.seed(int(seed))


def start():
    while True:
        process_input()


hidden_stock = None
hidden_price = None


def make_offer(current_stock: str):
    current_stock = map(Stock.parse, current_stock.split(LIST_DELIMITER))
    pass


def accept_offer(available_offers: str):
    available_offers = list(map(Offer.parse, available_offers.split(LIST_DELIMITER)))
    return random.sample(available_offers, 1)[0]


def accepted_offers(offers: str):
    offers = map(Offer.parse, offers.split(LIST_DELIMITER))
    pass


if __name__ == "__main__":
    start()

1
이것은 너무 복잡합니다.
noɥʇʎԀʎzɐɹƆ

2
대부분 도우미입니다. 파이썬으로 작성하는 경우 하단 3 함수를 구현하면됩니다.
Nathan Merrill

무엇을합니까?
noɥʇʎԀʎzɐɹƆ

봇은 임의의 주식을 수락합니다. 도우미는 파싱 / 인코딩을 수행 할뿐만 아니라 오퍼 / 스톡에 대한 클래스를 제공합니다.
Nathan Merrill

... 그리고 그것은 승리 : /
noɥʇʎԀʎzɐɹƆ

3

VincentKasuga, 자바

내 Java가 유효한지 확실하지 않습니다. 검토하시기 바랍니다.

작동 원리

-모든 주식을 소유 한 경우 주식의 가격을 설정할 수 있습니다. 당신은 유일한 판매자입니다. 1. 모든 주식을 구매하십시오. 2. 마지막 주식에서 모든 주식의 가격을 최고가로 설정합니다. 3. 이익! -일반적으로 불가능하기 때문에 ...

  • 가격은 일반적으로 무한대로 치 솟을 것입니다 ...하지만 한계가 있습니다!
  • ... (더 많은 이유)

작동 방식, v2

  • 가격은 일부 무정부주의 국가에 의해 인위적으로 최대로 설정됩니다
  • 이것은 경제적으로 나쁘다
  • 봇은 예측하지 않습니다. 시장 구조에 내재 된 결함을 악용합니다!

할 것

  • 시장을 여러 번 코너링하십시오! 무 하하!

자주하는 질문

Q : Vincent Kasuga는 누구입니까?

에이: 그는 미국에서 모든 양파와 양파 선물을 샀습니다. (비밀 창고에 모두 담아) 몸값으로 업계를 열었습니다. X 백만을 주거나 가격을 낮게 설정하면 파산하게됩니다.

그러나 그는 거기서 멈추지 않았습니다.

그런 다음 그는 양파 ETF를 비밀리에 단축했습니다 (단, 내려갈 것입니다). 그는 한 번에 모든 양파를 팔아 수천 대의 트럭으로 증권 거래소에 실제로 배달했습니다. 양파 백은 양파보다 저렴합니다. 그는 수백만을 다시 만들었습니다. 요컨대 허드슨 강에는 양파가 넘쳐 흐르고있었습니다.

그는 진짜 사람입니다.

코드

import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.List;

public class VincentKasuga extends Player {
    private int knownStock;
    private int knownPrice;
    private int corneredStockType = -1;
    private int corneredLikelehood = 0;
    private boolean marketCornered;
    private int ticks;

    public Offer acceptOffer(List<Offer> offers) {
        if (!marketCornered) {
            Offer maxOffer = null;
            int maxAmount = 0;
            if (corneredStockType == -1) {
                for (Offer offer: offers) {
                    if (offer.getOffer().getAmount() > maxAmount) {
                        maxAmount = offer.getOffer().getAmount();
                        maxOffer = offer;
                    }
                }
            } else {
                for (Offer offer: offers) {
                    if (offer.getOffer().getAmount() > maxAmount && offer.getOffer().getType() == corneredStockType) {
                        maxAmount = offer.getOffer().getAmount();
                        maxOffer = offer;
                    }
                }
            }


            if (maxOffer == null) {
                // may have cornered the market
                corneredLikelehood++;
                if (corneredLikelehood == 5) {
                    // probably cornered the market
                    marketCornered = true;
                }
            }
            return maxOffer;
        } else {
            // who needs offers when the market is cornered!?
            return null;
        }
    }

    public Offer makeOffer(List<Stock> currentStock) {
        ticks++;
        if (ticks >= 999) {
            // SELL SELL SELL!
            return new Offer(new Stock(corneredStockType, 1000), 1000);
        } else {
            return null;
        }
    }

    public void secretValue(int stockType, int value) {
        knownStock = stockType;
        knownPrice = value;
        if (stockType == corneredStockType) {
            if (knownPrice == 1000) {
                corneredLikelehood += 3;
            } else if (knownPrice < 900){
                // didn't corner the market.
                corneredLikelehood = 0;
            }
        }
    }
}

"본드 씨, 금 시장을 모색했습니다!"


봇용 자동 다운로더를 포함 시켰습니다. 코드를 코드 블록에 넣으십시오. 맞지 않으면 괜찮습니다.
Nathan Merrill

@NathanMerrill 이해합니다. 그러나 컴파일됩니까?
noɥʇʎԀʎzɐɹƆ

@NathanMerrill이 완료했습니다. 프로브가 컴파일되지 않습니다. 흥미로운 전략? 그리고 경제학 수업!
noɥʇʎԀʎzɐɹƆ

for (offer: offers)->for (Offer offer: offers)
Nathan Merrill

corneredStockType == null또한 유효하지 않습니다. 가 int될 수 없습니다 null.
MegaTom

2

스패머, 자바

import java.util.List;
import java.util.ArrayList;
import com.ppcg.stockexchange.*;

public class Spammer extends Player {
    private boolean panic = false;

    public Offer acceptOffer(List<Offer> offers) {
        for (Offer offer : offers) {
            if (this.panic || offer.getPayment() < 20)
                return offer;
        }
        return null;
    }
    public Offer makeOffer(List<Stock> currentStock) {
        if (currentStock.size() > 1) { // Don't sell all the stock
            this.panic = false;
            return new Offer(currentStock.get(secretStockType).setAmount(1), 1);
        }
        this.panic = true; // BUY
        return null;
    }
}

주식이 정말로 싼 주식으로 시장을 스팸하고, 가격이 20보다 적을 때만 주식을 사십시오. 주식 수가 1로 떨어지면 무엇이든 사려고합니다.


대공황에서 잘 작동
noɥʇʎԀʎzɐɹƆ

... 어떻게 이기는가!?
noɥʇʎԀʎzɐɹƆ

2

다트 몽키, 자바

(비경쟁 :이기는 것이 아니며 이미 다른 답변이 있습니다)

다트 원숭이는 물건을 던지는 것을 좋아합니다. 그리고 그 옆에 뾰족한 막대기 더미가 많이 있습니다. 그는 벽에 종이를 보았습니다. 밤! 밤! 밤! 다트 몽키는 80 개의 다트를 던졌습니다. 다트의 절반은 빨간색이고 나머지 절반은 파란색이며 난수는 무작위입니다! 다트 원숭이는 컴퓨터를 본다 ... 숫자에 다트 원숭이 종류. 다트 원숭이는 숫자를 좋아합니다. 다트 원숭이는 다트에서 돈을 벌고 ...


진지하게, DartMonkey는 주식 수의 두 배인 길이를 갖는 정수 배열을 초기화합니다. 그는 사고 / 팔고 자하는 주식의 숫자 하나와 주식 가격의 숫자 하나를 저장합니다. 그런 다음 배열에서 주식을 판매하고 배열에 따라 오퍼를 수락합니다. 만약 그가 어레이에서 주식을 가지고 있지 않다면, 그는 아무것도 제공하지 않을 것이며, 만약 그가 어레이로부터 그에게 제안을 제공하지 않으면, 그는 아무것도 받아들이지 않을 것입니다.


이 답변은 채팅에서 다트 원숭이를 언급 한 @TheNumberOne에서 영감을 얻었습니다.

import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.List;
import java.util.Random;

public class DartMonkey extends Player {
    private int basePrice = 100;
    private int numStocks;
    private int[] dartBoard;
    private boolean first = true;

    @Override
    public Offer acceptOffer(List<Offer> offers) {
        for(Offer offer : offers) {
            Stock stock = offer.getOffer();
            int type = stock.getType();
            int amount = stock.getAmount();
            int price = offer.getPayment();
            if(this.dartBoard[type] < 0 && amount <= -this.dartBoard[type] && price <= this.dartBoard[type + this.numStocks]) {
                this.dartBoard[type] = 0;
                return offer;
            }
        }
        return null;
    }

    @Override
    public Offer makeOffer(List<Stock> stocks) {
        if(this.first) {
            this.first = false;
            this.numStocks = stocks.size();
            this.dartBoard = new int[this.numStocks * 2];
            Random random = this.getRandom();
            for (int i = 0; i < 20; i++) {
                int index = random.nextInt(this.dartBoard.length / 2);
                this.dartBoard[index] = random.nextInt(1001);
                this.dartBoard[this.numStocks + index] = random.nextInt(1001);
            }

            for (int i = 0; i < 20; i++) {
                int index = random.nextInt(this.dartBoard.length / 2);
                this.dartBoard[index] = -random.nextInt(1001);
                this.dartBoard[this.numStocks + index] = random.nextInt(1001);                
            }
        }

        for (Stock stock : stocks) {
            int type = stock.getType();
            if(this.dartBoard[type] > 0) {
                Offer offer = new Offer(stock.setAmount(this.dartBoard[type]), this.basePrice + this.dartBoard[type + this.numStocks]);
                this.dartBoard[type] = 0;
                this.dartBoard[type + this.numStocks] = 0;
                return offer;
            }
        }

        return null;
    }

}

월스트리트를 무작위로 걷다 보니?
Rohan Jhunjhunwala

이것은 아마도 자살 항목 이며 허용되지 않습니다.
Mego

1
@Mego 어떻게 보지 못합니다 ... 자살 응모작은 주식을 0 달러에 팔 것입니다. 어느 규칙에 확실히 맞지 않습니다 ....
Socratic Phoenix

2

InsideTrader, 자바

InsideTrader는 방금 둘러보고 모두가 창의력을 발휘하려고 노력하는 것을 보았습니다. 그러나 그는 창조적 인 일을했습니다. 예상되는 일을하십시오.

이 봇은 "투자 결정"을 "안내"하기 위해 "내부 문서"를 "차용"했으므로 "가치"를 구매합니다.

코드에서 수행 할 작업 및 작동 방식 ;)

코드"

import java.util.List;

import com.ppcg.stockexchange.*;

public class InsideTrader extends Player {
    public String coverStory = "I can tell the good companies from the bad ones.";
    private String theTruth = "I'm cheating. (but so is everyone else)";
    private String ambitions = "Learn to \"follow the market\"";  // don't steal this idea
    private int secretStock = -1;
    private int secretStockValue = -1;

    private int appraiseOffer(Offer offer) {
        /* get how much the offer is worth, 0 if it's not the secret stock */
        if (offer.getOffer().getType() != secretStock ||offer.getOffer().getAmount() == 0) {
            return 0;
        }
        return (offer.getPayment()/offer.getOffer().getAmount())  // price per stock...
                - secretStockValue  // minus value of stock.
                ;
    }
    public Offer acceptOffer(List<Offer> offers) {
        Offer bestOffer = null;
        int bestOfferValue = -1;
        for (Offer offer :
                offers) {
            int value = appraiseOffer(offer);
            if (value > bestOfferValue && value > 0) {
                bestOfferValue = value;
                bestOffer = offer;
            }
        }
        return bestOffer;
    }

    public Offer makeOffer(List<Stock> currentStock) {
        return new Offer(new Stock(0,1), Integer.MAX_VALUE);
    }

    public void secretValue(int stockType, int value) {
        secretStock = stockType;
        secretStockValue = value;
    }

    public void acceptedOffers(List<Offer> acceptedOffers) {

    }
}

당신은 파일의 시작 부분에 추가 클래스를 가질 수 없습니다 ... 그것은 문법적으로 유효하지 않습니다 ... 공개하지 않고 끝에 추가 할 수 있습니다.
Socratic Phoenix

Error on line 50: modifier private not allowed here Error on line 54: modifier private not allowed here. 방금 수업을 제거하고 연장했습니다Player
Nathan Merrill

참고로, 일부 새로운 봇은 주식을 0으로 제공하므로 봇이 appraiseOffer의 반환에서 ArithimeticException (/에 의해 0)을 던지고 있습니다.
Socratic Phoenix

@SocraticPhoenix 감사합니다.
noɥʇʎԀʎzɐɹƆ

축하합니다,이 봇은 현재 두 번째입니다!
Nathan Merrill

2

월스트리트, 코 틀린

높은 판매와 낮은 구매에서 시작하여 점차 가격이 실제로 생각하는 것으로 이동합니다. 또한 이것을 kotlin에서 직접 만들기위한 템플릿으로 사용할 수 있습니다.

참고 : 여기에는 안정적으로 재현 할 수없는 버그가 있습니다. 프로그램이 충돌하거나 문제가 발생하면 채팅으로 핑 (Ping )하고 내용의 페이스트 빈을 연결하십시오.submissions/other/WallStreet/log.txt

kotlinc WallStreet.kt
kotlin WallStreetKt
WallStreet.kt
import java.io.FileOutputStream
import java.io.PrintStream
import java.util.*

val LOGGER = PrintStream(FileOutputStream("log.txt", true))
const val DEBUG = false

const val LOG_GAME_HEADER = """
###############
#STARTING GAME#
###############"""

data class Stock(val type : Int, val amount : Int) {

    operator fun minus(amount : Int) = copy(amount = this.amount - amount)
    operator fun plus(amount: Int) = copy(amount = this.amount + amount)
    fun setAmount(amount: Int) = copy(amount = amount)

    operator fun minus(other : Stock) : Stock {
        assert(type == other.type)
        return copy(amount = this.amount - other.amount)
    }

    operator fun plus(other : Stock) : Stock {
        assert(type == other.type)
        return copy(amount = this.amount + other.amount)
    }

    override fun toString() = "$type:$amount"
}

data class Offer(val offer: Stock, val payment: Int) {
    override fun toString() = "$offer@$payment"
}

fun parseStock(repr : String) : Stock {
    val data = repr.split(":").map { it.toInt() }
    return Stock(data[0], data[1])
}

fun parseOffer(repr: String) : Offer {
    val data = repr.split("@")
    return Offer(parseStock(data[0]), data[1].toInt())
}

fun parseOffers(repr: String) = if (repr == "") emptyList<Offer>() else repr.split(";").map { parseOffer(it) }


interface Player {
    fun secretValue(stockType: Int, value: Int)
    fun makeOffer(currentStock: List<Stock>) : Offer?
    fun acceptOffer(offers: List<Offer>) : Offer?
    fun acceptedOffers(offers: List<Offer>)

    var random : Random
}

fun main(args : Array<String>) {

    try {

        if (DEBUG) {
            LOGGER.println(LOG_GAME_HEADER)
        }
        //Change bot name here
        val player = WallStreet()

        while (true) {
            val function = readLine()
            function ?: return
            val line = readLine()!!
            if (DEBUG) {
                LOGGER.println("\nInput:")
                LOGGER.println(function)
                LOGGER.println(line)
            }
            var result : Any
            try {
                result = when (function) {
                    "SecretValue" -> {
                        val data = line.split(":").map { it.toInt() }
                        player.secretValue(data[0], data[1])
                    }
                    "MakeOffer" -> player.makeOffer(line.split(";").map { parseStock(it) }) ?: ""
                    "AcceptOffer" -> player.acceptOffer(parseOffers(line)) ?: ""
                    "AcceptedOffers" -> player.acceptedOffers(parseOffers(line))
                    "RandomSeed" -> player.random = Random(line.toLong())
                    else -> return        //Exit program
                }
                if (function == "AcceptOffer" && result.toString() !in line) {
                    throw Exception("Offer not among available offers!!!!\nResult: $result\nParsed Available Offers: ${parseOffers(line)}")
                }
            } catch (e : Exception) {
                LOGGER.println("Turn #${player.turn}")
                LOGGER.println("\nInput:")
                LOGGER.println(function)
                LOGGER.println(line)
                throw e
            }

            if (result == Unit) {
                result = ""
            }
            if (DEBUG) {
                LOGGER.println("Output:")
                LOGGER.println(result)
            }

            println(if (result == Unit) "" else result)
        }
    } catch (e : Exception) {
        e.printStackTrace(LOGGER)
        throw e
    } finally {
        LOGGER.close()
    }
}


// ###################################################
// #          Put program logic below here.          #
// ###################################################


const val DEFAULT_STOCK_VALUE = 333
const val MAX_TURNS = 1000
const val MAX_STOCK_VALUE = 1000

class WallStreet : Player {

    var secretStockType = 0
    var secretStockValue = 0
    override var random = Random()


    var turn = 0
    val stockPriceStatistics = mutableMapOf<Int, DoubleSummaryStatistics>()

    override fun secretValue(stockType: Int, value: Int) {
        secretStockType = stockType
        secretStockValue = value
    }

    override fun makeOffer(currentStock: List<Stock>): Offer {
        val stock = currentStock[random.nextInt(currentStock.size)]
        val type = stock.type
        val amount = random.nextInt(stock.amount)
        val price = getSellPrice(type) * amount
        return Offer(Stock(type, amount), Math.ceil(price).toInt())
    }

    override fun acceptOffer(offers: List<Offer>): Offer? {
        var bestOffer : Offer? = null
        var mostProfit = 0.0
        for (offer in offers) {
            val offerProfit = profitOfOffer(offer)
            if (offerProfit > mostProfit) {
                bestOffer = offer
                mostProfit = offerProfit
            }
        }
        if (bestOffer != null && bestOffer !in offers) {
            throw IllegalStateException("Tried to accept non-existent offer.\nOffer:  $bestOffer\nAvailable Offers: ${offers.joinToString(";")}")
        }
        return bestOffer
    }

    override fun acceptedOffers(offers: List<Offer>) {
        turn++
        for ((stock, payment) in offers) {
            val stats = stockPriceStatistics.getOrPut(stock.type) { DoubleSummaryStatistics() }
            for (i in 1..stock.amount) {
                stats.accept(payment.toDouble() / stock.amount)
            }
        }
    }

    private fun getSellPrice(type: Int): Double {
        var price = getPrice(type)
        if (price < 1000) {
            price += (1000 - price) * (MAX_TURNS - turn) / MAX_TURNS
        }
        return if (type == secretStockType) Math.max(secretStockValue.toDouble(), price) else price
    }

    private fun getPrice(type: Int): Double {
        return stockPriceStatistics[type]?.average ?: DEFAULT_STOCK_VALUE.toDouble()
    }

    private fun profitOfOffer(offer: Offer): Double {
        return getBuyPrice(offer.offer.type) * offer.offer.amount - offer.payment
    }

    private fun getBuyPrice(type: Int): Double {
        var price = getPrice(type)
        price = price * turn / MAX_TURNS
        return if (type == secretStockType) Math.min(secretStockValue.toDouble(), price) else Math.min(price, MAX_STOCK_VALUE.toDouble())
    }

}

command.txt파일 이름이 필요하지 않습니다. 좋은 포스트!
Nathan Merrill

문자열 보간이 $가 아니라 $ {}로 수행되었다고 생각 했습니까?
Socratic Phoenix

@SocraticPhoenix $는 변수 이름으로 만 작동합니다. ${}임의의 코드를 실행합니다. 기본적으로 그것은 어느 쪽이든 작동하며 중괄호없이 선호합니다.
TheNumberOne

참고 : 임시 솔루션으로이 파일을 실행하려는 창 사용자는 command.txt다음 을 변경해야합니다 kotlinc.-> kotlinc.batkotlin->kotlin.bat
Nathan Merrill

컨트롤러를 고치면이 봇은 많은 불량 데이터를 반환하기 시작하여 경쟁에서 제거했습니다. 당신이 :) 원한다면 나는 채팅방에서 당신을 도울 수 있습니다
나단 메릴

1

UncleScrooge, 자바

import java.util.List;
import com.ppcg.stockexchange.*;

public class UncleScrooge extends Player {
    public Offer acceptOffer(List<Offer> offers) {
        Offer offer;
        try {
            offer = offers.get(0);
        } catch (Exception ex) {
            return null;
        }
        if (offer.getPayment() < 100)
            return offer;
        else
            return null;
    }
    public Offer makeOffer(List<Stock> currentStock){
        if (this.getRandom().nextDouble() < 0.6)
            return new Offer(currentStock.get(secretStockType).setAmount(1), Integer.MAX_VALUE);
        else
            return null;
    }
    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) { }
}

주식을 정말 높은 가격으로 판매하고 가격이 100 미만인 경우에만 구매하십시오.


1

프로 피어, 자바

이익을 위해 돈을 벌고 있으며 항상 동전을 세고 있습니다. 그는 얼마나 많은 돈을 받았는지 보수적으로 추정합니다. 그런 다음 비밀 재고가 가치보다 작거나 싼 주식을 구매할 것입니다. 그는 모든 것에 대해 지불 한 금액을 기억하고 항상 주가보다 높은 가격을 제시합니다. 또한 그는 돈이 적 으면 더 높은 제안을 할 것입니다.

참고 :이 작업을 올바르게 수행했다고 생각하지만 @NathanMerrill이 버그 코드를 감추고 싶지 않다면 좋을 것입니다.

import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class Profiteer extends Player {
    private List<StockInfo> onMarket;
    private List<StockInfo> stocks;
    private int money;
    private boolean first = true;

    @Override
    public Offer acceptOffer(List<Offer> offers) {
        Offer finalOffer;

        Optional<Offer> offer = offers.stream().filter(o -> o.getOffer().getType() == this.secretStockType && o.getPayment() < this.secretStockValue * o.getOffer().getAmount()).sorted((a, b) -> Integer.compare((this.secretStockValue * a.getOffer().getAmount()) - b.getPayment(), (this.secretStockValue * b.getOffer().getAmount()) - b.getPayment())).findFirst();
        if (offer.isPresent()) {
            finalOffer = offer.get();
        } else {
            finalOffer = offers.stream().sorted((a, b) -> Integer.compare(a.getPayment(), b.getPayment())).findFirst().orElse(null);
        }

        if (finalOffer == null || this.money <= finalOffer.getPayment()) {
            return null;
        } else {
            this.stocks.add(new StockInfo(finalOffer.getOffer(), finalOffer.getPayment()));
            this.refreshMoney();
            return finalOffer;
        }
    }

    @Override
    public Offer makeOffer(List<Stock> stocks) {
        if (this.first) {
            this.init(stocks);
        } else {
            this.refreshMarketList(stocks);
        }

        Optional<StockInfo> least = this.stocks.stream().sorted((a, b) -> Integer.compare(a.getBoughtPrice(), b.getBoughtPrice())).findFirst();
        Optional<StockInfo> secret = this.stocks.stream().filter(stockInfo -> stockInfo.getStock().getType() == this.secretStockType).sorted((a, b) -> Integer.compare(a.getBoughtPrice(), b.getBoughtPrice())).findFirst();

        StockInfo finalOffer;
        int price;
        if (secret.isPresent()) {
            finalOffer = secret.get();
        } else if (least.isPresent()) {
            finalOffer = least.get();
        } else {
            return null;
        }

        this.onMarket.add(finalOffer);
        this.stocks.remove(finalOffer);
        price = this.calculatePrice(finalOffer.boughtPrice);
        return new Offer(new Stock(finalOffer.getStock().getType(), finalOffer.getStock().getAmount()), price);
    }

    private int calculatePrice(int boughtPrice) {
        return (int) (boughtPrice + ((boughtPrice / (double) this.money) * this.money)) + 1;
    }

    private void refreshMarketList(List<Stock> stocks) {
        this.stocks.addAll(this.onMarket.stream().filter(stockInfo -> stocks.contains(stockInfo.getStock())).collect(Collectors.toList()));
        this.onMarket.clear();
    }

    private void refreshMoney() {
        this.money = this.stocks.stream().mapToInt(info -> this.secretStockType == info.getStock().getType() ? this.secretStockValue : 5).reduce((a, b) -> a + b).orElseGet(() -> 0) - this.stocks.stream().mapToInt(StockInfo::getBoughtPrice).reduce((a, b) -> a + b).orElseGet(() -> 0);
    }

    private void init(List<Stock> stocks) {
        this.stocks = stocks.stream().map(stock -> new StockInfo(stock, 0)).collect(Collectors.toList());
        this.onMarket = new ArrayList<>();
        this.money = 0;
        this.first = false;
        this.refreshMoney();
    }

    private static class StockInfo {
        private Stock stock;
        private int boughtPrice;

        public StockInfo(Stock stock, int boughtPrice) {
            this.stock = stock;
            this.boughtPrice = boughtPrice;
        }

        public Stock getStock() {
            return this.stock;
        }

        public int getBoughtPrice() {
            return this.boughtPrice;
        }

    }

}

당신은 빚에 여전히 주식에 의해 갈 수 있습니다 ...
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython 알고 있지만 수익자는 위험을 감수하고 싶지 않습니다
Socratic Phoenix

undownvote
noɥʇʎԀʎzɐɹƆ

@AgentCrazyPython meh, 괜찮습니다. 게임은 재미 있고 중요합니다
Socratic Phoenix

1

맥스 봇, 자바

이 봇은 각 거래에서 최대한의 수익을 올리려고합니다. 판매하는 동안 $ 250를 살 때 알 수없는 주식의 가격은 $ 300입니다.

import java.util.List;
import com.ppcg.stockexchange.*;
public class MaxBot extends Player {
    int toSell;
    int sellPrice;

    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
        toSell = stockType;
        sellPrice = (value + 1000)/2;
    }
    public Offer acceptOffer(List<Offer> offers) {
        Offer max = null;
        int maxDif = 0;
        for(Offer o: offers){
            int price = secretStockType == o.getOffer().getType()? secretStockValue: 250;
            int val = price * o.getOffer().getAmount();
            int dif = val - o.getPayment();
            if(maxDif < dif){
                max = o;
                maxDif = dif;
            }
        }
        return max;
    }
    public Offer makeOffer(List<Stock> currentStock){
        if(toSell == -1){
            return null;
        }
        int sum = 0;
        for (Stock s: currentStock){
            if(s.getType() == toSell){
                sum += s.getAmount;
            }
        }
        int n = sum - sum/2;
        return new Offer(new Stock(toSell, n), n * sellPrice);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) {
        int highStock = -1;
        int highPrice = 0;
        int markup = 0;
        for(Offer o: offers){
            int trueVal = secretStockType == o.getOffer().getType()? secretStockValue: 250;
            int marketVal = o.getPayment()/o.getOffer().getAmount();
            if(marketVal - trueVal > markup){
                highStock = o.getOffer().getType();
                highPrice = marketVal;
                markup = marketVal - trueVal;
            }
        }
        toSell = highStock;
    }
}

1

블랙 마켓, 자바

이 거래에 대해 말할 것도 많지 않습니다.이 거래가 차트에서 벗어날 것입니다.

import java.util.List;
import com.ppcg.stockexchange.*;

public class BlackMarket extends Player {
    private boolean approvedBySEC = false;
    private int ammoLeft = 30;
    public String taxView = "We want higher tax rates";
    public String excuse = "I never saw that in my life";

    public void secretValue(int drugType, int warrantForMyArrest) {
        super.secretValue(drugType, warrantForMyArrest);
        if (warrantForMyArrest != 0 || drugType == 420) {
            ammoLeft += 10;
        }
    }

    public Offer acceptOffer(List<Offer> offers) {
        for (Offer offer : offers) {
            if (this.approvedBySEC || offer.getPayment() < 9)
                return offer;
        }
        return null;
    }


    public Offer makeOffer(List<Stock> currentStock) {
        return new Offer(new Stock(0,1),420);
    }
}

return null is outside ... 제대로 들여 쓰기하십시오.
noɥʇʎԀʎzɐɹƆ

1
@AgentCrazyPython 감사합니다! 어두워 지 자마자 "return null"을 검색합니다. 다음 달 차를 따라 다니는 자동차에주의하십시오.
Timtech

1
왜 공감해야합니까? 우리는 마지막 경쟁에서 4 위를 차지했습니다. 확실하지 않지만 ...
Timtech

0

NotQuiteABanksBestFriend, Python 3

Command.txt :

python3 NotQuiteABanksBestFriend.py
NotQuiteABanksBestFriend.py
import random
from functools import total_ordering
from io import StringIO

log = StringIO()
log.write("\n\n~~~NEW GAME~~~\n\n")

LIST_DELIMITER = ';'
STOCK_DELIMITER = ':'
OFFER_DELIMITER = '@'

JAVA_MAX_INT = 2147483647

@total_ordering
class Stock:
    @staticmethod
    def parse(string: str):
        return Stock(*map(int, string.split(STOCK_DELIMITER)))

    def __init__(self, stock_type: int, amount: int):
        self.type = stock_type
        self.amount = max(amount, 0)

    def __str__(self):
        return "T%sx%s"%(self.type, self.amount)

    def __repr__(self):
        return str(self.type)+STOCK_DELIMITER+str(int(self.amount))

    def __bool__(self):
        return bool(self.amount)

    def __eq__(self, other):
        return self.amount == other.amount

    def __lt__(self, other):
        return self.amount < other.amount

    def update(self, amount) -> 'Stock':
        return Stock(self.type, amount)

    def __mul__(self, other: int) -> 'Stock':
        return self.update(self.amount*other)

    def __floordiv__(self, other: int) -> 'Stock':
        return self.update(self.amount//other)

    def __add__(self, other: int) -> 'Stock':
        return self.update(self.amount+other)

    def __sub__(self, other: int) -> 'Stock':
        return self.update(self.amount-other)


class Offer:
    @staticmethod
    def parse(string: str) -> 'Offer':
        try:
            stock, price = string.split(OFFER_DELIMITER)
        except ValueError:
            raise Exception("Cannot unpack "+string)
        return Offer(Stock.parse(stock), int(price.strip()))

    def __init__(self, stock: Stock, price: int):
        self.stock = stock
        self.price = price
        try:
            self.price_per_unit = self.price/self.stock.amount
        except ZeroDivisionError:
            self.price_per_unit = float('inf')

    def __str__(self):
        return "%s$%s"%(self.stock, self.price)

    def __repr__(self):
        return repr(self.stock)+OFFER_DELIMITER+str(int(self.price))


def read_stock_value(value: str):
    global hidden_price, hidden_stock
    stock, price = value.split(STOCK_DELIMITER)
    hidden_price = float(price)
    hidden_stock = int(stock)
    log.write("Hidden StockID: %s\nHidden Price: %s\n"%(hidden_stock, hidden_price))

def process_input():
    handlers = {
        "SecretValue": read_stock_value,
        "RandomSeed": read_seed,
        "MakeOffer": make_offer,
        "AcceptOffer": accept_offer,
        "AcceptedOffers": accepted_offers,
    }
    method = input().strip()
    data = input().strip()
    output = handlers[method](data)
    if output is not None:
        print(repr(output))
    else:
        print()

def read_seed(seed: str):
    random.seed(int(seed))

def start():
    while True:
        process_input()

hidden_stock = None
hidden_price = None

def filter_offers(offer):
    if offer.stock.amount == 0:
        return False
    if offer.price_per_unit > 1000:
        return False
    return True

def certain_profit(offer):
    stock = offer.stock
    if stock.type == hidden_stock and offer.price_per_unit < hidden_price:
        log.write("Offer, %s is certainly profitable.\n"%offer)
        return True
    return False

def make_offer(current_stock: str):
    current_stock = list(map(Stock.parse, current_stock.split(LIST_DELIMITER)))
    own_stock = [stock for stock in current_stock if stock.type == hidden_stock]
    if own_stock and own_stock[0]:
        own_stock = own_stock[0]
        amount_sold = min(random.randrange(1,50), own_stock.amount)
        price = hidden_price+random.randrange(10,50)
        return Offer(Stock(hidden_stock, amount_sold), price*amount_sold)
    sell_stock = random.choice(current_stock)
    amount_sold = min(random.randrange(1,50), sell_stock.amount)
    price = random.randrange(1000, JAVA_MAX_INT//(amount_sold or 1))
    return Offer(Stock(sell_stock.type, amount_sold), price*(amount_sold or 1))

def accept_offer(available_offers: str):
    available_offers = list(map(Offer.parse, available_offers.split(LIST_DELIMITER)))
    filtered_offers = list(filter(filter_offers, available_offers))
    profitable = list(filter(certain_profit, filtered_offers))
    rtn_list = filtered_offers
    if profitable:
        log.write("Profitable: %s\n"%profitable)
        rtn_list = profitable
    if not rtn_list:
        return None
    accepted_offer = min(rtn_list, key=lambda offer: offer.price_per_unit)
    log.write("Bidded for %s\n"%accepted_offer)
    return accepted_offer

def accepted_offers(offers: str):
    pass


if __name__ == "__main__":
    try:
        start()
    finally:
        log.close()

숨겨진 주식을 항상 가치 이상으로 판매하려고합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.