전쟁 게임의 결과 찾기


15

전쟁 게임의 결과 찾기

제가 초등학교에있을 때, 우리는 "바위 가위"게임을했습니다. 우리는 선생님을 기다릴 때나 쉬는 시간에 어셈블리를 할 때 할 것입니다. 우리는 "전쟁"이라고 불렀습니다. 그러나 일부 검색 후, 이것은 WikiHow에 따르면 "Shotgun Game" 의 훨씬 간단한 변형입니다 . 규칙이 약간 다르기 때문에 "War"라고 부르겠습니다.

두 사람이 서로 가로 질러 앉아 있습니다. 게임의 목표는 상대방을 "죽이는"것입니다. 매 턴마다 3 개의 동작 중 하나를 재생할 수 있습니다.

  • 재 장전 : 당신은 한 발의 총을 가지고 있습니다. 매번 발사하기 전에 다시로드해야합니다. 이미 탄약을 가지고있을 때 재장 전하는 것은 합법적이지만 아무것도하지 않습니다. 재 장전은 양손으로 사원을 두드려 상징되었습니다. 각 플레이어는 0 탄약으로 시작합니다.

  • 가드 : 유일한 안전한 움직임. 지키는 동안 총을 맞으면 죽지 않습니다. 가슴 위로 팔을 교차시켜 보호를 상징했습니다.

  • 발사 : 총을 발사하십시오. 성공적으로 발사하려면 마지막 사격 이후 재장 전해야합니다. 상대방이 재 장전하면 승리합니다. 그들이 또한 발사하고 둘 다 탄약을 가지고 있다면, 그것은 무승부입니다. 그들이 지키고 있다면, 당신은 탄약을 낭비합니다. 탄약없이 발사하는 것은 합법적 인 행동이지만, 아무것도하지 않으며 재장 전처럼 취약합니다. 발사는 다른 선수를 가리키는 것으로 상징되었습니다.

RPS와 비슷하게 플레이되었습니다. 각 플레이어는 동시에 자신의 선택을 포기합니다 (우리는 다리 사이를 두 번 두드려서 서로 리듬을 유지하지만 도전에는 중요하지 않습니다).

도전 과제 :

당신의 임무는 전쟁 게임의 결과를 찾는 것입니다. 함수 또는 전체 프로그램 일 수 있습니다.

입력

  • 각 플레이어가 각 턴에서 선택한 옵션은 문자 / 문자열로 표시됩니다.

    • r : 새로 고침

    • g : 가드

    • f : 불

  • 입력은 쌍의 목록, 구분 / 구분되지 않은 문자열 또는 이러한 행을 따르는 다른 항목이됩니다.

Python의 입력 예 [("r", "g"), ("f", "r")]는 첫 번째 플레이어가 다시로드되고 두 번째 플레이어가 보호되는 것을 의미합니다. 두 번째 턴에서는 첫 번째 플레이어가 발사되고 두 번째 플레이어가 다시로드됩니다. 플레이어 1 명이이 게임에서 승리합니다. 동일한 입력이 선택적으로 표시 될 수있는 "r g f r", "rgfr", "rg fr" "rg-fr"...

다음을 가정 할 수 있습니다.

  • 입력 한 내용은 선택한 형식과 일치하며 유효한 문자 만 포함합니다.

  • 누군가 100 턴 안에 죽을 것입니다.

그러나 누군가 죽으면 회전이 끝났다고 가정 할 수는 없습니다.

산출

누가 이겼는지 (또는 누가 먼저 이겼는지) 나타내는 값 *입니다. 각 시나리오에 대해 출력 할 항목을 선택할 수 있지만 다음을 고려해야합니다.

  • 플레이어 1 승리

  • 플레이어 2 승리

  • 그들은 서로를 죽입니다 (무승부)

각 결과에는 지구 가치가 있어야하며 각 시나리오마다 항상 동일해야합니다.

