เอามันหรือทิ้งมันไว้ II: เกมโชว์สำหรับคอมพิวเตอร์


20

นี่เป็นครั้งที่สองในชุดของปริศนาที่ฉันจะโพสต์ทุกวันจันทร์เวลาเที่ยงคืน PST ปริศนาแรกตั้งอยู่ที่นี่

บริบท:

มหาเศรษฐีสันโดษได้สร้างรายการเกมเพื่อดึงดูดโปรแกรมเมอร์ที่ดีที่สุดและสว่างที่สุดในโลก ในวันจันทร์เวลาเที่ยงคืนเขาเลือกบุคคลหนึ่งคนจากกลุ่มผู้สมัครเป็นผู้แข่งขันในสัปดาห์และมอบเกมให้พวกเขา คุณเป็นผู้โชคดีในสัปดาห์นี้!

เกมของสัปดาห์นี้:

โฮสต์ให้คุณเข้าถึง API เพื่อเข้าถึงซองจดหมายดิจิทัลจำนวน 10,000 ซอง ซองจดหมายเหล่านี้จะถูกจัดเรียงแบบสุ่มและมีค่าเงินดอลลาร์อยู่ในนั้นระหว่าง $ 1 ถึง $ 10,000 (ไม่มีซองจดหมายสองซองที่มีค่าเงินดอลลาร์เดียวกัน)

คุณมี 4 คำสั่งในการกำจัดของคุณ:

  1. อ่าน (): อ่านตัวเลขดอลลาร์ในซองจดหมายที่ด้านบนของสแต็ก

  2. ใช้ (): เพิ่มตัวเลขดอลลาร์ในซองจดหมายลงในกระเป๋าเงินโชว์เกมของคุณและป๊อปอัพซองจดหมายออกจากสแต็ค

  3. ผ่าน (): เปิดซองจดหมายที่ด้านบนของสแต็ก

  4. Oracle (M): ส่งคืนค่าเฉลี่ยของซองจดหมาย M ถัดไปในสแต็กไม่รวมซองที่คุณสามารถอ่านได้ในปัจจุบัน ()

กฎระเบียบ:

  1. หากคุณใช้ Pass () บนซองจดหมายเงินภายในจะหายไปตลอดกาล

  2. หากคุณใช้ Take () บนซองจดหมายที่มี $ X จากจุดนั้นไปข้างหน้าคุณจะไม่สามารถใช้ Take () บนซองจดหมายที่มี <$ X ใช้ () บนหนึ่งในซองจดหมายเหล่านี้จะเพิ่ม $ 0 ในกระเป๋าเงินของคุณ

  3. หากคุณใช้ Oracle (M) ในการเปิด T ซองจดหมาย T + 1 ถึงค่าเฉลี่ยของ T + M จะถูกส่งคืน Oracle () ถูกปิดใช้งานจนกว่าจะเปิด T + M

เขียนอัลกอริทึมที่เล่นจบเกมด้วยจำนวนเงินสูงสุด

หากคุณเขียนอัลกอริทึมของคุณใน Python คุณสามารถใช้คอนโทรลเลอร์นี้ได้โดย @Maltysen: https://gist.github.com/livinginformation/70ae3f2a57ecba4387b5

หมายเหตุ 1: "สูงสุด" ในกรณีนี้หมายถึงค่ามัธยฐานในกระเป๋าเงินของคุณหลังจาก N> = 1,000 ทำงาน ฉันคาดหวังแม้ว่าฉันจะชอบที่จะได้รับการพิสูจน์ผิดว่าค่ามัธยฐานของอัลกอริทึมที่กำหนดจะมาบรรจบกันเมื่อ N เพิ่มขึ้นเป็นอนันต์ รู้สึกอิสระที่จะพยายามเพิ่มค่าเฉลี่ยสูงสุด แต่ฉันมีความรู้สึกว่าค่าเฉลี่ยมีแนวโน้มที่จะถูกโยนออกโดย N ขนาดเล็กกว่าค่ามัธยฐานคือ

หมายเหตุ 2: เนื่องจากโซลูชันทั้งหมดของส่วนก่อนหน้าของปริศนานี้มีผลบังคับใช้ที่นี่การผ่านรายการใหม่จึงมีมูลค่าน้อย เฉพาะการปรับปรุงอัลกอริทึมของปริศนาก่อนหน้านี้จะได้รับการพิจารณาในส่วนที่สอง

