6移動以内で首謀者を解く


24

あなたの目標は、6つ以下の動きで首謀者のパズルを解決するプログラムを書くことです。

バックグラウンド

首謀者はボードゲームです。ゲームの目標は、他のプレイヤーが隠している4色のペグの組み合わせ(色と順序)を正確に推測することです。推測が行われると、他のプレーヤーは0〜4個の白または赤のペグで応答します。赤いペグは、色と場所が正しい場所です。白いペグは、残りの部分で色が表されている場所ですが、間違った場所にあります。推測に重複する色がある場合、秘密の対応する色ごとに1つのペグしか付与されません。(つまり、シークレットに1つのブルーが含まれていて、推測に2つのブルーがあり、1つが正しい場所にある場合、1つの赤いペグが与えられます)。6つの異なる色があり、複製を使用できます。

したがって、たとえば、ゲームは次のようになります(ソリューションがRed Green Green Blueであると想定)

1:  Blue Purple Black Green - 2 white pegs
2:  Green Red Black Blue    - 2 white pegs, 1 red peg
3:  Green Green Green Blue  - 3 red pegs
4:  Red Green Green Blue    - 4 red pegs

ルールはウィキペディアで拡張されています

必要条件

  • プログラムはstdinから読み取り、stdoutに書き込む必要があります
  • 色の代わりに簡単にするために数字を使用します。推測する組み合わせは、1〜6の4つの数字になります。
  • 推測は、改行で終わる1〜6の一連の4つのスペースで区切られた数値として出力する必要があります。例えば:

    1 5 2 2 \ n

  • プログラムは、スペースで区切られ、改行で終わる0〜4の2つの整数を推測した後、入力として受信します。1つ目は白いペグの量、2つ目は赤いペグの量です。

  • 「0 4」(4つの赤いペグ)の入力で、プログラムは終了する必要があります
  • プログラムは、6ターン未満でパズルを解くことができなければなりません(プログラムが出力し、応答入力が1ターン続く)。それをより少なく解決できることに対する(証明の複雑さによる)ボーナスはありません。
  • ソリューションは完全に内部にあり、ソースに含まれている必要があります。標準ライブラリのみが許可されています。したがって、ソリューションは他のファイル(辞書など)やインターネットに依存しない場合があります。

入出力の例

> is your programs output
< is the responding input
Solution is 1 5 6 6

> 1 2 3 4
< 0 1
> 4 1 6 6
< 1 2
> 1 6 5 6
< 2 2
> 1 5 6 6
< 0 4 

得点

  • これは純粋でシンプルなコードゴルフです。バイト単位の最短ソリューション勝ちです。

これは私の最初のCode Golfの質問です。何か間違ったことをしてしまった場合はおologiesび申し上げますが、曖昧さが絶対にないようにし、可能な限り多くのルール弁護士を防ぐように、できる限り努力しました。曖昧または不明瞭な場合は、お気軽に質問してください。


1
あなたの例では、入力/出力は1 2 3 4返されません0 1か?
ガフィ

1
また、テキストの例では、「Green Green Green Blue」も白いペグを与えるべきではありません(最初のグリーンについて)。編集-あなたが書いたように、ウィキペディアは白を与えてはならないことを明確にします。しかし、私は質問で白/黒のルールを明示的に述べるべきだと思います。
ウゴレン

動作が遅くなりますか?
反時計回りに

@Gaffi-絶対に正しい-修正
済み-lochok

1
白いペグのルールはここには記載されていません。1234を選択し、5611を推測するとします。私の1はどちらも間違った場所で正しい色であるため、ルールを説明した方法から、私は2つの白を取得すると言います。しかし、いや-ウィキペディアは、それが1つの白だと言います。誤った方法はプログラミングも簡単です(ただし、Steven RumbalskiはWikipediaのルールを正しく実装しました)。
ugoren

回答:


8

Python 2 Python 3、359 365 338文字

