6 개 이하의 동작으로 마스터 마인드 해결


24

당신의 목표는 6 개 이하의 움직임으로 Mastermind 퍼즐을 해결하는 프로그램을 작성하는 것입니다.

배경

Mastermind는 보드 게임입니다. 이 게임의 목표는 다른 플레이어가 숨겨둔 4 개의 컬러 페그의 조합 (컬러 및 순서)을 정확하게 추측하는 것입니다. 추측하면 다른 플레이어는 0에서 4 사이의 흰색 및 / 또는 빨간색 못으로 응답합니다. 빨간 말뚝은 색상과 위치가 올바른 곳입니다. 흰색 말뚝은 색상이 나머지 조각으로 표시되지만 잘못된 위치에 있습니다. 추측에 중복 된 색상이있는 경우 비밀의 해당 색상 당 하나의 페그 만 수여됩니다. (따라서-비밀에 1 개의 파란색이 포함되어 있고 추측에 올바른 위치에 1 개의 파란색이 있고 2 개의 빨간색 페그가있을 것입니다). 6 가지 색상이 있으며 복제본을 사용할 수 있습니다.

예를 들어 게임은 다음과 같이 진행될 수 있습니다. (솔루션이 빨강 녹색 녹색 파랑이라고 가정)

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

규칙은 Wikipedia에서 확장됩니다

요구 사항

  • 프로그램은 stdin에서 읽고 stdout에 써야합니다.
  • 색상 대신 단순성을 위해 숫자를 사용합니다. 추측 할 조합은 1과 6 사이의 4 개의 숫자입니다.
  • 그들은 1 줄에서 6 줄 사이의 줄 바꿈으로 끝나는 일련의 4 개의 공백으로 숫자를 추측하여 출력해야합니다. 예를 들어 :

    1 5 2 2 \ n

  • 프로그램은 공백으로 구분되고 개행 문자로 끝나는 0에서 4 사이의 정수 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 

채점

  • 순수하고 간단한 코드 골프 입니다. 바이트 단위 의 최단 솔루션 이깁니다.

이것이 나의 첫 번째 코드 골프 질문입니다. 내가 잘못한 일이 있으면 사과하지만 가능한 한 모호성이 없는지 확인하고 가능한 한 많은 변호사 변호사를 막으려 고 노력했습니다. 모호하거나 명확하지 않은 경우 언제든지 질문하십시오.


1
귀하의 예에서 입력 / 출력은 1 2 3 4반환 하지 않아야 0 1합니까?
Gaffi

1
예제 텍스트에서 "Green Green Green Blue"가 흰색 페그도 제공해서는 안됩니까 (첫 번째 Green의 경우)? 편집-위키 백과는 당신이 쓴 것처럼 흰색을 주어서는 안된다는 것을 분명히합니다. 그러나 나는 흰색 / 검은 색 규칙이 질문에 명시 적으로 언급되어야한다고 생각합니다.
ugoren

작동이 얼마나 느려 집니까?
반 시계 회전을 중지

@Gaffi-절대적으로 맞습니다-고정
lochok

1
화이트 페그의 규칙은 여기에 명시되어 있지 않습니다. 1234를 선택하고 5611을 추측한다고 가정하십시오. 내 1은 모두 잘못된 위치에 올바른 색상이므로 2 개의 흰색을 얻습니다. 그러나 아니오-Wikipedia는 흰색이라고 말합니다. 잘못된 방법은 프로그래밍하기도 쉽지만 Steven Rumbalski는 Wikipedia의 규칙을 올바르게 구현했습니다.
ugoren

답변:


8

Python 2 Python 3, 359365338

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)는 반복 가능해야합니다
Blazer

내 루프 구조는 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

@블레이저. 이 출력을 유발 한 테스트 사례는 무엇입니까?
Steven Rumbalski

@Blazer : 4 0네 개의 흰색 못입니다. 나는 당신이 점수를 반대로 생각합니다.
Steven Rumbalski

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 움직임에서 정확한 추측을 보장합니까?
ugoren

어 나는 그것이 OP의 예제와 다른 솔루션에서 작동 한다고 생각 했지만 철저한 테스트는 때로는 7 가지 추측이 필요하다는 것을 보여줍니다. 나는 아직이 일을해야 할 것이다!
반 시계 회전을 중지

5

Python, 385 357 자, 5 개의 이동으로 해결

내가 그것을 바꿀수록 Steven Rumbalski와 같이 점점 더 커집니다 ... 주요 차이점은 정수가 아닌 문자열로 작업한다는 것입니다.
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)
gnibbler

from collections import*
gnibbler

a,b=map(int,raw_input())
gnibbler

product(*[range(1,7)]*4)
gnibbler

Counter(r(x,i)for i in A).values()
gnibbler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.