Ayo main Mölkky!


32

Mokky

Mölkky adalah permainan melempar Finlandia. Para pemain menggunakan pin kayu (juga disebut "mölkky") untuk mencoba menjatuhkan pin kayu dengan dimensi yang hampir sama dengan pin lempar, ditandai dengan angka dari 1 hingga 12. Posisi awal pin adalah sebagai berikut:

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

Deskripsi dan aturan di bawah ini didasarkan pada Wikipedia .

Aturan Mölkky yang disederhanakan

  1. Mengetuk lebih dari satu pin akan menghitung jumlah poin yang ditandai pada pin tersebut.

  2. Mengetuk 2 atau lebih pin menghasilkan jumlah pin yang terjatuh (misalnya, merobohkan 3 pin mencetak 3 poin).

  3. Tujuan permainan ini adalah untuk mencapai tepat 50 poin. Mencetak lebih dari 50 dihukum dengan mengembalikan skor menjadi 25 poin.

  4. Untuk tujuan tantangan ini, kami akan membuat asumsi bahwa pin selalu dalam urutan yang tepat seperti dijelaskan di atas. (Dalam permainan nyata, pin berdiri lagi setelah setiap lemparan di lokasi di mana mereka mendarat.)

Semua aturan Mölkky lainnya diabaikan dan hanya satu pemain yang dipertimbangkan.

Memasukkan

Daftar daftar kosong 12 boolean. Setiap daftar boolean menggambarkan hasil lemparan: 1 jika pinnya terjatuh dan 0 sebaliknya. Boolean diberikan sesuai urutan pin, dari kiri atas ke kanan bawah: 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2 .

Keluaran

Skor setelah semua lemparan dijelaskan dalam input, dihitung dengan menerapkan aturan 1 , 2 dan 3 .

Contoh terperinci

Mari pertimbangkan masukan berikut:

// 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

Output yang diharapkan adalah 27 .

Aturan tantangan

  • Anda dapat mengambil input dalam format apa pun yang masuk akal. Alih-alih daftar boolean, Anda dapat menggunakan bilangan bulat di mana bit paling signifikan adalah pin # 7 dan bit paling signifikan adalah pin # 2. Dalam format ini, contoh di atas akan dilewatkan sebagai [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ].
  • Daftar input mungkin berisi lemparan di mana tidak ada pin sama sekali terlempar, dalam hal ini skor dibiarkan tidak berubah.
  • Anda tidak memiliki hal khusus untuk dilakukan ketika skor mencapai tepat 50 poin. Tetapi Anda dapat mengasumsikan bahwa tidak ada lemparan lain yang akan mengikuti ketika itu terjadi.
  • Ini adalah , jadi jawaban tersingkat dalam byte menang.

Uji kasus

Menggunakan daftar bilangan bulat sebagai input:

[ 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

Anda dapat mengikuti tautan ini untuk mendapatkan test case ini dalam format Boolean.


5
Tantangan keren, dan juga permainan yang bagus untuk dimainkan di musim panas bagi Anda yang belum mencobanya - bekerja sangat baik bersama dengan pemanggang.
Nit

2
@Nit, terima kasih. :) Saya harus mengakui bahwa saya tidak tahu permainan ini sampai hari ini. Saya melihat orang-orang bermain sambil berjalan di taman sore ini. Sekarang, saya ingin mencobanya.
Arnauld

Jawaban:


7

Python 2 , 126 111 108 104 byte

-3 byte terima kasih kepada Jonathan Allan

-4 byte terima kasih kepada Kaya!

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

Cobalah online!

Menentukan fungsi rekursif yang mengambil array 2D 1s dan 0s dan mengembalikan nilai integer. Tidak ada yang terlalu istimewa dalam konstruksi, dan saya yakin ada solusi yang lebih sederhana.

Penjelasan:

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))%16menghemat 1 karakter versusord('GIHEKLFCJDAB'[A[0].index(1)])-65
Kaya

1
Sedikit lebih optimal:762447093078/12**A[0].index(1)%12
Kaya

Hal itu terlihat seperti ilmu hitam bagiku! Terima kasih @Kaya!
Jo King

1
Itu hanya penyandian dengan basis 12
enedil

6

Jelly , 25 byte

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

Tautan monadik yang menerima daftar daftar satu dan nol (masing-masing dengan panjang 12) yang mengembalikan bilangan bulat.

Cobalah online!Atau lihat test-suite (menggunakan nilai integer yang diberikan dalam OP)

Bagaimana?

Solusi ini merek penggunaan, œ?yang diberi nomor, n, dan daftar menemukan n th leksikografis permutasi dari daftar di mana daftar mendefinisikan urutan. Pertama, kita perlu menyelesaikan inin :

 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)

... yaitu, Ppada indeks idiatur ke indeks nilai aslinya i.
Ini Pmemiliki indeks leksikografis dari 438.337.469 (yaitu, jika Anda mengambil semua 12! Permutasi dari angka 1 ke 12 dan mengurutkannya leksikografis, yang 438.337.469 th akan P).
Ini dapat ditemukan menggunakan Œ¿atom Jelly .
Kedua langkah dapat dilakukan dalam sekali jalan menggunakan program JellyĠŒ¿

