魔术:具有能力的聚会战斗


16

有关

目标:

给定两个具有可选战斗能力的生物,返回唯一但一致的值,该值表示哪些生物死亡(如果有)。

输入:

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

每个生物将以的形式给出[P,T,"<abilities>"]。它将采用,或的形式[P,T],如果没有能力,则由您选择。P是> = 0的整数,T是> = 1的整数。是的子集,或者可以根据需要通过单个数字/位串表示。标志的顺序也由您决定。[P,T,""][P,T,0]<abilities>"DFI"

战斗力学:

每个生物都有两个属性,分别是力量和防御力,以及可选能力。生物的力量> = 0。生物的韧性> = 1。

每个生物都会同时对对方生物造成等同于其力量的伤害(除非有第一击)。如果该值大于或等于对手的韧性,则它将死亡(除非它是坚不可摧的)。

示例:Alice是a 2/2,Bob是a 3/4,两者都没有能力。爱丽丝会对鲍勃造成2点伤害,并以3点伤害作为回报。爱丽丝的韧性是2,所以它会死,鲍勃的韧性是4,所以它会活下去。

我们将为此考虑3种可选功能(尽管游戏中还有更多功能)。这些将是一个字符标志:

  • [D]触摸:任何程度的伤害(X> 0)被认为是致命的。
  • [F] irst Strike:将首先造成其伤害,能够杀死另一只生物,然后再发起攻击。如果两个生物都具有“先攻”,则照常结算战斗。
  • 不可破坏:没有任何致命的伤害,包括死亡之触。

输出:

以下四种情况的任何一致值。请说明您的答案中的四个值。示例返回值(以括号为单位):

  • 两人均未死亡(0)
  • 第一个生物死亡(1)
  • 第二生物死亡(2)
  • 两个生物都死了(3)

规则:

  • 确保输入具有两个正确格式的生物。
  • 如果您使用角色的异能,则可以假定已按照想要的顺序对它们进行了排序,但如果相关,则发布使用的顺序。
  • 如果您使用数字/位串表示能力,请张贴您正在使用的编码。例如:111is D/F/I7is 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
@ user71546是的。涉及更多规则,但在MtG中,“不能”胜过“可以”。从功能上讲,坚不可摧忽略死亡打击。编辑,以便更明确
-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
路易斯·费利佩·德·耶稣·穆诺兹

Answers:


6

Perl 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)的十项测试,测试通过:

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

JavaScript中,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)

我将位图编号用于能力D = 4 F = 2 I = 1 "DFI"将会是7。我的输出是没有死0,第一死1,第二死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!很好的第一个解决方案:)我可以看到一些进一步打高尔夫球的潜力,但是在喝了几杯啤酒之后我一直在打电话,所以无法正常测试。
蓬松的

不过,这里可以节省7个字节,这是快速的:tio.run/##bc/RbsIgFAbg@z0FuxgBd7RwNEu2SPcgjERKtak1ZVHjle/…
毛茸茸的

@毛茸茸。好一个!当然,逗号运算符-我是个菜鸟。
詹姆斯

1
我们都是新来的人:)
Shaggy

3

JavaScript(ES6),83 76字节

将输入作为6个不同的参数:2 x(力量,韧性,能力)。可以将能力作为位掩码使用:

  • 1个
  • 2
  • 4

01个23

(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
使用宏-DZ=P,T,F,p,t,f) 96字节-在线尝试!
Logern

使用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

在线尝试!链接包括测试用例,尽管我已经取代999999速度。输入使用字母,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

如果两个人都死了,那么拥有“第一罢工”的人将幸免。

F

否则,“ First Strike”无济于事。


1

C ++,177 131 127 121字节

这不是我在C ++中这么短的解决方案。每个生物的能力为3位:

  1. D = 0x1(0001)
  2. F = 0x2(0010)
  3. 我= 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字节(可选)

通过稍微作弊并捕获lambda中的变量,而不将其作为参数传递,可以减少到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;}

在线尝试!


这是代码高尔夫,除非有特殊用途,否则为了避免竞争,可以预期会发生此类hack……除非您使用的是专用的代码高尔夫语言,这会改变游戏规则。
3D1T0R'9

1

Perl 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));

“死亡接触”的意思是“您的力量乘以敌人的韧性”,“坚不可摧”则翻译为“您的敌人的力量现在为零”,后者为先例。该代码运行两轮,一轮只有第一个攻击者可以攻击,另一轮只有非第一个攻击者可以攻击。如果第一轮导致死亡,则第二轮不会发生。由于我们从一开始就已经处理了死亡和坚不可摧的问题,因此“死亡”就像检查韧性是否大于零一样简单。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.