마술 : 능력을 가진 채집 전투


16

관련

골:

선택적인 전투 능력을 가진 두 생물이 있다면, 어떤 생물이 죽었는지 나타내는 고유하지만 일관된 값을 반환합니다.

입력:

#Longest form:
[[P,T, "<abilities>"], [P,T, "<abilities>"]]
#Shortest form:
[[P,T], [P,T]]

각 생물은의 형태로 제공 [P,T,"<abilities>"]됩니다. 그것은 형태가 될 것이다 [P,T], [P,T,""]또는 [P,T,0]이 더 능력, 양식에 선택의 여지가없는 경우. P는 0보다 큰 정수이고, T는 1보다 큰 정수이다. <abilities>은의 하위 집합 "DFI"이거나 원하는 경우 단일 숫자 / 비트 문자열을 통해 표현 될 수 있습니다. 깃발의 순서도 당신에게 달려 있습니다.

전투 역학 :

각 생물에는 두 가지 능력치, 즉 힘과 강인함의 순서와 선택 능력이 있습니다. 생물의 힘은> = 0입니다. 생물의 강인함은> = 1입니다.

각 생물은 동시에 상대의 생물과 동일한 피해를 입 힙니다. 값이 상대방의 강인 이상인 경우 (파괴 할 수없는 경우 제외) 사망합니다.

예 : Alice는 능력 2/2이 있고 Bob은 3/4능력이 없습니다. 앨리스는 밥에게 2의 피해를주고 대가로 3의 피해를받습니다. Alice의 강인함은 2이므로 죽을 것이고 Bob의 강인함은 4이므로 살 것입니다.

우리가 이것에 대해 고려할 옵션 능력은 3 가지뿐입니다 (게임에는 더 많지만). 이것들은 하나의 문자 플래그가 될 것입니다 :

  • [D] eathtouch : 모든 피해량 (X> 0)은 치명적인 것으로 간주됩니다.
  • [F] irst Strike : 먼저 피해를 입히고, 다른 생물이 다시 공격하기 전에 죽일 수 있습니다. 두 생물이 모두 첫 타격을 가하면 정상적으로 전투를 해결하십시오.
  • [I] 파괴 불가능 : 죽음의 손길을 포함하여 치명적인 피해는 없습니다.

산출:

다음 네 가지 경우 각각에 대해 일관된 값입니다. 답에 네 가지 가치를 명시하십시오. 괄호 안의 반환 값 예 :

  • 어느 생물도 죽지 않았다 (0)
  • 첫 번째 생물이 죽었다 (1)
  • 두 번째 생물이 죽었다 (2)
  • 두 생물 모두 죽었다 (3)

규칙 :

  • 입력에는 올바르게 형식이 지정된 두 생물이 있어야합니다.
  • 능력을 위해 캐릭터를 사용하는 경우, 캐릭터가 원하는대로 주문되었다고 가정 할 수 있지만 관련이있는 경우 사용 된 주문을 게시 할 수 있습니다.
  • 기능에 숫자 / 비트 스트링을 사용하는 경우 사용중인 인코딩을 게시하십시오. 예 : 111is D/F/I, 7is D/F/I
  • 생물에게 능력이 없다면, [P,T, ""]또는 동등한 숫자 로도 사용할 수 있습니다
  • 표준 허점 금지
  • 이것은 이므로 가장 짧은 코드가 승리합니다.

예 :

Input: [[2,2], [1,1]]
Output: 2nd Dies

Input: [[0,2], [0,1]] #0/2 vs 0/1
Output: Neither Die

Input: [[2,1], [2,1]] #2/1 vs 2/1
Output: Both Die

Input: [[1,1, "D"], [2,2]] #1/1 Deathtoucher vs 2/2 
Output: Both Die

Input: [[2,2], [0,1, "D"]] #2/2 vs 0/1 Deathtoucher
Output: 2nd Dies

Input: [[2,2], [1,1, "DF"]] #2/2 vs 1/1 Deathtouch First-striker 
Output: 1st Dies

Input: [[0,2, "D"], [0,1, "DF"]] #0/2 Deathtoucher vs 0/1 Deathtouch First-striker
Output: Neither Die

Input: [[2,2], [2,2, "F"]] #2/2 vs 2/2 First-striker
Output: 1st Dies

