Bar Oyunu Zar'ı kim kazandı?


24

Meydan okuma

Bar Zar, Zarlı bir Bar'da oynanan basit bir oyundur (dolayısıyla adı). Beş altı yüzlü zar atar ve en iyi eli yapmaya çalışırsın.

Puanlama, aynı rakamlarla en fazla zarın toplanmasına dayanır. Her bir el geçerli bir el olabilmesi için en az bir tane "As" veya bir tane içermelidir; Aslar "Wilds" olarak hareket eder ve başka herhangi bir rakamla eşleştirilebilir. Bir oyuncunun elinin kuvveti ilk önce hane sayısına ve ardından bu hane sayısına bağlıdır. Örnek olarak, dört 3'lü bir el (sayıları), üç 5'li bir elden daha iyidir, ancak beş 2'li bir elden daha iyidir.
Alındığı Wikipedia makalesinde

Bu, en yüksek sıradaki elin tamamen 6 ve 1'in oluşturduğu ve en düşük sıralamanın 1 olmayan herhangi bir el olduğu anlamına gelir.

Buradaki zorluğun iki eli ele geçirmek ve hangi oyuncunun kazandığını ya da bağlarsa geri dönmek.

Giriş

1 ile 6 arasında değişen 5 sıralı iki sıralı liste. Her liste oyuncunun elini temsil eder. Giriş formatı esnektir.

Çıktı

Oyuncu 1'in mi yoksa oyuncu 2'nin mi kazandığını mı yoksa beraberlik mi olduğunu belirten herhangi üç farklı ancak tutarlı statik değere (aralıklara izin verilmez). Lütfen cevabınızda hangi değerleri ne için kullandığınızı belirtiniz. Örneğin, -1eğer P1 kazanırsa, 0berabere 1kalırsa ve P2 kazanırsa geri dönebilirsiniz .

kurallar

  • Giriş her zaman geçerli olacak
  • Bir kazananı belirlemek için her el sadece mümkün olan en yüksek puanı alır. Bağ kırıcı yok. Örneğin, [1,4,4,3,3]kravat olacak [1,4,4,2,2]yerine kravat-kesici olarak 3 's ve 2' s kullanmanın.
  • Çıktı, her seferinde seçilen 3 değerden biri olmalıdır. Tüm negatif sayıları basitçe eşlemenize P1 Winsizin verilmez ve normalleştirilmelidir.
  • Geçersiz eller, yani 1'leri olmayanlar, geçerli olan tüm elleriyle kaybeder ancak diğer geçersiz ellerle bağlanır. Örneğin, [2,2,2,2,2]bağlar [3,3,3,3,3].
  • [1,1,1,1,1]Sıralama amacıyla geçerli bir 6'lı set olarak sayma eli .
  • Bu çok kısa bayt sayısı kazanır.

Örnekler

#You guys are pretty good at finding edge-cases that break things. Good job!
Input:  [2,1,5,6,6], [6,2,6,6,6]
Output: P1 Wins

Input:  [2,4,5,6,6], [6,2,6,6,6]
Output: Tie

Input:  [1,2,3,4,5], [5,4,3,2,1]
Output: Tie

Input:  [1,5,5,3,2], [5,4,1,6,6]
Output: P2 Wins

Input:  [3,2,2,2,1], [4,1,3,6,6]
Output: P1 Wins

Input:  [1,1,1,1,1], [6,1,1,6,6]
Output: Tie

Input:  [1,3,3,4,4], [1,2,2,5,5]
Output: P2 Wins

Input:  [1,3,3,5,5], [1,3,3,2,2]
Output: P1 Wins

Input:  [1,3,3,3,4], [1,1,3,3,3]
Output: P2 Wins

Input:  [2,2,2,6,1], [5,3,3,1,2]
Output: P1 Wins

Input:  [5,5,5,1,5], [1,1,1,1,1]
Output: P2 Wins

Input:  [1,1,1,1,1], [1,1,5,1,1]
Output: P1 Wins

Yanıtlar:


10

Jöle , 17 14 bayt

ċⱮ6Ḣ©+$®aĖUṀ)M

Çevrimiçi deneyin!

