루비, 레브 B 121 바이트
제출은 익명 함수에서 빼기 f=
입니다. 사용을 설명하기 위해 테스트 프로그램에 표시됩니다.
f=->n{["~mK)\7","}uYwQO"][l=n%2].bytes{|t|9.times{|i|(m=n|1<<i)==n||8.times{|j|m/2*257>>j&255==126-t&&t+j%2!=119&&l=m}}}
l}
puts g=f[gets.to_i]
puts
[7,6,5,
8,0,4,
1,2,3].each{|i|print g>>i&1; puts if i/3==1}
중앙 정사각형을 최상위 비트 대신 최하위 비트로 만들어 2 바이트를 절약합니다 ( /2
대신 대신 제거 %256
). 허용 가능한 이동 테이블을 재구성하여 남은 비용 절감. X의 총 개수가 아닌 중앙 정사각형 여유 공간 / 빈 공간으로 구성하면 테스트가 더 간단 해집니다. 또한 배열에 문자열이 2 개뿐이므로 %w{string1 string2}
구문이 구문을 포기 ["string1","string2"]
합니다. 이를 통해 인쇄 할 수없는 문자 \7
를 포함시킬 수 있으며, 126-t
대신에 보다 간단한 인코딩을 사용할 수 있습니다 (36-t)%120
.
루비, 레브 A 143 바이트
->n{l=r=("%b"%n).sum%8
%w{$ %5 - I+Wy Q S#}[r].bytes{|t|9.times{|i|(m=n|1<<i)==n||8.times{|j|m%256*257>>j&255==(t-36)%120&&t+j%2!=43&&l=m}}}
l}
이것은 익명의 기능입니다. 입력 / 출력 형식이 열려 있으므로 9 비트 이진수로갔습니다. 512 비트는 중심을 나타내고 나머지 비트는 그 주위를 나선형으로합니다 (1 비트는 코너로 간주됩니다).
허용 가능한 출력보다 훨씬 많은 입력이 가능하므로 알고리즘은 모든 움직임을 시도하고 허용 가능한 출력 패턴에 맞는 것을 찾는 것입니다. 각 X 수에 허용되는 출력 패턴이 하드 코딩됩니다.
중앙 정사각형에 대한 정보가 제거되고 나머지 8 비트에 257을 곱하여 복제합니다. 그런 다음이 패턴은 오른쪽 이동으로 허용 가능한 패턴을지나 회전됩니다.
패턴이 발견 될 때 루프가 종료되지 않으므로 리턴 된 패턴은 마지막으로 허용되는 패턴입니다. 이러한 이유로, 선호 패턴이있는 선호 패턴이 나중에 목록에 나타납니다.
'Knights move'전략을 고려할 때 패턴이 45도 회전하는지 여부는 중요하지 않습니다. ungolfed 버전은 기사 이동 전략을 따르므로 코너 사각형과 가장자리 사각형을 구분할 필요가 없습니다.
그러나 다음과 같은 트릭이 있기 때문에 이것이 항상 최선의 전략은 아닙니다. 상대방이 먼저 가고 중앙을 차지하면 승리해야합니다. 그러나 그의 두 번째 움직임에서 그는 당신이 2x2 정사각형을 만들 수 없다는 오류를 범합니다. 이것은 골프 버전으로 구현됩니다. 이 경우에는 코너에있는 3 개의 X (상대방을 잃게 함)와 한 쪽 가장자리에있는 3 개의 X (즉시 자살)를 구분하기 위해 약간의 추가 코드가 필요합니다.
테스트 프로그램에서 언 골프
ungolfed 버전은 질문에 표현 된 논리를 따릅니다.
골프 버전에서는 테이블이 약간 다르게 수정되어 [[0],[1,17],[9],[37,7,51,85],[45],[47,119]]
사건에 대해 약간 다른 동작을 구현합니다 r=3
. 그런 다음 인쇄 가능한 ASCII로 압축됩니다 (디코딩 필요 (t-36)%120
). 표 항목 7의 경우 모서리에있는 3 개의 X와 모서리에있는 3 개의 X를 구별하려면 추가 비트가 필요합니다.&&t+j%2!=43
f=->n{l=r=("%b"%n).sum%8 #convert input to text, take character checksum to count 1's(ASCII 49.)
#0 is ASCII 48, so %8 removes unwanted checksum bloat of 48 per char.
#l must be initialised here for scoping reasons.
[[0],[1,17],[9],[11,13,37,51,85],[45],[47,119]][r].each{|t| #according to r, find the list of acceptable perimeter bitmaps, and search for a solution.
9.times{|i|(m=n|1<<i)==n|| #OR 1<<i with input. if result == n, existing X overwritten, no good.
#ELSE new X is in vacant square, good. So..
8.times{|j|m%256*257>>j&255==t&&l=m}} #%256 to strip off middle square. *257 to duplicate bitmap.
#rightshift, see if pattern matches t. If so, write to l
}
l} #return l (the last acceptable solution found) as the answer.
#call function and pretty print output (not part of submission)
puts g=f[gets.to_i]
puts
[6,7,0,
5,8,1,
4,3,2].each{|i|print g>>i&1; puts if i<3}
테스트 프로그램의 출력
이것은 컴퓨터 자체가 재생 될 때 발생합니다.
C : \ Users \ steve> ruby tictac.rb
0
256
000
010
000
C : \ Users \ steve> ruby tictac.rb
256
384
010
010
000
C : \ Users \ steve> ruby tictac.rb
384
400
010
010
100
C : \ Users \ steve> ruby tictac.rb
400
404
010
010
101
C : \ Users \ steve> ruby tictac.rb
404
436
010
110
101
C : \ Users \ steve> ruby tictac.rb
436
444
010
110
111
게임 분석 첫 게임
이것은 실제로 매우 간단하고 선형입니다.
처음 플레이 할 때 중간 스퀘어는 항상 첫 번째 스퀘어가됩니다.
r = 0
... binary representation 0
.X.
...
r = 2
X.. binary representation 1001=9
.XX
...
r = 4
X.. binary representation 101101=45
.XX
XX.
게임이 끝나지 않고 보드의 중간 정사각형을 포함하여 5 개의 X를 갖는 한 가지 방법 (최대 대칭까지)이 있습니다. 중간 정사각형에는 X가 있으며, 대각선 1 개 (각각 90도)와 가로 / 세로 중심선 (90도)이 있습니다. 배열 가능. 다른 플레이어는 다음 이동에서 잃어야합니다.
게임 분석 두 번째 게임
다른 플레이어가 중간 정사각형을 선택하는지에 따라 플레이는 상당히 다릅니다.
r = 1
점령 된 중간 광장
.X. X.. binary representation 1
.X. .X.
... ...
중간 광장 무료
X.. .X. binary representation 10001=17
... ...
..X .X.
r = 3
다른 플레이어가 마지막 X 근처에서 플레이하는 경우 중간 정사각형 점령되지 않은 버전에서 다음과 같이 기사의 이동을 재생하는 것이 지원됩니다.
XX. .XX binary representation 1011=11
.X. XX. or mirror image 1101=13
X.. ...
그러나 위의 방법은 최선의 방법이 아니며 골프 버전에서는 지원되지 않습니다. 가장 좋은 움직임은 다음과 같습니다. 다음 턴에 승리합니다.
XX. binary representation 111=7. XXX
XX. Only to be used where j is odd. .X.
... Even j would look like image to right. ...
다른 플레이어가 마지막 X에 90도 또는 135도를 재생하면 중앙 광장이 점령됩니다 (나이트 이동 거리).
X.X .X. binary representation 100101=37
.X. .XX
.X. X..
중간 광장 무료
X.X .X. XX. binary representations:
... X.X ... 1010101=85 (first two)
X.X .X. .XX and 110011=51 (last one)
r = 5
중간 광장이 점령되었습니다. 위에서 r = 4에 언급 된 이유로, 네 가지 가능한 움직임이 있으며,이 모두는 잃습니다. 하나만 지원됩니다 (101111 = 47).
중간 광장 무료. 다음과 같이 대칭까지 가능한 보드는 하나뿐입니다. 다른 플레이어는 다음 이동시 패해야하므로 r> 5를 지원할 필요가 없습니다.
XX. binary representation 1110111=119
X.X
.XX