Mölkky oynayalım!


33

Mölkky

Mölkky bir Fin fırlatma oyunudur. Oyuncular, 1 ile 12 arasında sayılarla işaretlenen, fırlatma pimi ile neredeyse aynı boyuttaki tahta pimlerini vurmaya çalışmak için bir tahta pimi ("mölkky" olarak da adlandırılır) kullanırlar.

   (07)(09)(08)
 (05)(11)(12)(06)
   (03)(10)(04)
     (01)(02)

Bu açıklama ve aşağıdaki kurallar Wikipedia'ya dayanmaktadır .

Basitleştirilmiş Mölkky kuralları

  1. Bir iğneyi vurmak, iğnede işaretli noktaların sayısını alır.

  2. 2 veya daha fazla pin vurmak, devirilen pinlerin sayısını belirtir (örneğin, 3 pinten 3 puan kazanmak).

  3. Oyunun amacı tam olarak 50 puana ulaşmak . Skoru 25 puana geri ayarlayarak 50'den fazla puanlama cezalandırılır .

  4. Bu zorluğun amacı için, pimlerin her zaman yukarıda açıklanan sırayla olduğu varsayımını yapacağız . (Gerçek bir oyunda, iğneler indikleri yerde her atıştan sonra tekrar ayağa kalkar.)

Diğer tüm Mölkky kuralları dikkate alınmaz ve sadece bir oyuncu kabul edilir.

Giriş

Boş olmayan 12 booleans listesinin listesi. Boole Her liste bir atış sonucunu açıklar: 1 pimi devirmiş ve eğer 0 aksi. Boolean'ler pimlerin tam olarak sırasıyla soldan aşağı sağa doğru verilmiştir: 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2 .

Çıktı

Girişte açıklanan tüm atışlardan sonraki puan, kural 1 , 2 ve 3 uygulanarak hesaplanır .

Detaylı örnek

Aşağıdaki girişi düşünelim:

// 07 09 08 05 11 12 06 03 10 04 01 02
[ [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],  // scores 5 (rule #1)
  [ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],  // scores 2 (rule #2), total: 7
  [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 ],  // scores 7, total: 14
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],  // scores 12, total: 26
  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],  // scores 12, total: 38
  [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],  // scores 11, total: 49
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],  // scores 7, total: 56 -> 25 (rule #3)
  [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ] // scores 2, total: 27

Beklenen çıktı 27 .

Meydan okuma kuralları

  • Herhangi bir makul formatta girdi alabilirsiniz. Boolean listeleri yerine, en önemli bitin pim # 7 ve en az anlamlı bitin pim # 2 olduğu tam sayıları kullanabilirsiniz. Bu formatta, yukarıdaki örnek olarak iletilecektir [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ].
  • Giriş listesi, hiçbir pimin çarpılmadığı yerlerde atmalar içerebilir; bu durumda puan değişmez.
  • Skor tam 50 puana ulaştığında yapacak özel bir şeyin yok . Ancak, gerçekleştiğinde başka bir atış izlemeyeceğini varsayabilirsiniz.
  • Bu , yani bayt cinsinden en kısa cevap kazanır.

Test durumları

Tamsayı listelerini giriş olarak kullanma:

[ 0 ] --> 0
[ 528 ] --> 2
[ 4095 ] --> 12
[ 64, 0, 3208 ] --> 16
[ 16, 1907, 2048 ] --> 18
[ 2023, 2010, 1, 8 ] --> 29
[ 1726, 128, 35, 3136, 1024 ] --> 34
[ 32, 32, 2924, 2, 256, 16 ] --> 28
[ 64, 64, 2434, 1904, 3251, 32, 256 ] --> 25
[ 3659, 2777, 2211, 3957, 64, 2208, 492, 2815 ] --> 25
[ 2047, 1402, 2, 2599, 4, 1024, 2048, 3266 ] --> 50
[ 256, 2304, 127, 64, 64, 128, 2048, 3072 ] --> 27
[ 16, 8, 128, 1, 2048, 1, 2048, 513, 8, 3206 ] --> 30