Argüman olarak iki listenin bir listesini alan ve [1]oyuncu 1 kazanır, [2]oyuncu 2 kazanır ve [1, 2]beraberlik için geri döner . TIO bağlantısı bunu ekran görüntüsü için düzenler.

3 byte tasarruf için @JonathanAllan teşekkürler!

açıklama

            )   | For each input list (e.g. of one list 1,1,3,3,4)
ċⱮ6             | - Count each of 1..6 (e.g. 2,0,2,1,0,0)
      $         | - Following as a monad:
   Ḣ            |   - Head (number of 1s)
    ©︎           |   - Copy to register
     +          |   - Add (e.g. 2,4,3,0,0)
       ®a       | - Register logical and with this
         Ė      | - Enumerate (e.g. [1,2],[2,4],[3,3],[4,0],[5,0])
          U     | - Reverse each (e.g. [2,1],[4,2],[3,3],[0,4],[0,5])
            Ṁ   | - Max (e.g. 4,2)
              M | Index/indices of maximal score

1
Sen yerini alabilecek IṠile Mkazanan (lar) listesi ve çıkış.
Jonathan Allan,

@JonathanAllan İyi nokta! Teşekkürler
Nick Kennedy,

1
Kayıt defterini kullanarak 15 bayt .
Jonathan Allan,

1
Listelerin tamsayılarla aynı şekilde sıralanmasından dolayı artık artık gereksiz olabileceğini düşünüyorum .
Jonathan Allan,

1
Bu hoş bir yaklaşım. Aferin.
Jonah

9

R , 115 96 bayt

Giuseppe sayesinde -6 bayt.

Aaron Hayman sayesinde -6 bayt.

JavaScript cevabındaki çıktı formatını takip eden Arnauld sayesinde -2 bayt .

function(i,j)(f(i)-f(j))/0
f=function(x,s=tabulate(x,6),l=s[1]+s[-1]*!!s[1])max(l)*6+order(l)[5]

Çevrimiçi deneyin!

İade InfP1 için, NaNbir kravat, için -InfP2 için.

fHer el için bir puan hesaplayan yardımcı fonksiyonunu kullanır . Puan aşağıdaki gibi tanımlanır: den çok tekrarlanan rakam ve tekrarlanan rakamlar olsun n. Öyleyse, puan 6*n+den az bir as 0varsa ve hiçbir as yoksa. O zaman en yüksek puanı alan oyuncuyu bulmamız gerekiyor.

Ungolfed:

f = function(x) {
  s = tabulate(x, 6)         # number of occurrences of each integer
  l = s[1] + s[-1] * !!s[1]  # add the number of wild aces to all values; set to 0 if s[1] == 0
  max(l) * 6 +               # highest number of repetitions (apart from aces)
    order(l)[5]              # most repeated integer (take largest in case of tie)
}
function(i, j){
  sign(f(i) - f(j))
}

96 baytlık bir çözüm elde etmek order(l)[5]yerine kullanabilirsiniz max.col(t(l),"l"): Çevrimiçi deneyin!
Aaron Hayman

@AaronHayman Çok hoş, teşekkürler!
Robin Ryder

6

JavaScript (ES6),  97  90 bayt

Girişi olarak alır (a)(b). İade +InfinityP1 için, -InfinityP2 veya NaNbir kravat.

a=>b=>((g=(x,m)=>x>6?m*/1/.test(a):g(-~x,a.map(k=>n+=k<2|k==x,n=x/6)|m>n?m:n))()-g(a=b))/0

Çevrimiçi deneyin!

Yorumlananlar