แก้ไข: เงื่อนไขการให้รางวัลถูกลบออกไปเนื่องจากโพสต์นี้ในเมตาดาต้า


ว้าวฉันไม่อยากจะเชื่อเลยว่าฉันกำลังง่วง: O
Beta Decay

@Beta Decay clock กำลังฟ้อง! :)
LivingInformation

ความรู้สึกของ rracle คืออะไร? คุณสามารถสร้าง oracle ฟรีของคุณเองโดยเพียงแค่เก็บซองจดหมายที่อ่านไว้ก่อนหน้าทั้งหมด ฉันทำอะไรผิด
Luis Mendo

1
@LuisMendo ด้วยการนับรวมของคุณเองคุณสามารถทราบค่าเฉลี่ยของค่าที่เหลือทั้งหมด กับ Oracle ที่คุณจะได้รับค่าเฉลี่ยของถัดไปค่าที่คุณจะได้รับเลือกM M
Reto Koradi

1
เนื่องจากโซลูชันทั้งหมดสำหรับความท้าทายก่อนหน้าของคุณเป็นโซลูชันที่ถูกต้องสำหรับความท้าทายนี้เราจึงสามารถพิจารณาได้ว่าพวกเขาส่งโดยปริยายหรือไม่
Reto Koradi

คำตอบ:


9

Groovy $ 713337 $ 817829 $ 818227

รหัส Bootstrap:

class Instance {
    List values = new ArrayList(1..10000); {
        Collections.shuffle(values)
    }
    int i = 0
    int value = 0
    int max = 0
    int nextOracle = 0

    def pass() {
        if (i >= 10000)
            throw new NoSuchElementException()
        i++
    }

    def take() {
        if (i >= 10000)
            throw new NoSuchElementException()
        int v = values[i]
        if (v > max) {
            max = v
            value += v
        }
        i++
    }

    double oracle(int m) {
        if (m <= 0 || i < nextOracle || i + m >= 10000)
            throw new NoSuchElementException()

        nextOracle = i + m
        values.subList(i + 1, i + m + 1).stream().reduce { l, r -> r+l }.get() / m
    }

    int read() {
        if (i >= 10000)
            throw new NoSuchElementException()
        values[i]
    }
}

ขั้นตอนวิธี

double square(double v) { v * v }
final double factor = Math.pow(1.5, 1.1)
int attempts = 5000
(1..attempts).stream().parallel().mapToLong {
    def puzzle = new Instance()

    int[] memory = 1..10000 // We will remember every envelope
    int memStart = 0

    while (memStart < 10000 - 3) {
        int value = puzzle.read()
        int i = Arrays.binarySearch(memory, memStart, 10000, value) - memStart
        if (i < 0) { // We can't use the money
            puzzle.pass()
            continue
        }
        if (i == 0) { // Of course we take the lowest
            puzzle.take()
            memStart++
            continue
        }
        int remaining = Arrays.stream(memory, i + 1 + memStart, 10000).sum() // Money we could win if taken
        int losing = Arrays.stream(memory, memStart, memStart + i).sum() // Money we cna't win if taken
        if (value > losing) { // If we pass, we lose money automatically
            puzzle.take()
            memStart += i + 1
        } else if ((losing - value * 16 / 7) * square(Math.log(i)) > remaining / factor) {
            System.arraycopy(memory, memStart, memory, ++memStart, i)
            puzzle.pass()
        } else {
            puzzle.take()
            memStart += i + 1
        }
    }

    // It's broken down to last three elements
    List values = Arrays.copyOfRange(memory, 10000 - 3, 10000)
    while (!values.contains(puzzle.read())) // Skip values we can't use
        puzzle.pass()
    int value1 = puzzle.read()
    int value2 = puzzle.oracle(1)
    if (value1 == values.max() && (
            values.contains(value2)
            ? (value1 * 2 < values.sum() && values.min() == value2)
            : (value1 < values.min() / 2 + (values - [value1]).max())
            )) {
        puzzle.pass()
    }

    // Finish it
    while (puzzle.i < puzzle.values.size()) {
        puzzle.take()
    }

    puzzle.value as Long
}.sum() / attempts // Sum runs and average