Input: [[2,2, "I"], [1,1, "DF"]] #2/2 Indestructible vs 1/1 Deathtouch First-striker
Output: 2nd Dies

Input: [[9999,9999], [1,1, "I"]] #9999/9999 vs 1/1 Indestructible
Output: Neither Die

Input: [[2,2, "F"], [1,1, "F"]] #2/2 First-Striker vs 1/1 First-Striker
Output: 2nd Dies

#9/9 Deathtouch, Indestructible First-Striker vs 9/9 Deathtouch, Indestructible First-Striker
Input: [[9,9, "DFI"], [9,9, "DFI"]] 
Output: Neither Die

1
네. MtG에는 "Can'ts"가 "Cans"보다 우선합니다. 따라서 기능적으로 파괴 불가능은 데스 스트라이크를 무시합니다. 보다 명확하게 편집
Veskah

1
@ fəˈnɛtɪk, 그것은 여전히 ​​피해를 입습니다. 단지 죽지 않습니다. 이 질문에 규칙이 잘못 명시되어 있습니다. " [파괴 불가] 지속 물은 치명적인 피해로 파괴되지 않으며 치명적인 피해를 확인하는 국가 기반 행동을 무시합니다 ".
피터 테일러

4
" 생물이 능력이 없다면, [P, T]로 해석해야합니다. [P, T," "]는 유효하지 않습니다 "는 잘못된 규칙입니다. 강력한 타이핑 기능이있는 언어를 차별하지 않습니다.
피터 테일러

2
@PeterTaylor 들쭉날쭉 한 배열을 유지하고 싶지만 더 나아지지 않는 것이 맞습니다. 따라서 규칙이 제거되었습니다
Veskah

1
@Veskah "D", "F", "I"를 숫자로 사용할 수 있습니까? D => 0, F => 1, I => 2
Luis felipe De jesus Munoz

답변:


6

펄 5 , 248 바이트

... 공백과 개행없이 :

