Büyü: Yeteneklerle Buluşma Mücadelesi


16

İlişkili

Hedef:

İsteğe bağlı savaş yeteneklerine sahip iki canlı verildiğinde, varsa hangi canlıların öldüğünü temsil eden benzersiz ancak tutarlı değerler döndürün.

Giriş:

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

Her yaratık şeklinde verilecektir [P,T,"<abilities>"]. O şeklinde olacak [P,T], [P,T,""]ya [P,T,0]da hiçbir yeteneklerini, form üzerinde seçiminizi varsa. P, = = 0 olan bir tam sayı, T = = 1 olan bir tam sayıdır. <abilities>bir alt kümesidir"DFI" grubudur veya isterseniz tek bir sayı / bit dizisi ile temsil edilebilir. Bayrakların sırası da size kalmış.

Savaş Mekaniği:

Her canlının iki statüsü vardır, bu sırayla Güç ve Tokluk ve isteğe bağlı yetenekler. Bir yaratığın gücü> = 0'dır. Bir yaratığın Tokluğu> = 1'dir.

Her yaratık aynı anda muhalif yaratığa olan gücüne eşit hasar verir (ilk vuruş olmadıkça). Değer rakibin sertliğinden büyük veya ona eşitse, ölmez (yok edilemezse).

Örnek: Alice bir 2/2, Bob bir3/4 , her ikisi de yeteneği olmayan. Alice Bob'a 2 hasar verir ve karşılığında 3 hasar alır. Alice'in dayanıklılığı 2, bu yüzden ölecek, Bob'un dayanıklılığı 4 olacak, böylece yaşayacak.

Bunun için dikkate alacağımız sadece 3 isteğe bağlı yetenek var (oyunda daha fazlası olmasına rağmen). Bunlar bir karakter bayrağı olacaktır:

  • [D] dokunma: Herhangi bir miktarda hasar (X> 0) ölümcül kabul edilir.
  • [F] ilk Grev: İlk önce hasarını verir, diğer yaratığı geri saldırabilmeden önce öldürebilir. Her iki canlıda da İlk Saldırı varsa, dövüşü normal şekilde çözün.
  • [I] tahrip edilemez: Deathtouch dahil hiçbir hasar öldürücü değildir.

Çıktı:

Aşağıdaki dört vakanın her biri için tutarlı bir değer. Cevabınızdaki dört değeri lütfen belirtin. Eşler cinsinden örnek dönüş değeri:

  • Hiçbir canlı ölmedi (0)
  • 1. yaratık öldü (1)
  • 2. yaratık öldü (2)
  • Her iki canlı da öldü (3)

Kurallar:

  • Girdinin doğru biçimlendirilmiş iki canlıya sahip olması garanti edilir.
  • Yetenekler için karakter kullanıyorsanız, bunların nasıl sipariş edildiğini varsayabilir, ancak uygunsa kullanılan siparişi gönderebilirsiniz.
  • Yetenekler için bir sayı / bit dizisi kullanıyorsanız, kullandığınız kodlamayı gönderin. ör .: 111is D/F/I, 7is D/F/I, vb.
  • Bir canlının yeteneği yoksa, aynı zamanda [P,T, ""] veya sayı eşdeğeri da
  • Standart Loopholes Yasak
  • Bu çok kısa kod kazanır.

Örnekler:

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 Evet. Biraz daha kural var ama MtG'de "Cants" koz "Cans". Yani işlevsel olarak, Yıkılmaz Deathstrike'ı görmezden geliyor. Daha açık olması için düzenlendi
Veskah

1
@ fəˈnɛtɪk, hala hasar alıyor, ondan ölmüyor. Dikkat edin, soru da kuralı yanlışlar. " [Yıkılmaz] kalıcılar ölümcül hasarla yok edilmemeli ve ölümcül hasarları kontrol eden devlet temelli eylemi görmezden gelmelidirler ".
Peter Taylor

4
" Bir canlının yeteneği yoksa, [P, T] olarak ayrıştırılmalıdır. [P, T," "] geçerli değil " kötü bir kural. Hiçbir faydası olmadan güçlü yazarak dillere karşı ayrımcılık yapar.
Peter Taylor

2
@PeterTaylor Pürüzlü dizileri tutmak istiyorum ama daha iyisini yapamayacağınız konusunda haklısınız. Böylece kural kaldırıldı
Veskah

1
@Veskah "D", "F", "I" sayıları alabilir miyim? D => 0, F => 1, I => 2
Luis felipe De jesus Munoz

Yanıtlar:


6

Perl 5,248 bayt

... boşluk ve satırsonu olmadan:

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 }

Çevrimiçi deneyin!

@Veskah (OP) 'dan gelen on test ile ungolfed versiyonum testlerden geçiyor:

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 bayt

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)

Ben yetenekleri için bitmap sayıları kullanıyorum D = 4 F = 2 I = 1 "DFI"olurdu 7. Benim çıkış Ne Ölüm edilir 01 öldü, 12 Ölüm, 2, İkisi öldü3 .

Şununla yapılan testler:

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)