a => b => (                 // a[] = dice of P1; b[] = dice of P2
  ( g = (                   // g is a recursive function taking:
      x,                    //   x = dice value to test; initially, it is either undefined
                            //       or set to a non-numeric value
      m                     //   m = maximum score so far, initially undefined
    ) =>                    //
      x > 6 ?               // if x is greater than 6:
        m * /1/.test(a)     //   return m, or 0 if a[] does not contain any 1 
      :                     // else:
        g(                  //   do a recursive call:
          -~x,              //     increment x (or set it to 1 if it's non-numeric)
          a.map(k =>        //     for each dice value k in a[]:
            n +=            //       add 1 to n if:
              k < 2 |       //         k is equal to 1
              k == x,       //         or k is equal to x
            n = x / 6       //       start with n = x / 6
          ) |               //     end of map()
          m > n ?           //     if m is defined and greater than n:
            m               //       pass m unchanged
          :                 //     else:
            n               //       update m to n
        )                   //   end of recursive call
  )()                       // first call to g, using a[]
  - g(a = b)                // subtract the result of a 2nd call, using b[]
) / 0                       // divide by 0 to force one of the 3 consistent output values

6

05AB1E , 16 15 bayt

JonathanAllan sayesinde -1 bayt

εWΘ*6L¢ć+°ƶà}ZQ

Çevrimiçi deneyin!

P1 kazananlar için [1, 0], bağlar için [1, 1], P2 kazananlar için [0, 1] döndürür.

2 tuple (zar sayısı, zar değeri) üzerinde leksikografik düzen kullanmak yerine, bu puan 10 ** zar sayısı * zar değeri olarak hesaplanır. 1 puanı olmayan eller 5.

ε           }           # map each hand to its computed score
 WΘ                     # minimum == 1 (1 if the hand contains a 1, 0 otherwise)
   *                    # multiply (sets hands without 1 to [0, 0, 0, 0, 0])
    6L                  # range [1..6]
      ¢                 # count occurences of each in the hand
       ć                # head extract (stack is now [2-count, ..., 6-count], 1-count)
        +               # add the 1-count to all the other counts
         °              # 10**x
          ƶ             # multiply each element by its 1-based index
           à            # take the maximum

Z                       # maximum
 Q                      # equality test (vectorizes)

1
Ohhh .. Sevdim ć+(şimdi görüyorum ki bunu düşünmedim inanamıyorum ..)! Bu benim denediğimden çok daha iyi .. Benzer bir fikrim var °. :) Zaten 20 bayttaydım ve hala test davasıyla ilgili bir sorunu çözmek zorunda kaldım. [[1,1,1,1,1],] [6,1,1,6,6]]Bana zaman kazandırdığın için teşekkür ederim, böylece girişimimi çöp kutusuna koyabilirim ..; p
Kevin Cruijssen

1
@KevinCruijssen Evet, ne kadar iyi ć+çalıştığı şaşırtıcı . Benim ilk fikrim ile başladı æʒW}ʒ1KË, ama bu [1,1,1,1,1]konu tarafından öldürülüyor .
Grimmy