ฉันเปรียบเทียบค่าที่เหลือกับค่าที่เป็นไปได้ สคริปต์นี้ไม่เร็ว (ใช้เวลา 1 นาทีต่อการจำลอง 1,000 เท่า) ... แต่มันจะทำการจำลองพร้อมกัน

ฉันไม่รู้ว่าทำไมอัลกอริธึมของฉันทำงานได้ แต่มันเป็นเพียงแค่การลองผิดลองถูก: การดำเนินการทางคณิตศาสตร์รวมกันและจัดการค่าคงที่ ฉันวิ่งไปที่ 5,000x สำหรับคะแนนปัจจุบันเพื่อพยายามลดความผันผวนของคะแนน (+/- $ 4,000 ขึ้นอยู่กับจำนวนการทำซ้ำ)

แม้จะไม่มี oracle ในตอนท้ายมันก็ควรจะยังคงเป็นคำตอบของ @ orlpสำหรับการไขปริศนาก่อนหน้านี้


7

C # - $ 803.603 ตอนนี้ -> $ 804.760 (พร้อม oracle)

รหัส Bootstrap

public static class ShuffleExtension
{
    private static Random rng = new Random();  

    public static void Shuffle<T>(this IList<T> list)  
    {  
        int n = list.Count;
        while (n > 1) {  
            n--;  
            int k = rng.Next(n + 1);  
            T value = list[k];  
            list[k] = list[n];  
            list[n] = value;  
        }  
    }
}

public class Puzzle
{
    public List<int> Values = new List<int>(10000);

    public Puzzle()
    {
        for ( int i = 1; i <= 10000; i++ )
        {
            Values.Add(i);
        }
        Values.Shuffle();
    }

    public int i = 0;
    public int value = 0;
    public int max = 0;
    public int nextOracle = 0;

    public void Pass() {
        if ( i >= Values.Count )
            throw new IndexOutOfRangeException();
        i++;
    }

    public void Take() {
        if (i >= Values.Count )
            throw new IndexOutOfRangeException();
        int v = Values[i];
        if (v > max) {
            max = v;
            value += v;
        }
        i++;
    }

    public double oracle(int m) {
    if (m <= 0) { 
        throw new IndexOutOfRangeException();
    }
    if ( i < nextOracle ) {
        throw new IndexOutOfRangeException();
    }
    if ( i + 1 + m > Values.Count ) {
        throw new IndexOutOfRangeException();
    }

    nextOracle = i + m;
    var oracleValues = new List<int>();
    for ( int l = 0; l < m; l++ )
    {
        oracleValues.Add(Values[i + 1 + l]);
    }
    return oracleValues.Average (v => v);
}

    public int Read() {
        if (i >= Values.Count )
            throw new IndexOutOfRangeException();
        return Values[i];
    }
}

รหัสเกม:

    void Main()
{
    var m = 0;
    for ( int l = 0; l < 1000; l++ )
    {
        var game = new Puzzle();
        var maxVal = 0;
        var lastOracle = 0;
        var lastOracleValue = 0.0m;
        var oracleValueForIOf = 0;

        for ( int i = 0; i < 10000; i++ )
        {
            var val = game.Read();
            var oracleStep = 1;
            var canUseOracle = (i - lastOracle >= oracleStep) && i + oracleStep + 1 <= 10000;
            if ( canUseOracle )
            {
                var oracle = game.oracle(oracleStep);
                lastOracle = i;
                lastOracleValue = (decimal)oracle;
                oracleValueForIOf = i + 1;
            }
            if ( TakeTheMoney(val, maxVal, oracleValueForIOf, lastOracleValue, i) )
            {
                maxVal = val;
                game.Take();
            }
            else
            {
                game.Pass();
            }
        }
        m += game.value;
    }
    ((int)(m / 1000)).Dump();
}