Bu benim ilk çalışma kodumdu

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

Hangi ben bu ara azalttı:

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'ye Hoşgeldiniz! Ve çok güzel ilk çözüm :) Daha fazla golf için bazı potansiyel görebilirsiniz ama telefonum, birkaç bira sonra düzgün test edemez sonra.
Shaggy


@Shaggy. Güzel! Tabii ki virgül operatörü - ne bir çaylakım.
James

1
Hepimiz bir zamanlar
Shaggy

3

JavaScript (ES6), 83 76 bayt

Girdiyi 6 ayrı argüman olarak alır: 2 x (Güç, Tokluk, Yetenekler). Yeteneklerin bitmask olarak beklenmesi:

  • 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

Çevrimiçi deneyin!

Yorumlananlar

(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 bayt

Ceilingcat ve Logern sayesinde çok golf.

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

İle derleyin -DZ=P,T,F,p,t,f).

Çevrimiçi deneyin!

Yaratıkların her birinin savaşta hayatta kalıp kalmayacağını (bağımsız olarak, savaş mekaniğinin simetrisi nedeniyle) kontrol ediyoruz (bu, her ikisi de doğruysa gerçekleşir):

  • yaratık yok edilemez;
  • yaratığın ilk vuruşu vardır ve diğeri yoktur VE gücü başkasının sertliklerine eşit veya daha büyüktür (bu nedenle başkalarının ölüm dokunuşunu göz ardı edebiliriz);
  • diğer yaratıkların ölüm dokunuşu yoktur ve gücü tokluğumuzdan daha azdır.

(Eski koşullar daha önemlidir).

Girdiler tamsayı olarak güç ve dayanıklılık, ve bir bit alanı olarak yeteneklerdir (1 = Yıkılmaz, 2 = Ölüm dokunuşu, 4 = İlk vuruş), çıktı da bir bit alanıdır (1 = İlk yaratık hayatta kalır, 2 = İkinci yaratık hayatta kalır).


1
-DZ=P,T,F,p,t,f) 96 baytlık
Logern

Kullanma P=…yerine return …ve yeni satır kaldırarak 85 bayt götürür.

Ayrıca -3 mantıksal operatörler değiştirerek bayt &&, ||Bitwise ile &,|

2

Retina 0.8.2 , 123 bayt

\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

Çevrimiçi deneyin! Ben ikame ettik rağmen Link test durumları kapsar 9için 99999hız için. Giriş, harflerden önce gelmesine DFIrağmen kullanır . Çıktı, sağ kalanlar ve kalıplar için formattadır . Açıklama:DI10

\d+
$*

İstatistikleri tekli'ye dönüştürün.

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

İstatistikleri geçici olarak değiştirin.

F(.*)F
$1

İki Fs iptal.

1+D
1

Death Touch rakibin Tokluğunu 1'e düşürür.

1*(,1+)I
$1

Yıkılmaz rakibin Gücünü 0'a düşürür.

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

Tokluğu geri çevirin, böylece artık P2, T1, F1; P1, T2, F2

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

Tokluk rakibin Gücünden daha yüksekse hayatta kalır.

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

Her ikisi de ölürse, First Strike olan hayatta kalır.

F

Aksi takdirde First Strike fark etmez.


1

C ++, 177 131 127 121 bayt

İşte benim C ++ benim kısa değil çözüm. Yetenekler her canlı için 3 bittir:

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

Ve sadece 0 döndürür : kimse ölmezse, 1 : ilk yaratıklar ölürse, 2 : ikinci yaratık ölürse ve 3 : her iki yaratık ölürse.

[](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;}

Çevrimiçi deneyin!

C ++, 85 81 bayt (Alternatif)

Değişkenleri lambda ile hafifçe hile yaparak ve yakalayarak ve argüman olarak geçirmeyerek 81 bayta kadar inmek mümkündür. Bunun kabul edilebilir bir çözüm olup olmadığını bilmiyorum, bu yüzden alternatif olarak gönderiyorum.

[&]{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;}

Çevrimiçi deneyin!


Bu kod golf , bu tür hackler, gerekirse, rekabet etmek için bekleniyor ... amacı biraz kod golf dilini kullanmazsanız, oyunu biraz değiştirir.
3D1T0R

1

Perl 5, 245 bayt

$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))

Şununla koş: -lapE

Ungolfed:

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

"Ölüm dokunuşu", "gücünüz artık düşmanınızın sertliğiyle çarpılır" anlamına gelir ve "yıkılmaz", "düşmanınızın gücü artık sıfırdır" anlamına gelir; ikincisi emsalidir. Kod, yalnızca ilk grevciler tarafından saldırıya uğradığı ve diğeri sadece ilk grevciler tarafından saldırabileceği iki tur yürütür. İlk tur ölümle sonuçlanırsa, ikinci tur gerçekleşmez. Zaten ölüm dokunuşuyla uğraştığımız ve başlangıçta yıkılamadığımız için, "ölüm", dayanıklılığın sıfırdan büyük olup olmadığını kontrol etmek kadar basittir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.