API ไข่อีสเตอร์อันยิ่งใหญ่!


15

API การล่าไข่อีสเตอร์!

มี API ที่http://easter_egg_hunt.andrewfaraday.comซึ่งจะให้การล่าไข่อีสเตอร์พิเศษสำหรับคุณ ...

คุณสามารถดูเอกสาร API ได้ตามที่อยู่ด้านบนหรือลองจากที่นี่

API:

การเรียกใช้ API นี้ทั้งหมดเป็นการร้องขอ GET ซึ่งจะส่งคืนสตริง JSON

ตัวอย่างเหล่านี้อยู่ในสวน 5x5 เพื่อประกอบการอธิบายเท่านั้น API จะทำงานบนสวน 100x100 (จากดัชนี 1 ถึง 100)

/new_game

ภายใน API สร้างสวนและซ่อนไข่ไว้ในนั้น

ในตัวอย่างนี้ไข่อยู่ที่ 4, 4

+----------+
|          |
|          |
|          |
|          |
|   E      |
|          |
|          |
|          |
|          |
|          |
+----------+

โทร

/new_game

ผลตอบแทน

{game_id: 'abcde'}

/guess/:game_id/:x/:y

API นั้นอยู่ในสวนและบอกคุณว่าคุณอยู่ใกล้แค่ไหน

หากคุณเดาว่า 2 ตรงข้ามกับ 8 ลงสวนก็จะเป็นแบบนี้

+----------+
|          |
|          |
|          |
|          |
|   E      |
|          |
|          |
| g        |
|          |
|          |
+----------+

โทร

/guess/abcde/2/8

ผลตอบแทน

{x: 'higher', y: 'lower'}

หมายความว่า: * x ของคุณต่ำเกินไป (ตำแหน่งไข่สูงกว่า) * คุณ y สูงเกินไป (ตำแหน่งไข่ต่ำกว่า)

โทรถูกต้อง:

/guess/abcde/4/4

ผลตอบแทน

{x: 'right', y: 'right', turns: 10}

กฎระเบียบ

เขียนโปรแกรมเพื่อค้นหาไข่อีสเตอร์ด้วย API

  • ใช้ภาษาใดก็ได้
  • ลองเขียนโค้ดที่กระชับ แต่อ่านได้
  • โปรแกรมของคุณต้องโทร '/ new_game' ทุกครั้งและใช้ game_id ที่ส่งคืนในการเรียก 'เดา' ทั้งหมด ไม่แอบมองสวน!
  • พยายามจบเกมอย่างสม่ำเสมอด้วยจำนวนการโทรที่น้อยที่สุด
  • นี่ไม่ใช่รหัสกอล์ฟ

คำตอบของคู่แข่ง?

การได้มีโอกาสชนะที่นี่คือสิ่งที่เราต้องรู้

  • คุณใช้รหัสอะไร (ในคำตอบของคุณหรือลิงค์ GitHub ถ้ามันใหญ่กว่าที่คุณต้องการใส่คำตอบ)
  • เรียกใช้รหัสของคุณ 10 ครั้งและบันทึก game_id และให้คะแนนในแต่ละครั้ง

-game_id- : -score-

เช่น

abbbbbbb : 10

abbbbbdd : 5

(หมายเหตุ: game_ids จะต้องตรวจสอบผล)

คะแนนจะถูกคำนวณดังนี้:

  • ผลลัพธ์สูงสุดและต่ำสุดที่สองจะถูกละเว้น
  • ส่วนที่เหลืออีก 6 คะแนนจะถูกรวมเข้าด้วยกัน
  • นี่คือคะแนนของคุณ
  • คะแนนต่ำสุดชนะ

ภาคผนวก

Tl, dr: แอพเล็ก ๆ น้อย ๆ

API ถูกเขียนในระยะเวลาประมาณ 90 นาทีและใช้งานบน Raspberry Pi 2 โปรดใช้ความสุภาพกับเซิร์ฟเวอร์ API ของฉัน หากคุณ DDOS สิ่งที่น่าสงสารนี้คุณสามารถทำลายมันได้สำหรับทุกคน

นอกจากนี้ยังมีการใช้งานกับ NOIP เพื่อจำลองที่อยู่ IP แบบคงที่ แต่บางครั้งสิ่งนี้จะเลื่อนออกไปสักครู่ นั่นคือสิ่งที่ฉันได้รับจากการใช้สำหรับเว็บโฮสติ้งที่ไม่มีงบประมาณ