private bool TakeTheMoney(int val, int maxVal, int oracleValueForIOf, decimal lastOracleValue, int i)
{
    if ( val > maxVal )
    {
        if ( oracleValueForIOf != i + 1
            &&
            (val < 466.7m + (0.9352m * maxVal) + (0.0275m * i))
            )
        {
            return true;
        }

        if (oracleValueForIOf == i + 1)
        {
            if ( val < 466.7m + (0.9352m * maxVal) + (0.0275m * i) )
            {
                return true;
            }
            if ( lastOracleValue > 466.7m + (0.9352m * val) + (0.0275m * i + 1) )
            {
                if ( val < 466.7m + (0.9352m * maxVal) + (0.0275m * i + 1) )
                {
                    return true;
                }
            }
        }
    }
    return false;
}

เครดิตเป็นของ Reto Koradi ( /codegolf//a/54181/30910 )

แก้ไข: การใช้งานพื้นฐานของ Oracle ถูกนำไปใช้ หาก oracle ถัดไปอยู่เหนือขีด จำกัด ที่จะใช้ให้ขยายซองจดหมายปัจจุบันไปยังดัชนีของ Oracle ดัชนี สิ่งนี้ไม่ได้เกิดขึ้นบ่อยครั้ง แต่เป็นการปรับปรุง ;-)


4
ฉันไม่คิดว่ามันจะมีประโยชน์มากในการแก้ปัญหา repost จากความท้าทายก่อนหน้า เราทุกคนต่างยอมรับว่าวิธีการแก้ปัญหาเหล่านี้สามารถใช้เป็นพื้นฐานในการท้าทายนี้ได้และฉันได้แสดงความคิดเห็นสำหรับ OP แล้วถามว่าเราควรจัดการกับสิ่งนั้นอย่างไร แนวคิดก็คือคุณต้องหาวิธีแก้ปัญหาของตัวเองซึ่งดีกว่าวิธีแก้ปัญหาที่ท้าทายมาก่อน
Reto Koradi

โปรดหยุด downvoting :) เพิ่มหมายเลขบันทึก 2 หลังจากส่งของฉัน และเนื่องจากมีประสิทธิภาพมากกว่าโซลูชันอื่น ๆ - ฉันโพสต์ไว้ที่นี่ ไม่จำเป็นต้องใช้ oracle เพื่อเอาชนะโซลูชั่นที่มีอยู่
Stephan Schinkel

@StephanSchinkel คุณมี upvote ของฉันถ้าคุณจัดการเพื่อรวม Oracle เพื่อปรับปรุงคะแนนปัจจุบัน แม้เพียงแค่ $ 1
Dorus

@BetaDecay มันคืออะไรที่ชุมชนขมวดคิ้วอีกครั้ง? ฉันเพิ่งตามคำถามจาก op เพิ่มหมายเลขหมายเหตุ 2 อีกครั้งหลังจากการส่งของฉัน
Stephan Schinkel

ไม่ใช้วิธีแก้ไขปัญหาจากส่วนที่ฉันทำแบบทดสอบ
Stephan Schinkel

4

Python - $ 74112

รับเฉพาะในกรณีที่ค่าปัจจุบันต่ำกว่าค่าถัดไป (เช่นคุณสามารถรับทั้งคู่ได้)

def algo():
  try:
    o=oracle(1)
  except ValueError:
    take()
  r=read()
  if r>o:
    passe()
  else:
    take()

Python - (ยังคงคำนวณค่าเฉลี่ย)

คำตอบนี้ใช้เวลานานมากในการคำนวณ ที่จะถึงรอบ670.000 $ ฉันจำซองจดหมายแต่ละอันที่ฉันเห็น ทุกครั้งที่ฉันต้องตัดสินใจฉันจะสร้างซองจดหมายที่เหลืออีกสองรายการที่ฉันสามารถเพิ่มลงในกระเป๋าเงินของฉันได้ถ้าฉันใช้ซองจดหมายปัจจุบันหรือปล่อยไว้ตามลำดับ

ฉันไม่ได้เพิ่มประสิทธิภาพรหัส

def algo_2():
  global max_taken, past
  weight=0.92 #Empirically chosen.
  r=read()
  if len(past)==0:
    past.append(r)
    passe()
    return
  if r<max_taken:
    past.append(r)
    take() #the same as passe
    return
  coming=[x for x in range(1,10001) if x not in past and x>max_taken and x!=r ]
  comingIfTake=[x for x in range(1,10001) if x not in past and x>r ]
  if sum(coming)*weight<=sum(comingIfTake)+r:
    past.append(r)
    take()
  else:
    past.append(r)
    passe()