예를 들어 1, 플레이어 1이 이길 2때, 플레이어 2가 이길 때 그리고 0추첨의 경우에 출력 할 수 있습니다. 그런 다음 플레이어 1이 이길 때, 플레이어 2가 이길 때 그리고 추첨의 경우 항상 출력 해야합니다 .120

반환하거나 stdout에 인쇄 할 수 있습니다. 후행 공백이 좋습니다.

확실히, 무승부로 이어지는 유일한 시나리오는 두 선수가 모두 발사하고 둘 다 탄약을 가지고있는 경우입니다.

*이 도전에서 누군가가 죽은 후에도 턴이 계속 될 수 있기 때문에 결국 1 명 이상의 플레이어가 이길 수 있습니다. 입력에 따라 누가 먼저 이겼는지 찾아야합니다.

테스트 사례 ( 1P1이 이길 2때, P2가 이길 때, 그리고 0추첨에 대한 가정 ) :

"rg fr" => 1 (P1 shot P2 while they were reloading)

"rg ff" => 1 (They both shot, but only P1 had ammo)

"rr ff" => 0 (Both had ammo and shot each other)

"rr ff rr fg" => 0 (Both had ammo and shot each other. Everything after the first win is ignored)

"rr fg rf" => 2 (P2 shot P1 while they were reloading)

"rf gg rr fg rr fr" => 1
    (P2 tried to shoot but didn't have any ammo, then they both guarded, then they both reloaded, then P2 blocked a shot, then they both reloaded again [but P2 still only has 1 ammo!], then P1 shoots P2 while they're reloading.

"rr gf fr rf gg rg ff" => 1
       ^ Player 1 wins here. The rest to the right has no effect on the output

이것은 코드 골프이므로 가장 적은 바이트 수가 이깁니다!

테스트 사례에서 알 수 있듯이 "멍청한"동작을 처리해야합니다. 탄약이 없을 때 사격을 시도하거나 2 턴을 연속으로 재 장전 (단일 탄약 만 축적)하는 것은 유효합니다.


마지막 라운드에서 무언가가 누락되었거나 출력을 확인할 수 있습니까?
xnor

@ 질문을 업데이트했습니다. 그리고 플레이어가 탄약을 가지고 있는지 아닌지를 알아야하기 때문에 아닙니다. 나는 당신이 마지막 턴이라는 사실에 근거하여 어떤 선수가 탄약을 가지고 있다고 가정 할 수 있음을 알고 있습니다. 나는 실제로 누군가가 죽었을 때 입력이 끝날 것이라고 가정했을 때 허용되는 규칙을 상당히 변경했습니다. 지금 후회하고 있습니다.
Carcigenicate


3
이것은 Load, Defend 및 Shoot 게임 점수매우 유사합니다 . 유일한 차이점은 다른 챌린지는 한 번 이상의 총을 가진 총을 가지고 있으며 빈 총을 쏘는 것은 부정 행위로 간주되어 게임을 몰수한다는 것입니다.
Dennis

예를 들어 라운드 대신 두 플레이어에 대해 두 개의 개별 입력을 취할 수 있습니까 {"rff","rgf"}?
betseg

답변:


2

레티 나 , 36 바이트

s`(?<=r..([^f]..)*)f
!
A`g
G1`!
\w
_

입력 형식은 줄 바꿈으로 구분 된 쌍이어야합니다. 예 :

rr
fr

결과는 플레이어 2가 이기고 무승부가있는 경우 !_플레이어 1이이기는 것 입니다._!!!

온라인으로 사용해보십시오! 편의상 공간 분리를 사용하는 테스트 스위트.

나는이 도전을 완전히 간과해야했다. 나는 그렇지 않으면 Retina에서 이것을 시도했을 것이라고 확신합니다. :)

설명

s`(?<=r..([^f]..)*)f
!

우리는 첫째을 돌려 "유효"샷을 표시하여 시작 f각 후 r로를 !. 우리는 다른 플레이어를 건너지 않고 같은 플레이어 f에서를 찾을 수있는 각각 을 일치시켜이 작업을 수행합니다 . 항상 한 번에 3 자씩 이동하면 같은 플레이어 에서 s로 검색을 제한하는 것이 쉽습니다.rfr

A`g

이제 우리는 누군가가 스스로를 지키는 모든 턴을 버립니다. 엔딩 턴은 그 중 하나 일 수 없기 때문입니다.

G1`!

이제 우리는 계속 에만 이 들어있는 첫 번째 턴 !. 유효한 샷이 발생하면 (그리고 우리는 아무도 지키지 않았다는 것을 알고 있습니다) 게임이 끝납니다.

\w
_

마지막으로 문자열을 통합하여 일관된 출력을 제공해야하며, !문자 가 아닌 ( r또는 f)를로 바꾸면 됩니다 _.


5

파이썬, 139 바이트

c=d=0
for i in input():
 b=(c&(i=='fr'))-(d&(i=='rf'));p,q=i
 if b|(i=='ff')&c&d:print b;break
 c,d=(p=='r',i!='fg')[c],(q=='r',i!='gf')[d]

stdin에서 2 문자 문자열 목록 형식으로 입력을받습니다 (예 : [ 'rf', 'rr', 'rg', 'ff']). 플레이어 1이 이기면 1을, 플레이어 2가 이기면 -1을, 무승부를 위해 0을 출력합니다.

설명 : 먼저 누군가가 총알을 발사했는지 확인합니다. 그런 다음 플레이어가 총을 재 장전하거나 탄약을 낭비했는지 확인합니다.

이것은 내 첫 번째 codegolf 게시물입니다 :)