เพียงเพื่อหัวเราะคิกคักนี่คือการวิเคราะห์ทางสถิติอย่างง่าย ๆ ของเกมที่เล่น ... http://easter_egg_hunt.andrewfaraday.com/stats


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Dennis

คำตอบ:


3

APL + WIN

ทำงานโดยเริ่มจากกึ่งกลางและลู่เข้าหาที่ตั้งโดยการตั้งค่าขีด จำกัด บนหรือล่างให้เป็นค่าสุดท้ายและเพิ่มหรือลบความแตกต่างครึ่งหนึ่งให้เป็นขีด จำกัด ที่เหมาะสมกับการเดาครั้งสุดท้ายในแต่ละรอบ

API                                                                               
id←¯20↑¯2↓GetUrl 'http://easter_egg_hunt.andrewfaraday.com/new_game'              
xh←yh←100 ⋄ xl←yl←0 ⋄ x←50 ⋄ y←50 ⋄ c←0                                           
:repeat                                                                           
    xy←GetUrl 'http://easter_egg_hunt.andrewfaraday.com/guess/',id,'/',(⍕x),'/',⍕y
    xy←(('higher'⍷xy)+(¯1×'lower'⍷xy)+2×'right'⍷xy)~0                             
    :if xy[1]=1 ⋄ xl←x ⋄ x←x+⌈(xh-x)÷2 ⋄ :endif                                   
    :if xy[1]=¯1 ⋄ xh←x ⋄ x←x-⌈(x-xl)÷2 ⋄ :endif                                  
    :if xy[2]=1 ⋄ yl←y ⋄ y←y+⌈(yh-y)÷2 ⋄ :endif                                   
    :if xy[2]=¯1 ⋄ yh←y ⋄ y←y-⌈(y-yl)÷2 ⋄ :endif                                  
    c←c+1                                                                         
:until 4=+/2↑xy                                                                   
'id:',id,' x:',(⍕x),' y:',(⍕y),' count:',⍕c 

ฟังก์ชันนี้ใช้ฟังก์ชันต่อไปนี้เพื่อทำการเรียก API:

r←GetUrl url                                     
⎕wself←'HTTP' ⎕wi 'Create' 'MSXML2.ServerXMLHTTP'
⎕wi 'XOpen' 'GET' url 0                          
⎕wi 'XSend'                                      
r←⎕wi 'xresponseText'

ผลการทดลอง 10 ครั้งคือ:

id:rbgprkxrqzzhwdfsbszn x:36 y:52 count:7      
id:nmpcxdqsdzhgrbtlcpbp x:35 y:49 count:6      
id:qqnsbpwnlbptxxblywnz x:99 y:22 count:6      
id:nsytnvcgnsyrgzvjcysc x:45 y:28 count:6      
id:yfkpfhphjpqxtqnwpmhv x:95 y:40 count:7      
id:kxhszzrhxqlnvwvwjgnm x:49 y:6 count:6       
id:rwnwfgdpzcjpzzfmgcfn x:93 y:34 count:7      
id:tcvhtpqlfrwngybsyzqh x:95 y:94 count:6      
id:pmlmqnprwcjggjfhttmy x:20 y:41 count:6      
id:kpsmmhfhxxrrlvbbgzkv x:9 y:28 count:5                   

2

Ruby (+ JSON, HTTParty) - คะแนน: 40 (6 + 7 + 7 + 7 + 7 + 6)

นี่เป็นความท้าทายที่สนุก ฉันใช้การค้นหาแบบไบนารีเพื่อค้นหาไข่และได้ผลลัพธ์เหล่านี้:

[{:x=>34, :y=>17, :game_id=>"mgpbmdqbnklcqrdjpyrr", :count=>7},
 {:x=>99, :y=>17, :game_id=>"mhrsqfzmrrlcqxtcfgnw", :count=>7},
 {:x=>23, :y=>86, :game_id=>"zgmsrjpqvdtmqmmglstn", :count=>6},
 {:x=>24, :y=>55, :game_id=>"vkpjffyyltplztwhdsft", :count=>7},
 {:x=>12, :y=>94, :game_id=>"pxrzjvqfjrjsptvtvnfw", :count=>4},
 {:x=>83, :y=>59, :game_id=>"bdxljxkcnqmsqgnvggql", :count=>7},
 {:x=>45, :y=>40, :game_id=>"mqrsbrhbldcqwgbnmymc", :count=>7},
 {:x=>13, :y=> 9, :game_id=>"bphxkdgfcyyrvwxnfvkx", :count=>6},
 {:x=> 8, :y=>80, :game_id=>"qzdstksdwnwrhxqrczpc", :count=>7},
 {:x=>56, :y=>92, :game_id=>"ypqkfvmvwrcvvmjccvxg", :count=>6}]