และ init_game เริ่มต้นดังนี้:

def init_game():
    global stack, wallet, max_taken, oracle_turns, past
    past=[]

3
หากคุณใช้ชุดเพื่อเป็นตัวแทนในอดีตมาและกำลังมาหากใช้และใช้จุดตัดรหัสของคุณจะเร็วขึ้นมาก
Nathan Merrill

4

C # - $ 780.176

ตรวจสอบว่าค่าถัดไปอยู่ในระดับต่ำกว่า 5% ของค่าที่เหลือทั้งหมด รับความผ่อนคลายมากขึ้นเมื่อเราสิ้นสุด

public class Taker
{
    private List<int> remaining;
    private Game game;

    public Taker(Game game)
    {
        this.game = game;
        remaining = Enumerable.Range(1, game.Size + 100).ToList();
    }

    int score = 0;

    public int PlayGame()
    {
        for (int i = 0; i < game.Size; i++)
        {
            if (game.Read() < game.Max ||
                game.Read() > selectThreshold() ||
                doOracle()
                )
            {
                remaining.Remove(game.Read());
                game.Pass();
                continue;
            }
            remaining = remaining.SkipWhile(j => j < game.Read()).ToList();
            score += game.Take();
        }
        return score;
    }

    private bool doOracle()
    {
        return game.Oracle(1) < game.Read() &&
            game.Oracle(1) > game.Max;
    }

    private int selectThreshold()
    {
        int selector = (int)(remaining.Count * 0.05);
        return remaining.ElementAt(selector);
    }
}

และคลาสเกมของฉันน่าเกลียดมากคลาสเกมไม่ได้ตรวจสอบถ้าอนุญาต oracle แต่เนื่องจากฉันใช้ Oracle (1) เท่านั้นที่ไม่ควรมีปัญหา

public class Game
{
    private int[] list;
    private int position = 0;
    private int max = 0;
    public int Max { get { return max; } }
    public int Size { get { return list.Length; } }

    public Game(int[] list)
    {
        this.list = list;
    }

    public int Read()
    {
        return list[position];
    }

    public int Take()
    {
        if (list[position] < max)
        {
            position++;
            return 0;
        }
        max = list[position];
        return list[position++];
    }

    public void Pass()
    {
        position++;
    }

    public int Oracle(int M)
    {
        int next = position + 1;
        M = Math.Max(0, Math.Min(M, list.Length - next));
        return new ArraySegment<int>(list, next, M).Sum();
    }
}

4

Java, $ 804,991

คะแนนจาก 1,051 รอบ อาจใกล้เกินไปที่จะโทรระหว่างคำตอบนี้กับของStephan SchinkelSchinkel

สิ่งนี้ขึ้นอยู่กับคำตอบของฉันในความท้าทายที่ผ่านมาโดยใช้การคำนวณแบบเอนโทรปีในการประมาณค่าตอบแทน ข้อแตกต่างที่สำคัญคือตอนนี้ใช้ซองจดหมายเป็นคู่ (1 & 2, 3 และ 4 ต่อไป) และดูที่การรวมกันที่เป็นไปได้ของการซื้อ, Take-Take, Take-Pass, Pass-Take ฯลฯ นอกจากนี้ยังคำนวณ คะแนนโดยประมาณที่แน่นอนเมื่อจำนวนซองจดหมายที่ถูกต้องมีขนาดเล็กมาก

"wrapper" ที่ฉันเขียนไม่ใช่เสื้อคลุมที่แท้จริงมันแค่ให้ซองเป็นคู่แทนที่จะเรียกOracle(1)ฟังก์ชั่นทุก ๆ รอบ

โดยรวมแล้วฉันจะบอกว่าแม้จะมีความซับซ้อนเพิ่มขึ้นบอทนี้ไม่ได้ดีไปกว่าของฉันก่อนหน้า

ผู้เล่น

import java.lang.Math;
public class Player2
{
    public int[] V;

    public Player2(int s)
    {
        V = new int[s];
        for(int i = 0; i<V.length; i++)
        {
            V[i] = i+1;
        }
        ////System.out.println();
    }