1
Evet, yaklaşımım çizgileri boyunca ilerliyordu ε1¢©Āy{γéθ¬sg®+°P}`.S, ama onu da [1,1,1,1,1]mahvetti. Sizin tüm cevap ile güzel bir sinerji yakaladık WΘ*, 6L¢, ć+, ve °ƶ. Özellikle yerleşikler Wćƶburada gerçekten güçlerini gösteriyor.
Kevin Cruijssen

Waslında gerekli değil 6L¢¬Ā*, aynı byte-count WΘ*6L¢.
Grimmy

Hmm, iyi nokta. :) WHaşhaş olmadan düşündüm ve sonra *gücünü gösterdi, ama ¬haşhaşsız ve sonra *temelde aynı. Açılmaması gerçeği, bir bayt tasarrufu yaparak ima ettiğim güçtür. Ama aslında esas olarak ćƶ.
Kevin Cruijssen


4

Perl 6 , 60 49 bayt

&[cmp]o*.map:{.{1}&&max (.{2..6}X+.{1})Z ^5}o&bag

Çevrimiçi deneyin!

İade More, Same, Lessiçin P1 Wins, Tie, P2 Wins.

açıklama

       *.map:  # Map input lists
                                             &bag  # Convert to Bag
             {                             }o  # Pass to block
              .{1}&&  # Return 0 if no 1s
                    max  # Maximum of
                         .{2..6}  # number of 2s,3s,4s,5s,6s
                                X+.{1}  # plus number of 1s
                        (             )Z     # zipped with
                                         ^5  # secondary key 0,1,2,3,4
&[cmp]o  # Compare mapped values

4

T-SQL sorgusu, 148 bayt

Tablo değişkenini giriş olarak kullanmak

p: oyuncu

v: rulo için değer

DECLARE @ table(p int,v int)
INSERT @ values(1,5),(1,5),(1,5),(1,5),(1,5)
INSERT @ values(2,4),(2,3),(2,3),(2,1),(2,4)

SELECT sign(min(u)+max(u))FROM(SELECT(p*2-3)*(s+sum(sign(s)-1/v))*(s/5*5+v+30)u
FROM(SELECT*,sum(1/v)over(partition by p)s FROM @)c GROUP BY v,s,p)x

Çevrimiçi deneyin

Player 1 wins returns -1
Tie returns 0 
Player 2 wins returns 1

2

Jöle , 21 bayt

Nick Kennedy tarafından gönderilmeden önce ezildim :)

’-oÆṃṀ$$Ạ?fÆṃ$L;$o5)M

Bir monadik Link (1 indeksli) kazananların listesini çıkaran bir oyuncu listesini kabul eder.

Yani P1 [1], P2 [2]ve bir kravatdır [1,2].

Çevrimiçi deneyin!


2

PowerShell , 112 126 123 121 bayt

Girişi olarak alır (a)(b). İade -1P1 için, kazanmak 1P2 veya 0bir kravat.

$args|%{$d=$($_-ne1|group|sort c*,n*|%{$m=$_};(7*(($o=($_-eq1).Count)+$m.Count)+$m.Name+6*!$m)[!$o])-$d}
[math]::Sign($d)

Çevrimiçi deneyin!

Test durumu @( @(1,1,5,1,1), @(1,1,1,1,1), 1)eklendi.

unrolled:

$args|%{
    $score=$(                                            # powershell creates a new scope inside expression $(...)
        $_-ne1|group|sort count,name|%{$max=$_}          # $max is an element with the widest group and the maximum digit except 1
        $ones=($_-eq1).Count                             # number of 1s in a player's hand
        $scoreRaw=7*($ones+$max.Count)+$max.Name+6*!$max # where $max.Name is digit of the widest group
        $scoreRaw[!$ones]                                # output $scoreRaw if the array contains 1, otherwise output $null 
    )                                                    # powershell deletes all variables created inside the scope on exit
    $diff=$score-$diff
}
[math]::Sign($diff)                                     # output the score difference

2

Wolfram Dili (Mathematica) , 78 75 74 bayt

Greg Martin tarafından -1 bayt

Order@@(#~FreeQ~1||Last@Sort[Reverse/@Tally@Flatten[#/. 1->Range@6]]&)/@#&

Çevrimiçi deneyin!

Oyuncu 1 kazandığında -1, oyuncu 2 kazandığında 1, beraberlik için 0 çıkışı verir.

                                    Helper function to score a list:
FreeQ[#,1] ||                       If there are 0 1s, score is True
Last@Sort[                          Otherwise, take the largest element of
    Reverse/@Tally@                 the {frequency, number} pairs in the flat list
       Flatten[ #/. 1->Range@6]     where each 1 is replaced by {1,2,3,4,5,6}.
]&                              e.g. {1,3,3,5,5} -> {1,2,3,4,5,6,3,3,5,5} -> {3,5}

Order @@ (...) /@ #&                Apply this function to both lists,
                                    then find the ordering of the result.

Sen değiştirerek bir bayt kaydedebilirsiniz FreeQ[#,1]ile #~FreeQ~1.
Greg Martin,

2

Java 8, 244 240 236 215 199 bayt

a->b->{int c[][]=new int[2][7],m[]=new int[2],p,i=5;for(;i-->0;c[1][b[i]]++)c[0][a[i]]++;for(i=14;i-->4;)m[p=i%2]=Math.max(m[p],c[p][1]>0?i/2+9*(c[p][i/2]+c[p][1]):0);return Long.compare(m[0],m[1]);}

@Someone sayesinde -4 byte . @Neil
sayesinde -21 bayt . @Ceilingcat sayesinde -16 bayt .

İade 1P1 kazanır eğer; -1P2 kazanırsa; 0eğer bir kravatsa.

Çevrimiçi deneyin.

Açıklama:

a->b->{                        // Method with 2 integer-array parameters & integer return
  int c[][]=new int[2][7],     //  Create a count-array for each value of both players,
                               //  initially filled with 0s
      m[]=new int[2],          //  The maximum per player, initially 0
      p,                       //  Temp-value for the player
  i=5;for(;i-->0;              //  Loop `i` in the range (5, 0]:
    c[1]                       //   For player 2:
        [b[i]                  //    Get the value of the `i`'th die,
             ]++)              //    and increase that score-count by 1
    c[0][a[i]]++;              //   Do the same for player 1
  for(i=14;i-->4;)             //  Then loop `i` in the range (14, 4]:
    m[p=i%2]=                  //   Set the score of a player to:
                               //   (even `i` = player 1; odd `i` = player 2)
      Math.max(                //    The max between:
        m[p],                  //     The current value,
                               //     And the value we calculate as follows:
        c[p][1]>0?             //     If this player rolled at least one 1:
          i/2                  //      Use the current value `i` integer-divided by 2
          +9*                  //      With 9 times the following added:
             (c[p][i/2]        //       The amount of dice for value `i//2`
              +c[p][1])        //       Add the amount of dice for value 1
        :                      //     Else (no 1s were rolled):
         0);                   //      Use 0
  return Long.compare(m[0],m[1]);}
                               //  Finally compare the maximum scores of the players,
                               //  resulting in -1 if a<b; 0 if a==b; 1 if a>b

