전쟁 게임의 결과 찾기


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, fr및 rf).

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(가드)로 변환하며, 여기서 화재 행동은 실제 화재 행동 으로 만 계산됩니다. 총알이로드 된 경우 다른 조치 는 없습니다 . 이를 달성하기위한 첫 번째 주장 n은 0총알이 장착되어 있고 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.