    public boolean [] takeQ(int x, int y)
    {
        //System.out.println("Look: " + x + " " + y);
        boolean [] move = new boolean[]{false,false};
        double max = 0;
        double val = 0;
        int[] nextV = V;

        ////System.out.println("look " + x);
        int i = find(V,x);
        if(i >= 0)  //if found
        {
            //try taking first envelope
            int[] newVt = takeSlice(V,i);
            //System.out.println("  T: " + ats(newVt));
            int j = find(newVt,y);
            if(j >= 0)
            {
                //try taking first and second
                int[] newVtt = takeSlice(newVt,j);
                val = x + y + calcVal(newVtt);
                //System.out.println("  TT: " + ats(newVtt) + " " + val);
                if(val > max)
                {
                    move = new boolean[]{true,true};
                    max = val;
                    nextV = newVtt;
                }
            }
            //try taking first and passing second
            int[] newVtp = passSlice(newVt,j);

            val = x + calcVal(newVtp);
            //System.out.println("  TP: " + ats(newVtp) + " " + val);
            if(val > max)
            {
                move = new boolean[]{true,false};
                max = val;
                nextV = newVtp;
            }
        }
        int[] newVp = passSlice(V,i);
        //System.out.println("  V: " + ats(V));
        //System.out.println("  P: " + ats(newVp));
        int j = find(newVp,y);
        if(j >= 0)
        {
            //try passing first and taking second
            int[] newVpt = takeSlice(newVp,j);
            val = y + calcVal(newVpt);
            //System.out.println("  PT: " + ats(newVpt) + " " + val);
            if(val > max)
            {
                move = new boolean[]{false,true};
                max = val;
                nextV = newVpt;
            }
        }
        //try taking first and passing second
        int[] newVpp = passSlice(newVp,j);

        val = calcVal(newVpp);
        //System.out.println("  PP: " + ats(newVpp) + " " + val);
        if(val > max)
        {
            move = new boolean[]{false,false};
            max = val;
            nextV = newVpp;
        }
        V = nextV;
        //System.out.println("  NEW: " + ats(V));
        return move;
    }

    public static String ats(int [] a)
    {
        String s = "";
        for(int i = 0; i < a.length; i++)
        {
            s += a[i] + ",";
        }
        return s;
    }

    public static int[] takeSlice (int[] list, int loc)
    {
        int [] newlist = new int[list.length - loc - 1];
        for(int j = loc + 1; j < list.length; j++)
        {
            newlist[j - loc - 1] = list[j];
        }
        return newlist;
    }

    public static int[] passSlice (int[] list, int loc)
    {
        int [] newlist = list;
        if(loc >= 0)
        {
            newlist = new int[list.length-1];
            for(int k = 0; k < loc; k++)
            {
                newlist[k] = list[k];
            }
            for(int k = loc + 1; k < list.length; k++)
            {
                newlist[k-1] = list[k];
            }
        }
        return newlist;
    }

    public static double calcVal(int [] list)
    {
        if(list.length < 8)
        {
            for(int i : list)
            {
                ////System.out.print(i + ",");
            }

                ////System.out.println();
            return computeMean(list);

        }
        return smoothEstimate(list);
    }

    public static double computeMean(int[] V)
    {
        if(V.length == 1)
        {
            return V[0];
        }
        else if(V.length > 1)
        {
            double[] Es = new double[V.length];
            for(int i = 0; i < V.length; i++)
            {
                int[] newVp = new int[V.length - 1];
                for(int j = 0; j < i; j++)
                {
                    newVp[j] = V[j];
                }
                for(int j = i + 1; j < V.length; j++)
                {
                    newVp[j-1] = V[j];
                }
                double pass = computeMean(newVp);
                int[] newVt = new int[V.length - i - 1];
                for(int j = i + 1; j < V.length; j++)
                {
                    newVt[j - i - 1] = V[j];
                }
                double take = V[i] + computeMean(newVt);
                if(take > pass)
                {
                    Es[i] = take;
                }
                else
                {
                    Es[i] = pass;
                }
            }
            double sum = 0;
            for(double d : Es)
            {
                sum += d;
            }
            return sum/V.length;
        }
        else
        {
            return 0;
        }
    }

