素晴らしいAPIイースターエッグハント!


15

APIイースターエッグハント!

http://easter_egg_hunt.andrewfaraday.comには、特別なイースターエッグハントを提供するAPIがあります。

上記のアドレスで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'を呼び出し、すべての 'guess'呼び出しで返されたgame_idを使用する必要があります。庭を覗かないで!
  • 可能な限り少ない通話数でゲームを一貫して終了するようにしてください。
  • これはコードゴルフではありません。

競争力のある答え?

勝つチャンスを得るには、次のことを知っておく必要があります。

  • どのコードを使用していますか(回答内、または回答よりも大きい場合はgithubリンク)。
  • コードを10回実行し、毎回game_idとスコアを記録します。

-game_id -:-スコア-

例えば

abbbbbbb:10

abbbbbdd:5

(注:結果を確認するにはgame_idsが必要です)

スコアは次のように計算されます:

  • 最高と最低の2つの結果は無視されます。
  • 残りの6つのスコアは合計されます。
  • これがあなたのスコアです。
  • 最低スコアが勝ちます。

補遺

Tl、dr:アプリは少し見苦しいです。

APIは約90分のスペースで作成され、Raspberry Pi 2にデプロイされます。私のAPIサーバーにはご注意ください。この悪いことをDDOSするなら、みんなのためにそれを台無しにすることができます。

また、静的IPアドレスをシミュレートするためにNOIPで実装されていますが、これはしばらくの間ドロップアウトする場合があります。それは私が予算ゼロのウェブホスティングに使用するために得るものです。

笑いのために、ここではプレイされたゲームの簡単な統計分析があります... http://easter_egg_hunt.andrewfaraday.com/stats


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
デニス

回答:


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

実際、1行と結果セットがかなり良いことを修正しました。むしろ一貫して6と7の。良い仕事:D
AJFaraday

@AJFaradayおっと。私の悪い!修正していただきありがとうございます!そして、この楽しいチャレンジをしてくれてありがとう!
クリスティアンルパスク

そこにちょっと心配していました;)
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を少し追加します
リックロンゲン

また、あなたは自分自身を過大評価しています。最高の2つの結果と最低の2つの結果を割引します。合計6つだけ残して...スコアを常にタイトルに入れることもできます。
AJFaraday

ああ、私は誤解しました。最初と最後の1つだけを削除することを考えました。それから修正します:)
リックロンゲン

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_contentsjson_decodeを

私の知る限り、最適な戦略には、1つの軸で平均5.8の移動と、2つの軸で平均6.4786の移動で、最大7つの移動が必要です。


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

(編集:スコアリングで最高と最低の結果を落とす部分を逃しました)

バイナリ検索を使用しています。不正行為をせずに平均して1回の試行で6.5を超える方法があるかどうかはわかりません(より良いスコアを取得するまで10のセットを実行し続けることができると思いますが、その面白さはどこにありますか?)。

ああ、ところで非常に楽しい挑戦。アイデアは全員を包括するのに十分なほど単純であり、私は通常、日々の仕事でWeb APIを扱っておらず、試してみる言い訳が必要ですservantので、そのための感謝:)あなたであれば、おそらくそれほど大きくありません」競争を期待していますが、このような課題は初心者向けのコードサンプルやそのようなものを収集するために使用できると思います。

実行可能スクリプト(1つのゲームを実行し、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は、コードゴルフではない場合でも、バイトをクランチしないことを信じられないほど難しくしています!
シャギー

1

さび

たまたま、Rustにはserdeこのプログラムで非常に役立つ非常に素晴らしいデシリアライゼーションライブラリがあります。アルゴリズム自体は、2回実行されることを除いて、かなり単純なバイナリ検索xですy

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

ゴルフヴェスリオン-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.