นี่คือรหัส :

require 'rspec/autorun'
require 'json'
require 'httparty'
require 'pp'

GuessResult = Struct.new :x, :y, :count

class FakeGame
  def initialize(x=random_num, y=random_num)
    @x = x
    @y = y
    @count = 0
  end

  @@results = [:right, :higher, :lower]

  def guess(x, y)
    @count += 1
    GuessResult.new(@@results[@x <=> x], @@results[@y <=> y], @count)
  end

  def id
    :fake
  end

  def random_num
    rand(100) + 1
  end
end

class RealGame
  def initialize
    response = HTTParty.get('http://easter_egg_hunt.andrewfaraday.com/new_game')
    j = JSON.parse(response.body)
    @id = j['game_id']
  end

  def guess(x, y)
    response = HTTParty.get("http://easter_egg_hunt.andrewfaraday.com/guess/#{id}/#{x}/#{y}")
    j = JSON.parse(response.body)
    x_result = j['x'].to_sym
    y_result = j['y'].to_sym
    count = (j['turns']||0).to_i
    GuessResult.new(x_result, y_result, count)
  end

  def id
    @id
  end
end


class BinarySearch
  def initialize(min, max)
    @min = min
    @max = max
    @guessed = false
    update_next_guess
  end

  attr_reader :next_guess, :guessed

  def go(result)
    return if @guessed
    case result
    when :right
      @guessed = true
    when :lower
      @max = @next_guess - 1
      update_next_guess
    when :higher
      @min = @next_guess + 1
      update_next_guess
    end
  end

  private

  def update_next_guess
    @next_guess = (@max + @min) / 2
  end

end

def play(game)
  x_search = BinarySearch.new(1, 100)
  y_search = BinarySearch.new(1, 100)

  until x_search.guessed && y_search.guessed
    puts ?.
    result = game.guess(x_search.next_guess, y_search.next_guess)
    x_search.go(result.x)
    y_search.go(result.y)
  end

  {
    x: x_search.next_guess,
    y: y_search.next_guess,
    game_id: game.id,
    count: result.count
  }
end


def game_controller(game_constructor, game_count)
  (1..game_count).map do |i|
    game = game_constructor.call
    puts "Starting game #{game.id}..."
    play(game)
  end
end


def main
  # pp game_controller(->{ FakeGame.new }, 10)
  pp game_controller(->{ RealGame.new }, 10)
end

main


# tests

describe :FakeGame do

  it "returns right results" do
    game = FakeGame.new 4, 4

    result = game.guess(2, 5)
    expect(result.x).to eql :higher
    expect(result.y).to eql :lower
    expect(result.count).to eql 1

    result = game.guess(5, 3)
    expect(result.x).to eql :lower
    expect(result.y).to eql :higher
    expect(result.count).to eql 2

    result = game.guess(4, 4)
    expect(result.x).to eql :right
    expect(result.y).to eql :right
    expect(result.count).to eql 3

  end

end

describe :binary_search do
  let(:search) { BinarySearch.new 1, 100 }

  it "makes optimal guesses" do
    # aiming for 34
    expect(search.next_guess).to eql 50
    expect(search.guessed).to be_falsey
    search.go(:lower)
    expect(search.next_guess).to eql 25
    search.go(:higher)
    expect(search.next_guess).to eql 37
    search.go(:lower)
    expect(search.next_guess).to eql 31
    search.go(:higher)
    expect(search.next_guess).to eql 34
    search.go(:right)
    expect(search.next_guess).to eql 34
    expect(search.guessed).to be_truthy
  end

end

describe :fake_game do

  it "correctly responds to guesses" do
    game = FakeGame.new(34, 77)
    result = play(game)
    expect(result.y).to eql :lower
    expect(result.count).to eql 1

    result = game.guess(5, 3)
    expect(result.x).to eql :lower
    expect(result.y).to eql :higher
    expect(result.count).to eql 2

    result = game.guess(4, 4)
    expect(result.x).to eql :right
    expect(result.y).to eql :right
    expect(result.count).to eql 3

  end