“ñ€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)

Saya pikir penjelasan Anda tentang menemukan indeks leksikografis yang sesuai di antara semua permutasi akan layak ditambahkan sebagai tip Jelly . (Terakhir kali saya harus melakukan itu, saya melakukan pencarian dikotomik manual, yang tidak terlalu lama untuk urutan pendek tapi ... agak membosankan. ^^)
Arnauld

LOL; Saya memiliki solusi yang persis sama, kecuali untuk dua byte yang berbeda: -> , µ-> Ʋ. Jelly benar-benar akan mendapat manfaat dari acceppting link niladic sebagai ¡'s <link>(argumen pertama), kecuali bahwa, jika pada awal sangat dari program ini, menjaga perilaku khusus casing.
Erik the Outgolfer

... dan saya hampir menggunakan keduanya!
Jonathan Allan


4

Pyth, 51 48 38 byte

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

Disimpan 10 byte berkat Jonathan Allan Mengambil input sebagai daftar daftar boolean.
Coba di sini

Penjelasan

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.

Tidak yakin bagaimana cara memasukkannya ke dalam program persis, tetapi harus menyimpan 6 atau 7 byte jika Anda bisa ... 7tT8h4hT12h5h2T4h02-> .PC"îO&"S12- menggunakan pengindeksan permutasi leksikografis seperti jawaban Jelly saya. (Kode ini memiliki byte 0x0F yang tidak dapat dicetak pada awal string.)
Jonathan Allan

))bisa;
Jonathan Allan

4

05AB1E , 29 28 byte

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

Cobalah online!

Penjelasan

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 byte

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

Cobalah online!

Mengambil input sebagai serangkaian bitstring yang dipisahkan oleh baris baru.


3

Haskell , 96 byte

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

Cobalah online!

Pembungkusnya pintar: Saya pada dasarnya mengindeks posisi s+sum(…)pada daftar ([0..50]++cycle[25]). Namun, cara yang lebih singkat untuk menulis yaitu pengindeksan pada posisi sum(…)dan memulai daftar di s.


3

Java 10, 131 130 129 byte

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

Berisi 10 paket.
Input sebagai integer-matrix dari nol dan yang.

-1 byte terima kasih kepada @JonathanFrech , yang berubah \tmenjadi tab aktual (berfungsi di TIO, tidak berfungsi di IDE lokal saya).

Cobalah online.

Penjelasan:

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

Saya pikir Anda dapat menyimpan satu byte dengan menggunakan karakter tab yang sebenarnya di "\t\n".
Jonathan Frech

@ JonathanFrech Hmm, memang sepertinya bekerja di TIO. Tidak bekerja secara lokal di IDE saya, tetapi siapa yang peduli tentang itu saya kira ..;)
Kevin Cruijssen

Ketika ada implementasi yang berhasil di suatu tempat, itu diperbolehkan. : @
Jonathan Frech

2

Arang , 43 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil input sebagai array boolean. Penjelasan:

≔⁰η

Atur skor menjadi 0.

Fθ«

Lingkarkan di atas lemparan.

⎇⊖Σι

Apakah jumlah pin 1?

Σι

Jika tidak, maka ambil jumlah pin.

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

Jika tidak, terjemahkan posisi pin ke nilai.

≧⁺...η

Tambahkan ke skor.

¿›η⁵⁰≔²⁵η

Jika skor melebihi 50 maka atur kembali ke 25.

»Iη

Cetak hasil akhir setelah semua lemparan.


2

Haskell , 110 byte

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

Panjang yang sama: f l=foldl(\b a->last$b+m a:[25|b+m a>50])0lbukan fdanc

Cobalah online!


Jatuhkan argumen l dalam f selama 3 byte. f=foldl(\b->c.(b+).m)0
aoemica

2

Sekam , 47 35 byte

-12 byte terima kasih kepada H.PWiz (cara yang lebih baik untuk menghasilkan daftar poin penyandian)!

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

Cobalah online!

Penjelasan

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

Bagaimana dengan m+3d4652893071?
H.PWiz

1

Merah , 189 172 byte

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]

Cobalah online!

Penjelasan kode yang tidak diserami:

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 byte

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

Kasus uji:


Ukuran yang sama dengan (dan sangat mirip dengan) implementasi referensi saya . :)
Arnauld

Ah keren Saya senang setiap kali saya dapat mencocokkan ukuran kode Anda. Hanya sekali di bulan biru aku bisa mengalahkannya :)
Rick Hitchcock

0

Stax , 37 byte

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

Jalankan dan debug itu

Cobalah online!

Penjelasan

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

Bukan pekerjaan terbaik saya, tetapi berhasil. Saya yakin ada beberapa hal yang saya lewatkan untuk membuatnya sedikit lebih pendek.


0

Python 2 , 109 105 103 byte

c=0
for l in input():a=sum(l);c+=int('7985bc63a412'[l.index(1)],16)if a==1else a;c=(25,c)[c<51]
print c

Cobalah online!

Alternatif tanpa fungsi rekursif.

-2 dengan terima kasih kepada @ Jo King


Anda dapat menghapus tanda kurung di sekitar string literal
Jo King
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.