4

자바 스크립트 (ES6) 108 107 93 91 89 85 바이트

Titus의 도움으로 4 바이트 절약

각 플레이어의 움직임을 설명하는 2 문자열 배열로 입력을받습니다.

b=>b.map(c=>w=w||b&'312'[b=(s='0210231')[m='ffrfgrrggf'.search(c)]|s[m-2]&b,m],w=0)|w

보고:

  • 1 플레이어 1이 이기면
  • 2 플레이어 2가 이기면
  • 3 무승부

작동 원리

b총알이로드 된 사람을 설명 하는 비트 마스크 를 유지합니다 .

  • 비트 # 0 : 플레이어 1에 총알이 있습니다
  • 비트 # 1 : 플레이어 2에 총알이 있습니다

우리는 De Bruijn 시퀀스 'ffrfgrrggf' 를 사용하여 9 가지 가능한 움직임 조합을 모두 식별합니다. b이동 조합에 따라 업데이트하기 위해 OR 및 AND 비트 마스크를 사용 합니다. b우승자를 결정하기 위해 AND와 함께 사용되는 세 번째 비트 마스크 세트를 사용합니다 w. (단 세 우승 조합되고 ff, frrf).

OR 및 AND 마스크는 두 위치만큼 이동 된 동일한 패턴으로 저장 될 수 있습니다.

 Index in | Combination | Bullet   | Bullet  | Winner
 sequence |             | AND mask | OR mask | mask
----------+-------------+----------+---------+--------
    0     |     ff      |    0     |    0    |   3
    1     |     fr      |    0     |    2    |   1
    2     |     rf      |    0     |    1    |   2
    3     |     fg      |    2     |    0    |   0
    4     |     gr      |    1     |    2    |   0
    5     |     rr      |    0     |    3    |   0
    6     |     rg      |    2     |    1    |   0
    7     |     gg      |    3     |    0    |   0
    8     |     gf      |    1     |    0    |   0

테스트 사례


@Carcigenicate이 두 가지 경우 모두 해결해야합니다. 그러나, 나는 지금 반환있어 0(아무도 샷 없었다) 또는 3무승부의 경우 (플레이어는 서로 죽이기). 이것이 허용되는지 확실하지 않습니다. 그렇지 않으면 w%3대신 돌아올 수 있습니다 .
Arnauld