    public static double smoothEstimate(int [] list)
    {
        double total = 0;
        for(int i : list)
        {
            total+=i;
        }
        double ent = 0;
        for(int i : list)
        {
            if(i > 0)
            {
                ent -= i/total * Math.log(i/total);
            }
        }
        ////System.out.println("      total " + total);
        ////System.out.println("      entro " + Math.exp(ent));
        ////System.out.println("      count " + list.length);
        return total * Math.pow(Math.exp(ent),-0.5) * 4.0/3;// * 1.1287 + 0.05284);
    }

    public static int find(int[] list, int search)
    {
        int first  = 0;
        int last   = list.length - 1;
        int middle = (first + last)/2;

        while( first <= last )
        {
            if ( list[middle] < search )
                first = middle + 1;    
            else if ( list[middle] == search )
                break;
            else
                last = middle - 1;

            middle = (first + last)/2;
        }

        if(first > last)
        {
            return -1;
        }
        return middle;
    }
}

ตัวควบคุม

import java.lang.Math;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collections;
public class Controller2
{
    public static void main(String [] args)
    {
        int size = 10000;
        int rounds = 1001;
        ArrayList<Integer> results = new ArrayList<Integer>();
        for(int round = 0; round < rounds; round++)
        {
            int[] envelopes = new int[size];
            for(int i = 0; i<envelopes.length; i++)
            {
                envelopes[i] = i+1;
            }
            shuffleArray(envelopes);
            Player2 p = new Player2(size);
            int cutoff = 0;
            int winnings = 0;
            for(int i = 0; i<envelopes.length; i+=2)
            {
                boolean [] take = p.takeQ(envelopes[i],envelopes[i+1]);
                if(take[0] && envelopes[i] >= cutoff)
                {
                    winnings += envelopes[i];
                    cutoff = envelopes[i];
                }
                if(take[1] && envelopes[i+1] >= cutoff)
                {
                    winnings += envelopes[i+1];
                    cutoff = envelopes[i+1];
                }
            }
            results.add(winnings);
        }
        Collections.sort(results);
        System.out.println(rounds + " rounds, median is " + results.get(results.size()/2));

    }

    //stol... I mean borrowed from http://stackoverflow.com/questions/1519736/random-shuffling-of-an-array
    static void shuffleArray(int[] ar)
    {
        Random rnd = new Random();
        for (int i = ar.length - 1; i > 0; i--)
        {
            int index = rnd.nextInt(i + 1);
            // Simple swap
            int a = ar[index];
            ar[index] = ar[i];
            ar[i] = a;
        }
    }
}

ที่อยู่ Bitcoin: 1BVBs9ZEP8YY4EpV868nxi2R23YfL7hdMq


3

Python 3 - $ 615570

ไม่ได้ใช้ oracle จริงๆ ... เอ๊ะ :)

def algo():
    global prevs

    try:
        prevs.append(read())
    except NameError:
        prevs = [read()]

    if len(prevs) > 10000:
        prevs = [prevs[-1]]

    if read() < round(len(prevs),-1):
        take()
    else:
        passe()

สร้างรายการซองจดหมายก่อนหน้าทั้งหมดและตรวจสอบว่าซองจดหมายปัจจุบันน้อยกว่าจำนวนซองจดหมายก่อนหน้าโดยเพิ่มทีละ 10 ซองจดหมาย


0

Python, 87,424

นี่คืออัลกอริทึมธรรมดาและง่ายโชคดีที่เจ็ด

def LuckyNumber7():
Test = read()
if "7" in str(Test):
    take()
else:
    passe()

test(LuckyNumber7)

โดยพื้นฐานแล้วมันทำหน้าที่แปลง read () ไปเป็นสตริงและตรวจสอบว่ามีเจ็ดอยู่ในนั้นหรือไม่ หากมีจะใช้ซองจดหมาย ถ้าไม่มันก็ผ่านไป

โดยเฉลี่ยประมาณ 81,000 ฉันไม่ได้ติดตาม


ดังนั้นสิ่งนี้แสดงให้เห็นว่าการพึ่งพาโชคไม่ใช่กลยุทธ์ที่ประสบความสำเร็จ? ;)
Reto Koradi

@RetoKoradi Yep: D
The_Basset_Hound
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.