Bu test durumlarını Boolean biçiminde almak için bu bağlantıyı takip edebilirsiniz .


5
Harika bir meydan okuma ve aynı zamanda denememiş olanlar için yaz aylarında oynamak için harika bir oyun - bir ızgara ile birlikte harika çalışıyor.
Nit

2
@Nit teşekkür ederim. :) Bu oyunu bugüne kadar bilmediğimi itiraf etmeliyim. Bu öğleden sonra parkta yürürken insanların oyun oynarken gördüm. Şimdi, denemek istiyorum.
Arnauld

Yanıtlar:


7

Python 2 , 126 111 108 104 bayt

Jonathan Allan sayesinde -3 bayt

Kaya sayesinde -4 bayt!

f=lambda A,t=0:t>50and f(A,25)or A and f(A[1:],t-~(sum(A[0])-1or 762447093078/12**A[0].index(1)%12))or t

Çevrimiçi deneyin!

2 ve 1s'lik bir 2D dizisi alan ve bir tamsayı değeri döndüren özyinelemeli bir işlev tanımlar. İnşaatta çok özel bir şey yok ve daha basit bir çözüm olduğuna eminim.

Açıklama:

f=lambda A,t=0:    #Define the function, initialising t to 0 on the first iteration
               t>50and f(A,25)      #If t>50 then iterate again with t=25
                              or    #Else
               A and                #If A exists
                     f(A[1:],       #Iterate again without the first list of A
                        t-~         #And add to t, either
                           (sum(A[0])-1   #The sum of all elements if that's not 1
                                         or
                           762447093078/12**A[0].index(1)%12   #Else the appropriate pin value (black magic!)
               or t       #Finally, if A is finished, just return t

(0x103925BA4786>>4*A[0].index(1))%16karşı 1 karakter kaydederord('GIHEKLFCJDAB'[A[0].index(1)])-65
Kaya

1
Biraz daha uygun:762447093078/12**A[0].index(1)%12
Kaya

Bu şey bana kara büyü gibi geldi! @Kaya!
Jo King

1
Bu sadece üs 12 ile kodlama
enedil

6

Jöle , 25 bayt

“ñ€bḷ’œ?TLḢṖ?µ€+25¹>?50ɗ/

Bir tamsayı döndüren birlerin ve sıfırların (her birinin uzunluğu 12) bir listesini kabul eden bir monadik bağlantı.

Çevrimiçi deneyin! Veya test paketine bakın (OP'de verilen tamsayı değerlerini kullanarak)

Nasıl?

Bu çözüm, œ?bir sayı verilen, n'yi kullanır ve bir liste , listenin sıralama düzenini tanımladığı listenin ninci sözlük izinini bulur . İlk önce bunu çözmemiz gerekiyor n:

 index:  1  2  3  4  5  6  7  8  9 10 11 12
 value:  7  9  8  5 11 12  6  3 10  4  1  2   (as defined by the question)
     P: 11 12  8 10  4  7  1  3  2  9  5  6   (our permutation lookup array)

... olduğunu Pendeks de ideğerin orijinal endeksine ayarlanır i.
Bu Pbir lexicographical indeksine sahiptir 438,337,469 (tüm aldı olduğunu, 12! Sayıların permütasyon 1 ile 12 ve sözlük sırasında sıraladım 438,337,469 inci olurdu P).
Bu Jelly'in Œ¿atomu kullanılarak bulunabilir . Jelly programı kullanılarak
bir kerede her iki adımda gerçekleştirilebilirĠŒ¿

“ñ€bḷ’œ?TLḢṖ?µ€+25¹>?50ɗ/ - Link: list of lists of zeros and ones
             µ€           - perform the monadic chain to the left for €ach list:
“ñ€bḷ’                    -   base 250 number = 438337469
      œ?                  -   nth permutation (reorder the 1s and 0s to their pin values)
        T                 -   truthy indices (get the pin values of the 1s)
            ?             -   if...
           Ṗ              -   ...condition: pop (length greater than 1 ?)
         L                -   ...then: length (the number of pins)
          Ḣ               -   ...else: head (the first (& only) pin value)
                        / - reduce the resulting list of integers with:
                       ɗ  -   last three links as a dyad:
               +          -     addition (add the two values together)
                     50   -     literal fifty
                    ?     -     if...
                   >      -     ...condition: greater than (sum greater than 50 ?)
                25        -     ...then: literal twenty-five
                  ¹       -     ...else: identity (do nothing - just yield the sum)

Bence tüm permütasyonlar arasında uygun sözlükbilim endeksini bulma hakkındaki açıklama, Jelly ucu olarak eklenmeye değer . (Bunu son yapmam gerektiğinde, kısa sekanslar için o kadar uzun olmayan , ama biraz sıkıcı olan manuel bir ikilik taraması yaptım . ^^)
Arnauld

LOL; Ben tam olarak iki farklı bayt hariç, aynı çözüm: -> , µ-> Ʋ. Jöle gerçekten bir giriş parametresiz bağlantı acceppting yararlanacak ¡'ın <link>çok, programın başlangıç özel Kılıf davranışı tutmak eğer, olması dışında (ilk argüman).
Outgolfer Erik,

... ve neredeyse ikisini de kullandım!
Jonathan Allan,


4

Pyth, 51 48 38 bayt

VQI>=+Z?qJsN1@.PC"îO&"S12xN1J50=Z25;Z

Jonathan Allan sayesinde 10 bayt kurtarıldı. Boolean listeleri listesine girdi.
Burada dene

açıklama

VQI>=+Z?qJsN1@.PC"îO&"S12xN1J50=Z25;Z
VQ                                  ;     For each input...
    =+Z                                   ... add to the total...
       ?q sN1                             ... if one pin is down...
             @.PC"îO&"S12xN1              ... the score of that pin.
         J                    J           ... otherwise, the count.
  I>                           50         If we pass 50...
                                 =Z25     ... reset to 25.
                                     Z    Output the total.

Programa tam olarak nasıl gireceğinden emin değilim, ancak eğer yapabiliyorsanız 6 veya 7 bayt kurtarmalı ... 7tT8h4hT12h5h2T4h02-> .PC"îO&"S12- Jelly cevabım gibi sözlükbilimsel permütasyon indekslemesi kullanıyor. (Kod dizenin başlangıcında yazdırılamayan 0x0F bayt değerine sahip.)
Jonathan Allan

))olabilir;
Jonathan Allan

4

05AB1E , 29 28 bayt

v•CÞŸαLć•13вyOΘmyÏOO25‚¬50›è

Çevrimiçi deneyin!

açıklama

v                              # for each boolean list in input
 •CÞŸαLć•                      # push 13875514324986
         13в                   # convert to a list of base-13 numbers
            yO                 # push the sum of y
              Θm               # truthify and raise the pin-list to this number (0 or 1)
                yÏ             # keep those which are true in the current list
                  OO           # sum the list and the stack
                    25‚        # pair with 25
                       ¬50›    # check if the first number is larger than 50
                           è   # index into the pair with this result

4

Perl 5 , 74 70 bayt

$\+=y/1//-1||/1/g&&(0,6,8,7,4,10,11,5,2,9,3,0,1)[pos];$\=25if++$\>50}{

Çevrimiçi deneyin!

Girdiyi yeni satır ayrılmış bitstrings dizisi olarak alır.


3

Haskell , 96 bayt

foldl(\s a->([s..50]++e)!!sum(last$zipWith(*)[7,9,8,5,11,12,6,3,10,4,1,2]a:[a|sum a>1]))0
e=25:e

Çevrimiçi deneyin!

Kaydırma zekice: Ben esas s+sum(…)olarak listeye pozisyonunu indeksliyorum ([0..50]++cycle[25]). Ancak, bu pozisyonda indeksleme sum(…)ve listenin başında başlayan yazmak için daha kısa bir yol s.


3

Java 10, 131 130 129 bayt

m->{int r=0,i,s,t;for(var a:m){for(i=s=t=0;i<12;s+=a[i++])t=a[i]>0?"    \n".charAt(i):t;r+=s<2?t:s;r=r>50?25:r;}return r;}

10 yazdırılamaz içeriyor.
Sıfır ve tamsayı matrisi olarak giriş.

@JonathanFrech sayesinde -1 bayt , \tgerçek bir sekmeye dönüşüyor (TIO'da çalışıyor, benim yerel IDE'de çalışmıyor).

Çevrimiçi deneyin.

Açıklama:

m->{                // Method with integer-matrix parameter and integer return-type
  int r=0,          //  Result-integer, starting at 0
      i,s,t;        //  Temp integers
  for(var a:m){     //  Loop over the integer-arrays of the input
    for(i=s=t=0;    //   Reset `i`, `s` and `t` to 0
        i<12;       //   Loop `i` in the range [0,12)
        s+=a[i++])  //    Increase `s` by the current value (0 or 1)
      t=a[i]>0?     //    If the current value is 1:
         "  \n".charAt(i)
                    //     Set `t` to the score at this position
        :t;         //    Else: Leave `t` the same
    r+=s<2?         //   If only a single pin was hit:
        t           //    Add its score `t` to the result
       :            //   Else:
        s;          //    Add the amount of pins `s` to the result
    r=r>50?         //   If the result is now above 50
       25           //    Penalize it back to 25
      :r;}          //   If not, it stays the same
  return r;}        //  Return the result

İçinde gerçek bir sekme karakteri kullanarak bir bayt kaydedebileceğinizi düşünüyorum "\t\n".
Jonathan Frech

@ JonathanFrech Hmm, gerçekten de TIO'da çalışıyor gibi görünüyor.
IDE'mde

Bir yerde çalışan bir uygulama olduğunda buna izin verilir. : @
Jonathan Frech

2

Kömür , 43 bayt

≔⁰ηFθ«≧⁺⎇⊖ΣιΣι⌕᧔$|#z⁸Ug⊗”⌕ι¹η¿›η⁵⁰≔²⁵η»Iη

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Girdiyi bir boolean dizisi olarak alır. Açıklama:

≔⁰η

Skoru 0 olarak ayarlayın.

Fθ«

Atar üzerinde döngü.

⎇⊖Σι

Pin sayısı 1 mi?

Σι

Değilse, o zaman pin sayısını alın.

⌕᧔$|#z⁸Ug⊗”⌕ι¹

Aksi takdirde, pimin konumunu bir değere çevirin.

≧⁺...η

Puanına ekleyin.

¿›η⁵⁰≔²⁵η

Eğer skor 50'yi geçerse, tekrar 25'e ayarlayın.

»Iη

Tüm atışlardan sonra nihai sonucu yazdırın.


2

Haskell , 110 bayt

m s|sum s==1=sum$zipWith(*)[7,9,8,5,11,12,6,3,10,4,1,2]s|1>0=sum s
f l=foldl(\b->c.(b+).m)0l
c a|a>50=25|1>0=a

Aynı uzunluk: f l=foldl(\b a->last$b+m a:[25|b+m a>50])0lyerine fvec

Çevrimiçi deneyin!


L argümanını f ile 3 bayt arasında bırakın. f=foldl(\b->c.(b+).m)0
aoemica

2

Kabuğu , 47 35 bayt

H.PWiz sayesinde -12 bayt (liste kodlama noktalarını oluşturmanın daha iyi bir yolu)!

F₅0
S?25>50+?←Lε`f`+Nm+3d4652893071

Çevrimiçi deneyin!

açıklama

F₅0  -- input is a list of boolean lists
F    -- left fold by
 ₅   -- | the function flipped (overflowing label) on line 1
  0  -- | with initial value 0

S?25>50+?←Lε`f`+Nm+3d4652893071  -- example inputs: [0,0,0,1,0,0,0,0,0,0,0,0] 0
                     4652893071  -- integer literal: 4652893071
                    d            -- digits: [4,6,5,2,8,9,3,0,7,1]
                 m+3             -- map (+3): [7,9,8,5,11,12,6,3,10,4]
              `+N                -- append natural numbers: [7,9,8,5,11,12,6,3,10,4,1,2,3,...
            `f                   -- filter this list by argument: [5]
        ?  ε                     -- if it's of length 1
         ←                       -- | take first
          L                      -- | else the length
                                 -- : 5
       +                         -- add to argument: 5
 ?  >50                          -- if the value is > 50
  25                             -- | then 25
S                                -- | else the value
                                 -- : 5

Ne dersiniz m+3d4652893071?
H.PWiz

1

Kırmızı , 189 172 bayt

func[b][s: 0 foreach c b[d: 0 foreach e c[if e = 1[d: d + 1]]i: find c 1
n: either i[pick[7 9 8 5 11 12 6 3 10 4 1 2]index? i][0]if 50 < s: s + either 1 < d[d][n][s: 25]]s]

Çevrimiçi deneyin!

Ungolded kodun açıklaması:

f: func[b][                                            ; a block of blocks of booleans
    s: 0                                               ; sets sum to 0
    foreach c b[                                       ; for each row of booleans 
        d: 0 foreach e c[if e = 1[d: d + 1]            ; count the number of 1s         
        i: find c 1                                    ; the index of the first 1
        n: either i[pick [7 9 8 5 11 12 6 3 10 4 1 2]  ; if there is 1, pick the number
                    index? i][0]                       ; at the index of 1
                                                       ; otherwise 0  
        if 50 < s: s + either 1 < d[d][n][s: 25]       ; if there is only one 1, add 
                                                       ; the number to the sum, otherwise
                                                       ; the number of 1s 
                                                       ; if the sum > 50, reset it to 25 
    ]
    s                                                  ; return the sum 
]

1

JavaScript (ES6), 98 bayt

a=>a.map(b=>b.map((m,i)=>(c+=m,d+=m*('0x'+'7985bc63a412'[i])),c=d=0)|(t+=c>1?c:d)>50?t=25:0,t=0)|t

Test durumları:


Referans uygulamamın boyutuyla aynı (ve çok benzer) . :)
Arnauld

Ah guzel. Kod boyutunuzla eşleşebileceğimde mutluyum. Mavi bir ayda sadece bir kere yenebilirim :)
Rick Hitchcock

0

Stax , 37 bayt

├T<↓"♥←~;▌6»≥øF←î5░U╚_π○Q▒<│∟└ù║pε♀▀æ

Koş ve hata ayıkla

Çevrimiçi deneyin!

açıklama

F:1"=EA5MQ9-I1%)"!s@c%1={h+}{%+}?c50>{d25}{}?    # Full program, unpacked

F                                                # Loop through every element
 :1                                              # Get indices of truthy elements
   "=EA5MQ9-I1%)"!                               # Push encoded [7,9,8,5,11,12,6,3,10,4,1,2]
                 s@                              # Swap the top 2 elements of stack and get elements at indexes
                   c%1=                          # Copy the top element, get length of array, compare to length of 1
                       {h+}{%+}?                 # If it has length of 1, add the element, otherwise add the length of the array to total
                                 c50>            # Compare total to 50, 
                                     {d25}{}?    # If it is greater, pop it off and push 25 to reset counter, otherwise do nothing

En iyi işim değil ama işe yarıyor. Biraz kısaltmak için kaçırdığım bir şey olduğuna eminim.


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.