시나리오 당 1 개의 출력을 원했습니다. 나는 누군가가 항상 총에 맞을 것이라고 보장하므로 그 경우를 설명 할 필요는 없습니다. 추첨으로 이끄는 유일한 사례는 서로를 쏘고 탄약이있을 때입니다.
Carcigenicate

&마스크는 0이 될 수 있습니다 fr,rf,ff. '312'['0210231'[m='ffrfgrrggf'.search(c)]|'233331'[m-3]&b]또는 '123'['2100231'[m='frffgrrggf'.search(c)]|'233331'[m-3]&b]1 바이트를 저장하십시오. 그러나 그들은 작동합니까?
Titus

@Titus 흥미롭게도 AND 마스크 앞에 OR 마스크를 적용하면 기존의 모든 테스트 사례에서 작동합니다. 그러나 그것은 다음과 같은 것에 실패합니다["rr","fg","fr","rf"]
Arnauld

&보다 우선 순위가 높 |으므로 순서를 변경해도 바이트를 저장하는 것 외에는 아무것도 변경해서는 안됩니다. 그러나 내 코드에서 과제가 누락되었습니다. 시도하십시오 ...'123'[b='2100231'....
Titus

2

펄 6 , 71 62 바이트

{&[<=>](|map {m/r[..[r|g]]*.$^f/.to//∞},/[r|f]f/,/.f[r|f]/)}

정규식 기반 솔루션.

형식의 입력을 문자열로 "rg fr"받습니다.
세 가지 가능한 출력은 열거 된 값이다 More(플레이어 (1) 원), Less(선수 2 원), Same인쇄 할 때 그 단어로 설정하거나으로 - (무승부) 1, -1, 0번호 강제 때.

온라인으로 사용해보십시오!

작동 원리

  • map { m/r[..[r|g]]*.$^f/.to // ∞ }, /[r|f]f/, /.f[r|f]/

    입력에 대해 두 개의 정규식 일치를 수행합니다. 보간 후 두 정규식은 다음과 같습니다.

    • r[..[r|g]]*.[r|f]f – 2 번 선수가 성공한 첫 번째 경기와 일치합니다.
    • r[..[r|g]]*..f[r|f] – 1 번 선수가 성공한 첫 번째 경기와 일치합니다.

    각 경우에 일치 종료 위치 ( .to) 또는 일치하지 않는 경우 무한대를 반환합니다.

  • &[<=>](|   )

    <=>연산자를 두 경기 종료 위치에 적용합니다 . 첫 번째 인수가 두 번째 인수보다 크거나 작거나 같은지 여부에 따라 Order열거 형 ( More, Less또는 Same) 에서 값을 반환합니다 .


산뜻한. 호기심에서 무한대 기호를 어떻게 입력합니까? 특수 키보드 또는 alt +를 입력 some number합니까? 그리고 당신은 실제로 일반적인 Perl 코드와 같은 문자를 사용합니까, 아니면 골프를위한 것입니까?
Carcigenicate

@Carcigenicate : 맞춤형 키보드 구성표를 사용하면 4 개의 키를 눌렀을 때이를 입력 할 수 있습니다 [Menu] i n f( 작성 순서 라고 함 ). 예를 들면 - 그러나, 모든 펄 (6) 기호는 ASCII 버전이 Inf동의어이다 - 그렇지 그래서 필요한 펄 6 코드에서 유니 코드 문자를 사용할 수 있습니다. 난 그냥 좋아 ... :)
smls

아 그것이 Perl에 대해 내게 던진 한 가지는 무한대 기호였습니다. 나는 그것이 불필요하게 복잡해 보이는 요구 사항이라고 생각했습니다. Clojure가 지루할 때 Perl을 시도 할 것입니다. 최근에 많은 Perl 코드를 보았습니다.
Carcigenicate

@Carcigenicate : Perl 6은 기본적으로 Perl과 호환되지 않는 새로운 언어이며, 인터프리터는 여전히 느립니다 (일부 기능의 경우 버그가 있음). 현재 버전 v5.24 인 Perl은 계속 별도로 유지됩니다.
smls

알았어 고마워. 알아 둘만 한.
Carcigenicate

2

하스켈 , 101 91 87 바이트

n!(c:r)|'g'>c=n:1!r|'g'<c=1:0!r|1<3=2:n!r
_!r=[]
a#b=[x|x@(y,z)<-zip(1!a)$1!b,2>y+z]!!0

온라인으로 사용해보십시오! infix 함수 #는 두 플레이어 각각의 행동을 나타내는 두 개의 문자열을 취하여 (0,1)플레이어 1이 이기면 (1,0)플레이어 2와 (0,0)무승부로 돌아갑니다 .

사용법 예 :

Prelude> "rgrfrf" # "fgrgrr"
(0,1)

설명:

삽입 기능 !은 일련의 행동 'r'(재 장전), 'f'(화재) 및 'g'(가드)를 관찰 가능한 일련의 행동 0(실제 화재), 1(행동 없음) 및 2(가드)로 변환하며, 여기서 화재 행동은 실제 화재 행동 으로 만 계산됩니다. 총알이로드 된 경우 다른 조치없습니다 . 이를 달성하기위한 첫 번째 주장 n0총알이 장착되어 있고 1총이 장착되어 있지 않은 경우입니다. 이 방법으로 각각 'f'을 현재 전류로 간단하게 교체 할 수 있습니다 n. ( n=0-> loaded-> 실제 발사 -> 0, n=1-> unloaded-> 조치 없음 -> 1)

n ! (c:r)                -- n is 0 or 1, c is 'f', 'g' or 'r' and r the rest of the string
    |'g'>c = n : (1 ! r) -- c is smaller 'g', so it must be 'f'. append n to the list
                         --  and set load status to 1 (unloaded)
    |'g'<c = 1 : (0 ! r) -- c is larger 'g', so it must be 'r'. append 1 (no action)
                         --  and set load status to 0 (loaded)
    |1<3   = 2 : (n ! r) -- c must be equal to 'g'. append 2 (guard)
                         --  and leave the load status unchanged
_ ! r = []               -- base case for recursion

9 가지 결과 가능성은

  • (0,0): 두 선수가 쏴 죽고 게임이 끝납니다.
  • (0,1)또는 (1,0): 한 플레이어가 다른 플레이어를 쏴서 게임이 끝납니다.
  • (0,2)또는 (2,0): 한 선수는 쏘고 다른 경비는 쏴 버립니다.
  • (1,1), (1,2), (2,1)(2,2): 아니 플레이어 촬영, 게임은 계속됩니다.

게임 종료 옵션의 합은 2보다 작고 각 게임 연속 가능성의 합은 2보다 크거나 같습니다. 게임의 결과는 합이 2보다 작은 첫 번째 튜플입니다.

a#b=[x|         -- build the list of all x
    x@(y,z) <-  -- where x is an alias for the tuple (y,z) which is drawn from the list
    zip (1!a)   -- of tuples where the first component is from 1!a = eg. [1,2,1,0,1,0] 
        (1!b)   -- and the second from 1!b = eg. [1,2,1,2,1,1]
    , 2 > y+z]  -- and y+z are smaller 2.
    !!0         -- return the first element of this list

1

배치, 249 바이트

@echo off
set g=goto gg
set/ax=y=0
:gg
shift&goto %1
:fg
set x=0
%g%
:gf
set y=0
%g%
:rr
set/ax=y=1
%g%
:fr
if %x%==1 exit/b1
:gr
set y=1
%g%
:rf
if %y%==1 exit/b2
:rg
set x=1
%g%
:ff
set/az=3-x-x-y
if %z%==3 %g%
exit/b%z%

입력은 각 턴마다 문자 쌍의 형태이며 오류 레벨 (0 = 무승부, 1 = 플레이어 1, 2 = 플레이어 2)로 출력됩니다. x그리고 y모두 불, 결과가 때, 플레이어가 탄약이 있는지 여부를 추적 3-x-x-y하는 3되지 않는 경우에 우리는 계속,. 라인 5에서 나는 배치의 파서를 남용합니다- %1현재 shift구문은 명령문이 실행되고 제거 되기 전에 대체 되므로 올바른 레이블로 이동합니다.


1

클로저, 168 바이트

#(reduce(fn[[l L r R][a A]](if(and l L)(let[M(fn[r a A](if(and(= a \f)r)[nil(= A \g)][(or(= a \r)r)1]))[r L](M r a A)[R l](M R A a)][l L r R])[l L r R]))[1 1 nil nil]%)

덜 골프 (두 사람이 모두 살아 있다면 M탄약과 적의 생활 상태를 업데이트하는 데 사용 합니다. 그렇지 않으면 현재 상태를 반환합니다) :

(def f (fn[A] (reduce
                (fn [[l1 l2 r1 r2] [a1 a2]]
                  (if (and l1 l2)
                    (let[M (fn [r1 a1 a2]
                             (if (and(= a1 \f)r1)
                               [false (= a2 \g)]        ; we lost the ammo, a2 lives if he was guarding
                               [(or(= a1 \r)r1) true])) ; we might gain or keep ammo, a2 lives no matter what
                         [r1 l2] (M r1 a1 a2)
                         [r2 l1] (M r2 a2 a1)]
                      [l1 l2 r1 r2])
                    [l1 l2 r1 r2]))
                [true true false false] A)))

사용법 예 (첫 번째 요소는 플레이어 1이 게임 종료시 살아 있는지, 두 번째 요소는 플레이어 2가 살아 있는지, 3, 4 번째는 승자를 결정할 때 관련이없는 탄약 상태를 알려줍니다) :

(-> (for[[a b s] (partition 3 "rr fg rf fr ")][a b]) f (subvec 0 2))

업데이트 : 글쎄, 이것의 loop길이는 동일합니다! 내가 찾을 reduce당신이 사용하는 경우는 중간 상태를 쉽게 검사 할 수 있습니다로 개발하기 쉽게 버전 reductions.

#(loop[l 1 L 1 r nil R nil[[a A]& I]%](if(and l L)(let[M(fn[r a A](if(and(= a \f)r)[nil(= A \g)][(or(= a \r)r)1]))[r L](M r a A)[R l](M R A a)](recur l L r R I))[l L]))

기다리고있었습니다! 밀도가 높다.
Carcigenicate

Hehe 덕분에 여전히 반복해야한다는 점 [l1 l2 r1 r2](그 수정 된 값 let과 원래 값)과 그 fn서명을 짜증나게합니다.
NikoNyrh

적어도 후자에게는 이것이 내가 선호하는 이유 loop입니다. 더 깔끔한 코드로 연결됩니다. 하나 이상의 누산기로 접어야하는 즉시 전환합니다.
Carcigenicate 2019

1

PHP, 107 (101) 90 바이트

로딩 상태에 비트 마스크 $ d를 사용하고 발사 동작에 DeBruijn 시퀀스를 사용합니다.

for(;!$x=$d&strpos(_frff,$m=$argv[++$i]);)$d=$d&g<$m|h<$m|2*($d/2&f<$m[1]|g<$m[1]);echo$x;

입력을 2 문자 명령 행 인수로 사용하고로 실행하십시오 -nr.

1 = 플레이어 1 승리
2 = 플레이어 2 승리
3 = 무승부

고장

for(;!$x=$d&strpos(_frff,       // 1. $x=someone dies, loop while not
    $m=$argv[++$i]          // loop throug moves
);)
    $d=
        $d&g<$m|h<$m            // 2. unload/reload Player 1 = bit 0
    |2*(
        $d/2&f<$m[1]|g<$m[1]    // 3. unload/reload Player 2 = bit 1
    );
echo$x;
  • DeBruijn 시퀀스 : fr: position = 1 = P1 발사; rf= 위치 2 = P2 화재, ff= 위치 3 = 두 화재
  • g<$m<=> f<$m[0]( f<$m두 번째 문자가 있기 때문에 항상 참).

0

파이썬, 200 바이트

def war_game(turns):
    turn=0
    player1=True
    player2=True
    ammo1=False
    ammo2=False
    while turn<len(turns):
        if turns[turn][0]=='f' and ammo1==True and turns[turn][1]!='g':
            player2=False
        elif turns[turn][0]=='f' and turns[turn][1]=='g':
            ammo1=False
        elif turns[turn][0]=='r':
            ammo1=True
        if turns[turn][1]=='f' and ammo1==True and turns[turn][0]!='g':
            player1=False
        elif turns[turn][1]=='f' and turns[turn][0]=='g':
            ammo2=False            
        elif turns[turn][1]=='r':
            ammo2=True
        if player2==False or player1==False:
            break
        turn+=1
    if player1==True and player2==False:
        print('Player 1 wins')
        return 1
    elif player1==False and player2==True:
        print('Player 2 wins')
        return 2
    print('Draw')
    return 0

2
사이트에 오신 것을 환영합니다. 컨테스트는 바이트 수로 점수가 매겨 지므로 타이틀에 바이트 수를 포함시키고 변수 이름의 길이를 줄임으로써 최소화하는 것이 좋습니다. 이것을 작성한 언어도 포함시켜야합니다 (Python3처럼 보입니다).
Post Rock Garf Hunter

2
위에서 언급했듯이, 이것은 가장 작은 프로그램이 과제를 달성 할 수있게하는 경쟁입니다. turnsjust 대신 전체 이름을 사용 t하고 있습니다. 즉, 프로그램이 필요한 것보다 훨씬 큽니다. 또한 #Python 2, 200 bytes사용하는 언어가 명확하도록 (이것이 2이고 프로그램 길이가 200 바이트라고 가정) 과 같은 제출을 시작하십시오 .
Carcigenicate

0

클로저, 180 173 바이트

(fn[t](loop[z nil x nil[[c v]& r]t](let[k #(and %3(= %\f)(not= %2\g))h #(and(not= %\f)(or %2(= %\r)))q(k v c x)w(k c v z)](cond(and q w)0 q 2 w 1 1(recur(h c z)(h v x)r)))))

매크로를 사용하는 대신 함수를 전체 함수로 변경하여 -7 바이트 내부 함수 매크로를 만들어 조금 절약 할 수 있습니다.

이것은 매우 문자 그대로의 솔루션입니다. 방금 정식 버전의 게임을 작성했기 때문에 마음이 잠겨 있습니다. 이것은 기본적으로 내가 사용한 알고리즘의 버전이 크게 줄어 듭니다. 내가 할 수있는 많은 최적화가있을 수 있지만, 나는 그것에 매우 만족합니다. 설명은 사전 골프 코드를 참조하십시오.

(defn outcome [turns] ; Take input as ["rr" "ff"]
  (loop [p1-ammo? false ; Keep track of if each player has ammo
         p2-ammo? false
         [[p1-move p2-move] & rest-turns] turns] ; Deconstruct the turns out

    (let [killed? (fn [m m2 a] (and a (= m \f) (not= m2 \g))) ; Function that checks if one player killed the other
          has-ammo? (fn [m a] (and (not= m \f) (or a (= m \r)))) ; Function that decides if a player has ammo in the
                                                                 ;  next turn
          p1-killed? (killed? p2-move p1-move p2-ammo?) ; Check if each player was killed.
          p2-killed? (killed? p1-move p2-move p1-ammo?)]

      (cond ; Check who (if any) died. If no one died, recur to next turn.
        (and p1-killed? p2-killed?) 0
        p1-killed? 2
        p2-killed? 1
        :else (recur (has-ammo? p1-move p1-ammo?)
                     (has-ammo? p2-move p2-ammo?)
                     rest-turns)))))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.