sub c{eval'
(P,T,A,p,t,a)=@_;
     A=~/F/&&a!~/F/&&a!~/I/ ? c( P,2e9,A=~s/F//r,p,t, a         )
    :a=~/F/&&A!~/F/&&A!~/I/ ? c( P,T, A,        p,2e9,a=~s/F//r )
    : do{
        P=1e9 ifA=~/D/&&P>0;
        p=1e9 ifa=~/D/&&p>0;
        T=3e9 ifA=~/I/;
        t=3e9 ifa=~/I/;
        T-=p;
        t-=P;
        T>0&&t>0  ? 0
            : T>0 ? 2
            : t>0 ? 1
            :       3
}'=~s,[pta],\$$&,gri }

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

@Veskah (OP)의 10 가지 테스트로 내 ungolfed 버전은 테스트를 통과합니다.

sub co { #combat
    my($p1,$t1,$a1, $p2,$t2,$a2)=@_; #p=power, t=toughness, a=abilities
    $a1=~s/F// and $a2=~s/F// if "$a1$a2"=~/F.*F/; #both F, no F
    return co($p1,2e9,$a1=~s/F//r, $p2,$t2,$a2        ) if $a1=~/F/ && $a2!~/I/;
    return co($p1,$t1,$a1,         $p2,2e9,$a2=~s/F//r) if $a2=~/F/ && $a1!~/I/;
    $p1=1e9 if $a1=~/D/ and $p1>0;
    $p2=1e9 if $a2=~/D/ and $p2>0;
    $t1=3e9 if $a1=~/I/;
    $t2=3e9 if $a2=~/I/;
    $t1-=$p2;
    $t2-=$p1;
    $t1<=0 && $t2<=0 ? "Both Die"
   :$t1<=0           ? "1st Dies"
   :$t2<=0           ? "2nd Dies"
                     : "Neither Die"
}

my @test=map{[/Input: .*? (\d+),(\d+)(?:,\s*"([FDI]+)")?
                      .*? (\d+),(\d+)(?:,\s*"([FDI]+)")?
           .*? Output: \s* (1st.Dies|2nd.Dies|Both.Die|Neither.Die)? /xsi]}
         split/\n\n/,join"",<DATA>;
my $t=0;
for(@test){ $t++;
  my $r=co(@$_);#result
  $r=~s,0,Neither Die,; $r=~s,3,Both Die,;
  print $$_[-1]=~/^$r/
    ? "Ok $t\n"
    : "Not ok, combat $t --> $r, wrong! (".join(",",@$_).")\n"
}
__DATA__
Input: [[2,2], [1,1]]
Output: 2nd Dies

Input: [[0,2], [0,1]] #0/2 vs 0/1
Output: Neither Die

Input: [[2,1], [2,1]] #2/1 vs 2/1
Output: Both Die

Input: [[1,1, "D"], [2,2]] #1/1 Deathtoucher vs 2/2
Output: Both Die

Input: [[2,2], [0,1, "D"]] #2/2 vs 0/1 Deathtoucher
Output: 2nd Dies

Input: [[2,2], [1,1, "DF"]] #2/2 vs 1/1 First-strike, Deathtoucher
Output: 1st Dies

Input: [[2,2], [2,2, "F"]] #2/2 vs 2/2 First-striker
Output: 1st Dies

Input: [[2,2, "I"], [1,1, "DF"]] #2/2 Indestructible vs 1/1 First-strike, Deatht.
Output: 2nd Dies

Input: [[99999,99999], [1,1, "I"]] #99999/99999 vs 1/1 Indestructible
Output: Neither Die

Input: [[2,2, "F"], [1,1, "F"]] #2/2 First-Striker vs 1/1 First-Striker
Output: 2nd Dies

4

자바 스크립트 (137) 125 120 111 바이트

i=>(k=(a,b)=>!(b[2]%2)&&a[0]/(a[2]<=3)>=b[1],[c,d]=i,g=c[2]&2,h=k(c,d),j=k(d,c),d[2]&2-g&&(g?h&&2:j&&1)||j+2*h)

능력에 대해 비트 맵 번호를 사용하고 "DFI"있습니다 7. D = 4 F = 2 I = 1 할 것입니다 . 내 결과는 사망 0, 1 사망 1, 2 사망 2, 둘 다 사망 하지 않았습니다 3.

테스트 :

f([[2, 2, 0], [1,1, 0]]); // 2
f([[0, 2, 0], [0,1, 0]]); // 0
f([[2, 1, 0], [2,1, 0]]); // 3
f([[1, 1, 4], [2,2, 0]]); // 3
f([[2, 2, 0], [0,1, 4]]); // 2
f([[2, 2, 0], [1,1, 6]]); // 1
f([[2, 2, 0], [2,2, 2]]); // 1
f([[2, 2, 1], [1,1, 6]]); // 2
f([[99999, 99999, 0], [1,1, 1]]); // 0
f([[2, 2, 2], [1,1, 2]]); // 2)

이것은 내 첫 번째 작업 코드였습니다

const kills = (c1, c2) => { // Return true if c1 kills c2
    if (c2[2] % 2) {
        console.log("Indestructible");
        return false;
    }
    const c1p = c1[0] / (c1[2] <= 3); // Infinity if Deathtoucher && P > 0
    const c2t = c2[1];
    return c1p >= c2t;
}
const f = (input) => {
    console.log("Match:", input);
    const [c1, c2] = input;
    const f1 = (c1[2] & 2);
    const f2 = (c2[2] & 2);
    if (f2 !== f1) {
        if (f1) {
            if (kills(c1, c2)) {
                console.log("c1 killed c2 in first round");
                return 2;
            }
        } else {
            if (kills(c2, c1)) {
                console.log("c2 killed c1 in first round");
                return 1;
            }
        }
    }
    return kills(c2, c1) + 2 * kills(c1, c2);
};

이 중간체로 줄였습니다.

const f = i => {
    const k = (a, b) => !(b[2] % 2) && a[0] / (a[2] <= 3) >= b[1];
    const [c, d] = i;
    const g = c[2] & 2;
    const h = k(c, d);
    const j = k(d, c);
    return d[2] & 2 - g &&
        (g  ? h && 2
            : j && 1
        ) || j + 2 * h
}

PPCG에 오신 것을 환영합니다! 그리고 아주 좋은 첫 번째 해결책 :) 나는 더 많은 골프를 칠 가능성 이 있지만 맥주를 마신 후에 몇 가지 맥주를 마신 후에 제대로 테스트 할 수 없습니다.
Shaggy

: 여기에 빠른 7 바이트 저장하지만,의 tio.run/##bc/RbsIgFAbg@z0FuxgBd7RwNEu2SPcgjERKtak1ZVHjle/...
얽히고 설킨

@얽히고 설킨. 좋은 것! 물론 쉼표 연산자-내가 멍청한 놈입니다.
제임스

1
우리는 한 번 모두 새로운
21:06에 Shaggy

3

자바 스크립트 (ES6), 83 76 바이트

입력을 6 개의 별개의 인수로 취합니다 : 2 x (힘, 강인함, 능력). 능력은 다음과 같은 비트 마스크로 예상됩니다.

  • 1
  • 2
  • 4

0123

(p,t,a,P,T,A)=>(x=A<4&&p>=T|a&!!p)&(y=a<4&&P>=t|A&!!P)&&(a^A)&2?a+2>>1:x*2+y

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

댓글

(p, t, a, P, T, A) => // (p, t, a) = arguments for the first player (P1)
                      // (P, T, A) = arguments for the second player (P2)
  ( x =               // x is a flag which means 'P1 can kill P2',
                      // regardless of the 'First Strike' abilities
    A < 4 &&          // it is set to 1 if P2 is not Indestructible and:
    p >= T |          //   the power of P1 is greater than or equal to the toughness of P2
    a & !!p           //   or the power of P1 is not zero and P1 has the Death Touch
  ) &                 //
  ( y = a < 4 &&      // y is the counterpart of x and is computed the same way
    P >= t |          //
    A & !!P           //
  ) &&                // if both x and y are set
  (a ^ A) & 2 ?       // and exactly one player has the First Strike:
    a + 2 >> 1        //   return 2 if P1 has the First Strike, or 1 otherwise
  :                   // else:
    x * 2 + y         //   return the default outcome: x * 2 + y

3

C (GCC) , 114 (113) 95 바이트

ceilingcat와 Logern 덕분에 많은 골프.

g(Z{return F&1|F&4&&!(f&4||P<t)||!(f&2)&T>p;}
f(Z{return g(Z+2*g(p,t,f,P,T,F);}

로 컴파일하십시오 -DZ=P,T,F,p,t,f).

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

우리는 (전쟁 역학의 대칭으로 인해) 각각의 생물이 전투에서 살아남는지 여부를 확인합니다.

  • 생물은 파괴 할 수 없다.
  • 피조물은 먼저 타격을 입었고 다른 피조물은 공격하지 않으며 그 힘은 다른 사람의 강 인력보다 크거나 같습니다 (따라서 우리는 다른 사람의 죽음 접촉을 무시할 수 있습니다).
  • 다른 생물에게는 죽음의 손길이 없으며 그 힘은 우리의 강인함보다 적습니다.

(이전 조건이 더 중요합니다).

입력은 정수로서의 힘과 강인함, 비트 필드 (1 = 불멸, 2 = 데스 터치, 4 = 첫 번째 타격)와 같은 능력이며, 출력 또한 비트 필드입니다 (1 = 첫 번째 생물은 생존하고 2 = 두 번째 생물은 생존).


1

줄 바꿈 P=…대신 사용 return …하고 제거하면 85 바이트가됩니다.

또한, 논리 연산자 -3 대체하여 바이트 &&, ||비트 단위와 &,|

2

레티 나 0.8.2 , 123 바이트

\d+
$*
(.*1)(.*;)(.*1)
$3$2$1
F(.*)F
$1
1+D
1
1*(,1+)I
$1
(1+)(F?;1*,)(1+)
$3$2$1
(1*)1*,\1(1+)?
$#2
0(F)?;0(F)?
$#1;$#2
F

온라인으로 사용해보십시오! Link는 테스트 케이스를 포함하지만 속도를 대체 9했습니다 99999. 앞에 입력 해야 DFI하지만 입력은 문자를 사용 D합니다 I. 결과는 1생존과 주사위를 0위한 형식 입니다 . 설명:

\d+
$*

통계를 단항으로 변환합니다.

(.*1)(.*;)(.*1)
$3$2$1

통계를 일시적으로 교환하십시오.

F(.*)F
$1

두 개의 F취소합니다.

1+D
1

데스 터치는 상대의 강인함을 1로 낮 춥니 다.

1*(,1+)I
$1

파괴 불가능은 상대의 힘을 0으로 낮 춥니 다.

(1+)(;1*,)(1+)
$3$2$1

강인성을 다시 전환하면 P2, T1, F1; P1, T2, F2가됩니다.

(1*)1*,\1(1+)?
$#2

강인함이 상대방의 힘보다 높으면 살아남습니다.

0(F)?;0(F)?
$#1;$#2

둘 다 죽으면 First Strike를 가진 사람은 살아남습니다.

F

그렇지 않으면 퍼스트 스트라이크는 아무런 차이가 없습니다.


1

C ++, 177 131 127 121 바이트

여기에 C ++의 짧은 해결책이 있습니다. 능력은 각 생물에 대해 3 비트입니다.

  1. D = 0x1 (0001)
  2. F = 0x2 (0010)
  3. I = 0x4 (0100)

그리고 단순히 반환 0 : 아무도 다이, 경우 1 : 제 생물 다이, 경우 2 : 제 생물 다이 및 경우 3 : 두 생물 죽으면.

[](int p,int t,int a,int r,int k,int b){return(a&2&&b^4)^(b&2&&a^4)?1+(a&2):((t<r||b&1&&r)&&a^4)+((k<p||a&1&&p)&&b^4)*2;}

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

C ++, 85 81 바이트 (대체)

람다로 변수를 약간 부정하고 캡처하여 인수로 전달하지 않으면 81 바이트로 줄일 수 있습니다. 그것이 수용 가능한 솔루션인지 알 수 없으므로 대안으로 게시합니다.

[&]{s=(a&2&&b^4)^(b&2&&a^4)?1+(a&2):((t<r||b&1&&r)&&a^4)+((k<p||a&1&&p)&&b^4)*2;}

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


이것은 코드 골프입니다 . 필요하지 않은 경우 경쟁을 위해 그러한 해킹이 예상됩니다 ... 목적으로 만들어진 코드 골프 언어를 사용하지 않으면 게임이 약간 변경됩니다.
3D1T0R

1

펄 5, 245 바이트

$F[0]*=$F[4]if$F[2]=~/D/;$F[3]*=$F[1]if$F[5]=~/D/;$F[3]=0 if$F[2]=~/I/;$F[0]=0 if$F[5]=~/I/;$F[4]-=$F[0]if$F[2]=~/F/;$F[1]-=$F[3]if$F[5]=~/F/;if($F[1]>0&&$F[4]>0){$F[4]-=$F[0]if$F[2]!~/F/;$F[1]-=$F[3]if$F[5]!~/F/}$_=(0+($F[1]<=0)).(0+($F[4]<=0))

로 실행 -lapE

언 골프 드 :

# Takes input in one lines, of the form:
# PPP TTT "<abilities>" PPP TTT "<abilities>"

$F[0] *= $F[4] if $F[2] =~ /D/;
$F[3] *= $F[1] if $F[5] =~ /D/;

$F[3] = 0 if $F[2] =~ /I/;
$F[0] = 0 if $F[5] =~ /I/;

$F[4] -= $F[0] if $F[2] =~ /F/;
$F[1] -= $F[3] if $F[5] =~ /F/;

if ($F[1] > 0 && $F[4] > 0) {
    $F[4] -= $F[0] if $F[2] !~ /F/;
    $F[1] -= $F[3] if $F[5] !~ /F/;
}

$_ = (0+ ($F[1] <= 0)) . (0+ ($F[4] <= 0));

"Deathtouch"는 "당신의 힘은 이제 당신의 적의 인성을 곱한 것"으로, "파괴 할 수없는"은 "당신의 적의 힘은 이제 0"으로, 후자는 우선합니다. 이 코드는 첫 번째 공격자 만 공격하고 첫 번째 공격자가 아닌 공격자 만 공격 할 수있는 두 가지 라운드를 실행합니다. 첫 번째 라운드가 사망하면 두 번째 라운드는 발생하지 않습니다. 우리는 이미 죽음의 손길을 다루었 고 처음에는 파괴 할 수 없었기 때문에 "죽음"은 인성이 제로보다 큰지 아닌지를 확인하는 것만 큼 간단합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.