end

describe '#play' do

  it "guesses correctly" do
    game = FakeGame.new(34, 77)
    result = play(game)
    expect(result[:x]).to eql 34
    expect(result[:y]).to eql 77
    expect(result[:count]).to eql 7
    expect(result[:game_id]).to eql :fake
  end

end

ดูเหมือนว่าฉันจะทำผิดพลาดที่นี่ easter_egg_hunt.andrewfaraday.com/statsระบุว่ามีเพียง 12 เกมที่เสร็จสมบูรณ์ในประวัติศาสตร์ของแอป ฉันแน่ใจว่ามีอย่างน้อย 6 เมื่อวานนี้เสร็จสมบูรณ์ แม้ว่า 160 จะยาวที่สุด ฉันจะดูมัน
AJFaraday

ดูเหมือนว่าปัญหาจะอยู่ใน RealGame # guess ซึ่งคุณได้ฮาร์ดโค้ดเกมด้วย game_id "bswtdwfdjypdtfyqxbyz" แทนที่สิ่งนี้ด้วย # {@ id} เพื่อรับชุดผลลัพธ์ที่แม่นยำยิ่งขึ้น
AJFaraday

ที่จริงฉันแก้ไขว่าหนึ่งบรรทัดและชุดผลลัพธ์ของคุณค่อนข้างดี ค่อนข้าง 6 และ 7 อย่างสม่ำเสมอ การทำงานที่ดี: D
AJFaraday

@AJFaraday โอ๊ะโอ ความผิดฉันเอง! ขอบคุณสำหรับการแก้ไข! และขอขอบคุณที่ทำสิ่งที่ท้าทายนี้!
Cristian Lupascu

คุณทำให้ฉันกังวลสักครู่หนึ่งที่นั่น;)
AJFaraday

2

Python 3 (+ ร้องขอ) 39 คะแนน