from itertools import*
from collections import*
m=h=set(product(*['123456']*4))
def f(g,k):b=sum(x==y for x,y in zip(g,k));return'%s %s'%(sum(min(g.count(c),k.count(c))for c in set(g))-b,b)
while len(m)>1:g=min(h,key=lambda g:max(Counter(f(g,k)for k in m).values()));print(*g);s=input();m=set(x for x in m if s==f(g,x))
print(*(m.pop()))

面白いことに、5文字の変数名があることに気付くまでに多くの編集が必要でした。

私は長い輸入が好きではありません。collections.Counterインポートを節約するための置換を実装できるはずです。

私もprint(*(m.pop()))最後に好きではありません。whileループの中に消えていくような気がしますが、長くしないとそれをする方法が見つかりません。


TypeError: join() takes exactly one argument (2 given)return j(sum(min(g.count(c),k.count(c))for c in set(g))-b,b)。また、sum()はintを返しますが、j(str.join)は反復可能なものを取る必要があります
ブレイザー

私のループ構造はfinalを取り除き、print少し短くなると思います。また、要求された動作によく一致します(答えがわかっているときではなく、「4 0」で停止します)。そしてlen(m)>1== m[1:]。インポートは本当に迷惑です- from a,b import *良かったでしょう。
ugoren

このプログラムは、それが正しいと感じるときはいつでも終了するようです。一度実行して、5回の推測で停止したが、正しくありませんでした。次回、4回の推測で停止し、それが正しかったが、私は4 0まだ客観的な基準にある入力すらしていませんでした。それ以外の場合は例外で終了します:print(*(m.pop())) KeyError: 'pop from an empty set'
ブレイザー

@ブレザー。この出力を引き起こしたテストケースは何ですか?
スティーブンランバルスキー

@Blazer: 4 04つの白いペグです。スコアが逆になっていると思います。
スティーブンランバルスキー

7

ハスケル、317 304

q[0,4]_=error""
q[n,m]l=(\s->all(==4-m)[g s,n+g(u(foldr((u((.drop 1).(++)).).break.(==)))$unzip s)]).c(u(/=)).zip l
u=uncurry;m=map;g=length;c=filter
f a=[head.c(($(zipWith q(take n a)$f a)).all.flip($)).sequence$replicate 4[1..6]|n<-[0..]]
main=interact$unlines.m(unwords.m show).f.m(m read.words).lines

私は純粋に機能的なインタラクティブプログラムを書くのが大好きです!しかし、もちろんこのスタイルには一定の制限があります。エラーで終了しますが、これがうまくいかないと指定していません。IOエラーなしで終了するには、すべてをモナドにリファクタリングする必要があります。


6手で正しい推測を保証しますか?
ウゴレン

あー 私それはそうだと思っていましたが(OPの例と他のソリューションで動作します)、徹底的なテストにより、7つの推測が必要になることがあります。まだこれに取り組む必要があります!
反時計回りに

5

Python、385 357文字、5移動で解決

私がそれを変更すればするほど、それはスティーブン・ランバルスキーのようにますます成長します...主な違いは、彼が整数ではなく文字列を扱うことです。
Knuthのアルゴリズムを実装しました(今は正しく、願っています)。
Steven Rumbalskiから得点関数を借りました。
最初の推測を生成するのに長い時間がかかり、後で良くなります。
それをハードコーディング(g=len(A)==1296 and [1,1,2,2] or ...)すると、テストしたい場合に便利です。
私はセミコロンで置き換えることができる4つの改行とタブのペアをカウントしません。

from collections import*
from itertools import*
a=B=A=list(product(*[range(1,7)]*4))
r=lambda g,k:(sum(x==y for x,y in zip(g,k)),sum(min(g.count(c),k.count(c))for c in set(g)))
while a!=4:
    g=A[1:]and min(B,key=lambda x:max(Counter(r(x,i)for i in A).values()))or A[0]
    print"%d "*4%tuple(g)
    b,a=map(int,raw_input().split())
    A=[x for x in A if r(g,x)==(a,a+b)]

"%d "*4%tuple(g)
ニブラー

from collections import*
ニブラー

a,b=map(int,raw_input())
ニブラー

product(*[range(1,7)]*4)
ニブラー

Counter(r(x,i)for i in A).values()
ニブラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.