P üzerinden for döngüsü, ...*(c[p][1]>0?1:0)ile değiştirebilirsiniz c[p][1]>0?...:0. Çok uzun bir TIO bağlantısı yayınlayamıyorum ve kısaltmak istemiyorum. Ungolfed versiyonunda bir yerlerde dengesiz parantezler var.
zamirim monicareinstate

@someone Ah, elbette, teşekkürler. Daha c[p][1]>0?sonraları bug-fix olarak ekledim ama görünüşe göre fazla düşünmeden. -4 için teşekkürler. :)
Kevin Cruijssen

Neden *(i<2?6:i)? Sadece i=6ve için çabayı çoğaltırsınız i=1. Bu sadece olabilir *i(ve 2'ye ulaştığınızda döngü durur).
Neil

Ayrıca 9 arasında 5ve çevresinde herhangi bir sihirli sayı olabilir 32, değil mi? Kullanırsanız 8o zaman yerine (int)Math.pow(8,(...)*i)kullanabilirsiniz i<<3*(...).
Neil,

1
Ben bittim a->b->{int c[][]=new int[2][7],m[]=new int[2],s,p,i=5;for(;i-->0;c[1][b[i]]++)c[0][a[i]]++;for(i=7;i-->2;)for(p=2;p-->0;m[p]=s>m[p]?s:m[p])s=c[p][1]>0?i+9*(c[p][i]+(i>1?c[p][1]:0)):0;return Long.compare(m[0],m[1]);} ... test vakalarının tüm geçmesine görünüyor
Neil

1

Jöle , 27 bayt

’o5Rṗ5¤ṢŒr$€UẎṀ1e⁸¤×µ€_/Ṡo/

Çevrimiçi deneyin!

P1 için 1, P2 için -1, kravat için 0

açıklama

’o5Rṗ5¤ṢŒr$€UẎṀ1e⁸¤×µ€_/Ṡo/  Main link
                    µ€       For each list
’                            Decrement each value (so 1s become falsy)
 o                           Vectorized logical or (this replaces previous 1s (now 0s) with the test values)
  5Rṗ5¤                      1..5 cartesian-power 5 (1,1,1,1,1; 1,1,1,1,2; 1,1,1,1,3; ...)
          $€                 For each test list
       ṢŒr                   Sort and run-length encode (gives [digit, #digit])
            U                Reverse each list (gives [#digit, digit])
             Ẏ               Tighten by one (gives a list containing each possible hand for each possible wildcard)
              Ṁ              Take the maximum
               1e⁸¤×         Multiply the list values by (whether or not the original contained a 1) - becomes [0, 0] if not
                      _/Ṡ    Take the sign of the difference between the #digits and the digits
                         o/  If the number of digits differs, then 1/-1 is returned; otherwise, check the value of the digit (could still be 0)

1

Balyoz 0.4 , 27 bayt

⢱⢙⢂⠠⡾⢃⠐⢈⠸⣞⠴⠻⠎⡥⡳⡐⢒⠘⢛⣩⡓⣮⡕⡠⣢⣡⠿

Bu Wolfram Dili işlevine sıkıştırmalar:

Order @@ (FreeQ[#1, 1] || Last[Sort[Reverse[Tally[Flatten[#1 /. 1 -> Range[6]]], 2]]] & ) /@ #1 & 

Mathematica cevabımla tamamen aynı olduğu ortaya çıkıyor .


1

Kömür , 48 45 bayt

UMθ⮌E⁷№ι∨λ¹UMθ׬¬⊟ι⁺⊟ιιUMθ⟦⌈ι±⌕ι⌈ι⟧I⁻⌕θ⌈θ⌕θ⌊θ

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Bir dizi dizisi olarak girdi alır ve -1oyuncu 1 kazanırsa, 0bir beraberlik için ve 1oyuncu 2 kazanırsa çıkar. Açıklama:

UMθ⮌E⁷№ι∨λ¹

Her elinizi 6..1, eldeki değerlerin kaç kez göründüğünü sayın . Liste ters çevrilmiştir, çünkü a) en yüksek sayıyı en yüksek değerle bulmayı kolaylaştırır ve b) 1s sayısını çıkarmayı kolaylaştırır . Sayısı1 buna diğer sayımları eklemek için bir kez sıfırdan farklı olup olmadığını kontrol etmek kere, iki kere kaldırılacak gerektiğinden s katına çıkarıldı.

UMθ׬¬⊟ι⁺⊟ιι

Sayılara 1s sayısını ekleyin 6..2, ancak 1s sayısı sıfır olduğunda tüm sayıları sıfıra ayarlayın.

UMθ⟦⌈ι±⌕ι⌈ι⟧

Her el için bu sayı ile en yüksek sayıyı ve en yüksek değeri bulun. (Aslında bunun değerini 6golf eksi olarak eksi olarak buluruz.)

I⁻⌕θ⌈θ⌕θ⌊θ

Kazanan ve kaybeden ellerin pozisyonlarını çıkararak hangi eli kazanacağınızı belirleyin. (Eğer eller bağlanırsa, ilk el hem kazanır hem de kaybeder, böylece sonuç 0istenildiği gibi olur.)


1

C (gcc) / 32 bit, 117 bayt

t;m;s(int*r){int c[6]={};for(m=0;t=*r++;m=t>m?t:m)c[--t]+=5,t=t?c[t]+t:5;t=*c?*c+m:0;}f(a,b){t=s(a)-s(b);t=(t>0)-!t;}

Çevrimiçi deneyin!

İki sıfır sonlandırılmış tam sayı dizisini alır. İade 1, 0, -1için P1 Wins, P2 Wins, Tie.


1
@ Veskah Tamam, düzeltildi.
nwellnhof

1

J , 47 44 bayt

*@-&([:({.([:>./#\@]+9^*@[*+)}.)1#.i.@6=/<:)

Çevrimiçi deneyin!

Nick Kennedy'nin fikrinden esinlenmiştir.

ungolfed

*@-&([: ({. ([: >./ #\@] + 9 ^ *@[ * +) }.) 1 #. i.@6 =/ <:)

1

Perl 5 -MList::Util=max -pl , 80 bayt

sub t{$t=pop;$_=max map$_ x$t=~s/$_//g,2..6;/./;$t&&$_.$t*($&||6)}$_=t($_)<=>t<>

Çevrimiçi deneyin!

Giriş:

Her oyuncu ayrı bir çizgi üzerinde boşluk bırakmaz

Çıktı:

1 Birinci hat kazanır

0 Kravat

-1 İkinci hat kazanır


1
Oyunun kurallarını netleştirmenize dayanarak değiştirildi
Xcali
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.