http://easter_egg_hunt.andrewfaraday.com/guess/dbxqfgldhryxymljthkx/13/82
{"turns": 7, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/kfmgrdqlyxfknbgycfwm/6/52
{"turns": 7, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/gnykwddprlfwwkrybkmc/34/91
{"turns": 6, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/xhwrqdgtdyrwrvdqqcpk/92/54
{"turns": 7, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/hmbgrnxjfgqcxhbfkztm/44/48
{"turns": 7, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/mhbchhbkppqqyxzqvrnb/62/38
{"turns": 7, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/pbrkghynqybmkmctncmr/73/25
{"turns": 6, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/sspxcsfblrnmhflgtggn/89/73
{"turns": 6, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/rlvdstmpsthktzkqbynn/4/71
{"turns": 6, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}
http://easter_egg_hunt.andrewfaraday.com/guess/wknwwcrdrmjsqxnqbvhm/50/67
{"turns": 6, "url": "http://easter_egg_hunt.andrewfaraday.com/surprise", "x": "right", "y": "right"}

คะแนน 39 (7 + 7 + 7 + 6 + 6 + 6 - 7-7-6-6)

ที่มา:

import requests
import json
url='http://easter_egg_hunt.andrewfaraday.com/guess/{id}/{x}/{y}'
start='http://easter_egg_hunt.andrewfaraday.com/new_game'
gid = requests.get(start).json()['game_id']
x=y=50
step=25
lx=lr=''
def get_new(old,value):
        if value == 'higher':
                return old+step
        elif value == 'lower':
                return old-step
        else:#right
                return old
while True:
        res = requests.get(url.format(id=gid,x=x,y=y)).json()
        if res['x'] == 'right' and res['y'] == 'right':
                print(url.format(id=gid,x=x,y=y))
                print(json.dumps(res, sort_keys=True))
                break
        x=get_new(x,res['x'])
        y=get_new(y,res['y'])
        step=step // 2 or 1

เพิ่งสังเกตเห็นว่าไม่มี gameid ในผลลัพธ์ฉันจะรันใหม่อีกครั้งและเพิ่ม id เกมในระยะเวลาสั้น ๆ
Rick Rongen

คุณได้คะแนนมากเกินไปเช่นกัน เราลดราคาสูงสุดสองรายการและผลลัพธ์ต่ำสุดสองรายการ เหลือเพียง 6 เพื่อรวม ... คุณสามารถใส่คะแนนลงในชื่อเสมอได้เช่นกัน
AJFaraday

โอ้ฉันอ่านผิดฉันคิดว่าจะลบอันแรกและอันสุดท้ายเท่านั้น ฉันจะแก้ไขมันแล้ว :)
Rick Rongen

2

PHP

<?php

error_reporting(E_ALL);

$url = 'http://easter_egg_hunt.andrewfaraday.com';
extract(json_decode(file_get_contents("$url/new_game"), true));

$i = $j = 51;
$step = 50;
$right = false;

while(!$right) {
  extract(json_decode(file_get_contents(sprintf("$url/guess/$game_id/%d/%d", $i, $j)), true));
  $lower = -$higher = $step /= 2;
  $i += $$x;
  $j += $$y;
  $right = !($$x || $$y);
}

printf('{game_id: %s; x: %2d; y: %2d; turns: %d}', $game_id, $i, $j, $turns);

ใช้file_get_contentsและjson_decode

เท่าที่ฉันสามารถบอกได้กลยุทธ์ที่เหมาะสมที่สุดต้องมีการเคลื่อนไหว 7 ครั้งโดยเฉลี่ย 5.8 การเคลื่อนไหวในหนึ่งแกนและเฉลี่ย 6.4786 การเคลื่อนไหวในสองแกน


ตัวอย่าง 10

{game_id: pfmyldcsltlbtmcfjtqr; x: 76; y: 51; turns: 6}
{game_id: jnmshsfvstcmksdcdrnj; x: 40; y:  5; turns: 7}
{game_id: wsrptrymycxjfxwvdvlh; x: 55; y: 35; turns: 7}
{game_id: fxpxtqwnxstwcxbsqtwc; x: 73; y: 93; turns: 6}
{game_id: zppntvjxnjpnlmpfzcfj; x: 71; y: 76; turns: 6}
{game_id: fzvlxqgrxcvtbbydgrpj; x: 48; y: 51; turns: 6}
{game_id: hqytpzjxkfhqhhwwfryd; x: 23; y: 87; turns: 6}
{game_id: ldsbfgcqbqpxgdhtkxsm; x: 90; y: 81; turns: 5}
{game_id: shypwsmjljyqdvwcwnxv; x: 19; y: 57; turns: 7}
{game_id: bsfrhhrvmpqfvyhjxcwh; x: 82; y: 85; turns: 6}

คะแนน: 6 + 6 + 6 + 6 + 6 + 7 = 37


เล่นกอล์ฟ, 245 ไบต์

<?$e="extract(json_decode(file_get_contents('http://easter_egg_hunt.andrewfaraday.com";eval("$e/new_game".$f="'),1));");
for($i=$j=$h=50;!$url;$l=-$h/=2)eval("$e/guess/$game_id/".-~($i+=$$x[0]).'/'.-~($j+=$$y[0]).$f);
echo$game_id,~$i,~$j,-$turns;

ตัวอย่างผลลัพธ์

$ php egg-hunt.php
hgzqmqyrznglsdwfwcft-9-86-7

2

Haskell คะแนนรวม66 40

(แก้ไข: พลาดส่วนหนึ่งเกี่ยวกับการให้คะแนนสูงสุดและต่ำสุดในการให้คะแนน)

ฉันแค่ใช้การค้นหาแบบไบนารี่ ไม่แน่ใจว่ามีวิธีไหนที่จะดีกว่า 6.5 ต่อการลองโดยเฉลี่ยโดยไม่ต้องโกง (ฉันคิดว่าฉันคงวิ่งต่อไป 10 เซตจนกว่าฉันจะได้คะแนนที่ดีขึ้น แต่ความสนุกอยู่ตรงไหน?)

ความท้าทายที่สนุกมาก ความคิดนั้นง่ายพอที่จะรวมไว้กับทุกคนและฉันมักจะไม่จัดการกับเว็บ API ในงานประจำวันของฉันและฉันก็แค่อยากลองแก้ตัวservantดังนั้นขอขอบคุณที่ :) อาจไม่ดีถ้าคุณ ' หวังว่าจะได้การแข่งขัน แต่ฉันคิดว่าความท้าทายเช่นนี้สามารถนำมาใช้เพื่อรวบรวมตัวอย่างโค้ดสำหรับผู้เริ่มต้นและสิ่งต่าง ๆ เช่นนั้น

สคริปต์ที่ปฏิบัติการได้ (รันหนึ่งเกมและรายงาน gameId และคะแนน):

#!/usr/bin/env stack
{- stack
   --resolver lts-11.2
   script
   --package servant
   --package servant-client
   --package http-client
   --package aeson
   --package text
-}

-- the above comments allow this to be run as a script if haskell-stack is installed.
-- Actual source starts here.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Main where

import Data.Aeson
import Servant.API
import Servant.Client
import qualified Network.HTTP.Client as HttpClient
import Data.Proxy
import Data.Text(Text)
import Text.Printf
import System.IO(stderr)

newtype GameID = GameID Text deriving (PrintfArg, ToHttpApiData)

instance FromJSON GameID where
  parseJSON = withObject "GameID" $ \o ->
    fmap GameID (o .: "game_id")

data Accuracy = Lower | Higher | Correct

readAccuracy :: Text -> Accuracy
readAccuracy t
  | t == "lower" = Lower
  | t == "higher" = Higher
  | t == "right" = Correct
  | otherwise = error $ printf "Unexpected accuracy text: \"%s\"" t

data GuessResult = GuessResult { xAccuracy :: Accuracy, yAccuracy :: Accuracy, turnCount :: Maybe Int }

instance FromJSON GuessResult where
  parseJSON = withObject "GuessResult" $ \o ->
    GuessResult
      <$> fmap readAccuracy (o .: "x")
      <*> fmap readAccuracy (o .: "y")
      <*> o .:? "turns"

type EggAPI =    "new_game" :> Get '[JSON] GameID
            :<|> "guess"
              :> Capture "game_id" GameID
              :> Capture "x" Int
              :> Capture "y" Int
              :> Get '[JSON] GuessResult

getNewGame :: ClientM GameID
makeGuess :: GameID -> Int -> Int -> ClientM GuessResult
getNewGame :<|> makeGuess = client (Proxy :: Proxy EggAPI)

data CoordinateRange = CoordinateRange { lowerBound :: Int, higherBound :: Int }

middleOfRange :: CoordinateRange -> Int
middleOfRange rng = lowerBound rng + (higherBound rng - lowerBound rng) `div` 2

adjustCoordinateRange :: Accuracy -> CoordinateRange -> CoordinateRange
adjustCoordinateRange Lower rng = CoordinateRange (lowerBound rng) (middleOfRange rng)
adjustCoordinateRange Higher rng = CoordinateRange (middleOfRange rng) (higherBound rng)
adjustCoordinateRange Correct rng = rng

searchForEggs :: ClientM (GameID, Int)
searchForEggs = do
  game <- getNewGame
  let initialRange = CoordinateRange 1 100
  score <- loop game initialRange initialRange
  return (game, score) where
    loop gId xRange yRange = do
      guessResult <- makeGuess gId (middleOfRange xRange) (middleOfRange yRange)
      let newXRange = adjustCoordinateRange (xAccuracy guessResult) xRange
          newYRange = adjustCoordinateRange (yAccuracy guessResult) yRange
      maybe (loop gId newXRange newYRange) return $ turnCount guessResult

main :: IO ()
main = do
  manager' <- HttpClient.newManager HttpClient.defaultManagerSettings
  let clientEnv = mkClientEnv manager' (BaseUrl Http "easter_egg_hunt.andrewfaraday.com" 80 "")
  result <- runClientM searchForEggs clientEnv
  case result of
    Left err -> hPrintf stderr  "Error: %s\n" (show err)
    Right (game, score) -> printf "GameID: %s | Score: %d\n" game score

ผล

GameID               |  Score
---------------------+-------
fdcbwwxkvhkfskqlpgnh |  7
cdgjnksfnrhgjjsdbnhd |  7
lbjjqgkvfzzprnrxcpsx |  6
rtbngkdlwdfmhdyggnjd |  6
rcphvxzzgblfnzxdqlyh |  6
gyfjbjmplkrfnqjptygl |  7
bkdnbqhsbhwwvgtcfhjb |  6
knjdxdmvttwgltjdpvtv |  7
zqpstnhjgsykkwxnxcbv |  7
rccpmsbfxqvsmzxckhcs |  7

2

JavaScript, 35 คะแนน

โพสต์โค้ดที่ไม่ดีไม่ได้นั่งได้ดีกับฉัน! : D

(async _=>{
    url=`https://crossorigin.me/http://easter_egg_hunt.andrewfaraday.com/`
    promise=await fetch(url+`new_game`)
    json=await promise.json()
    id=json.game_id
    max={x:100,y:100}
    min={x:0,y:0}
    (guess=async (x,y)=>{
        promise=await fetch(url+`guess/${id}/${x|=0}/${y|=0}`)
        json=await promise.json()
        turns=json.turns
        if(turns)
            console.log(`{game:"${id}",turns:${turns},x:${x},y:${y}}`)
        else{
            switch(json.x){
                case`higher`:
                    min.x=x
                    x+=max.x
                    x/=2
                    break
                case`lower`:
                    max.x=x
                    x+=min.x
                    x/=2
            }
            switch(json.y){
                case`higher`:
                    min.y=y
                    y+=max.y
                    y/=2
                    break
                case`lower`:
                    max.y=y
                    y+=min.y
                    y/=2
            }
            guess(x,y)
        }
    })(50,50)
})()

เกณฑ์การให้คะแนน: 5 + 6 + 6 + 6 + 6 + 6 = 35

โชคดีมากที่ดึงคะแนน 3 จากการทดสอบครั้งสุดท้ายก่อนโพสต์!

{game:"bjzkjzxwmksmbsbxtdzp",turns:3,x:75,y:12}
{game:"bvmhssnmzhlnykgxdkww",turns:5,x:93,y:71}
{game:"mcydbttxhcxwqymksgbg",turns:5,x:71,y:37}
{game:"xdynxrkxgsyltsfrqzll",turns:6,x:54,y:88}
{game:"wjdkclsqksnvdnwbspxq",turns:6,x:90,y:13}
{game:"mgvlssfgjcgtylwqpvhq",turns:6,x:26,y:68}
{game:"rgjvbkrlzqvpdfphqxtq",turns:6,x:19,y:81}
{game:"hgrscvfzgrkzzjvkjjwb",turns:6,x:41,y:19}
{game:"lrfrblmmkggghntshnkj",turns:7,x:86,y:32}
{game:"ldsndvjsbvgvbhbtfckp",turns:7,x:24,y:7}

ลองมัน

ใช้รหัสที่ค่อนข้างกอล์ฟรุ่นด้านบน!


นี่ไม่ใช่โค้ดกอล์ฟจริง ๆ คุณสามารถขยายออกไปเล็กน้อยเพื่อความชัดเจนหากคุณต้องการฮ่า ๆ
Cubic

@ Cubic คุณพูดถูกฉันน่าจะทำ! : DI พบว่ามันยากอย่างไม่น่าเชื่อที่จะไม่กระทืบรอบไบต์ที่นี่แม้ว่าจะไม่ใช่code-golf !
Shaggy

1

สนิม

อย่างที่มันเกิดขึ้น Rust มีไลบรารี่ที่ดีมากที่เรียกว่า deserialization library serdeซึ่งช่วยได้มากกับโปรแกรมนี้ ขั้นตอนวิธีการของตัวเองคือการค้นหาไบนารีค่อนข้างตรงไปตรงมายกเว้นวิ่งสองครั้ง - ครั้งเดียวสำหรับและอีกครั้งสำหรับxy

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

Cargo.toml

[package]
name = "easter-egg-hunt"
version = "0.1.0"
authors = ["Konrad Borowski"]

[dependencies]
reqwest = "0.8.5"
serde = "1.0.36"
serde_derive = "1.0.36"

main.rs

extern crate reqwest;
extern crate serde;
#[macro_use]
extern crate serde_derive;

use reqwest::Client;

#[derive(Deserialize)]
struct NewGame {
    game_id: String,
}

#[derive(Deserialize)]
struct Guess {
    x: GuessStatus,
    y: GuessStatus,
    turns: Option<u32>,
}

#[derive(Deserialize)]
#[serde(rename_all = "lowercase")]
enum GuessStatus {
    Lower,
    Right,
    Higher,
}

macro_rules! url {
    ($path:expr) => {
        concat!("http://easter_egg_hunt.andrewfaraday.com", $path)
    };
    ($path:expr $(, $part:expr)*) => {
        &format!(url!($path) $(, $part)*)
    };
}

struct BinarySearch {
    low: u8,
    high: u8,
}

impl BinarySearch {
    fn new() -> Self {
        BinarySearch { low: 1, high: 100 }
    }

    fn current_guess(&self) -> u8 {
        (self.low + self.high) / 2
    }

    fn update(&mut self, guess_status: GuessStatus) {
        let current_guess = self.current_guess();
        match guess_status {
            GuessStatus::Lower => self.high = current_guess - 1,
            GuessStatus::Higher => self.low = current_guess + 1,
            GuessStatus::Right => {
                self.high = current_guess;
                self.low = current_guess;
            }
        }
    }
}

fn run_game(client: &Client) -> reqwest::Result<()> {
    let NewGame { game_id } = client.get(url!("/new_game")).send()?.json()?;
    let mut x_search = BinarySearch::new();
    let mut y_search = BinarySearch::new();
    loop {
        let x_guess = x_search.current_guess();
        let y_guess = y_search.current_guess();
        let response = client
            .get(url!("/guess/{}/{}/{}", game_id, x_guess, y_guess))
            .send()?
            .json()?;
        match response {
            Guess { x, y, turns: None } => {
                x_search.update(x);
                y_search.update(y);
            }
            Guess {
                turns: Some(turns), ..
            } => {
                println!("id:{} x:{} y:{} count:{}", game_id, x_guess, y_guess, turns);
                return Ok(());
            }
        }
    }
}

fn main() {
    let client = Client::new();
    for _ in 0..10 {
        run_game(&client).unwrap();
    }
}

สรุป

id:tlxjnjtslnsnbdxyzlvn x:97 y:22 count:7
id:bbzpyhhflrdjzylwxtbr x:21 y:6 count:5
id:kcjdkfvddgxckmprxwtw x:81 y:99 count:6
id:tnzryxpkblqrqbqrqkby x:30 y:25 count:7
id:pbzkdrmjrvwmkgmlvwcb x:79 y:20 count:7
id:qxvcbcslkdmjxnffsxfb x:36 y:94 count:7
id:hqfgpdmktyfwqtbrvvly x:94 y:71 count:5
id:ytgsnssvlpnhzqzgvygw x:1 y:83 count:7
id:gjhglmkbhvswqwgrynft x:65 y:94 count:5
id:rzghpypysxtwkclgpbkx x:55 y:96 count:7

5 + 6 + 7 + 7 + 7 + 7 = 39


1

Python 2

vesrion Golfed - 276 ไบต์

from requests import*
u='http://easter_egg_hunt.andrewfaraday.com'
i=get('%s/new_game'%u).json()['game_id']
x=y=50;s=25;o={}
while not'turns'in o:o=get('%s/guess/%s/%d/%d'%(u,i,x,y)).json();exec("%s+=s*'rh'.rfind(o['%s'][0]);"*2)%tuple('xxyy');s=s%2+s/2
print i,x,y,o['turns']

รุ่น + ความคิดเห็นที่อ่านได้เพิ่มเติม

from requests import*
u='http://easter_egg_hunt.andrewfaraday.com'
i=get('%s/new_game'%u).json()['game_id'] # get game id
x=y=50    # initial central position
s=25      # step of binary search
o={}      # initialize o to further store returns
while not'turns'in o:    # cycle until 'turns' occurs in return
    o=get('%s/guess/%s/%d/%d'%(u,i,x,y)).json()
    exec("%s+=s*'rh'.rfind(o['%s'][0]);"*2)%tuple('xxyy');s=s%2+s/2
    # this exec is used to shorten two similar lines for x and y:
    #  x += s * (... o['x'] ...); 
    #  s*'rh'.rfind(o['%s'][0]) - look at first letter of return and use its position in string 'rh' to map multipliers for step: 
    #                             -1 for lower, +1 for higher and 0 for right 
    #                             rfind() will return -1 for not finding l
    s=s%2+s/2    # divide step in two, rounding up
print i,x,y,o['turns']

ผล

vjwqvbydwmbvbrhwrxqz 19 95 4
svkdvszghjzfbvqxsprt 5 12 4
dvbpnxjdgrydwffcndnt 81 67 6
qqwgsctqhdcrbywwrcxf 21 49 6
zrgqqtzjjrrsqbgvkbsm 37 12 6
trzjngljbwbwxycxpcbk 91 2 7
kysjwfzsrdjsybrchnzg 76 45 7
kcjtxqfmcgszrwkyhlkm 68 48 7
wykbjvthqmcyzscxnsxt 68 41 7
kldrfccjdphzqnqcmdgz 88 14 7

สรุป

ค่อนข้างคาดหวัง: D
6 + 6 + 6 + 7 + 7 + 7 = 39


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