Hãy chơi Mölkky!


33

Mölkky

Mölkky là một trò chơi ném của Phần Lan. Người chơi sử dụng ghim gỗ (còn gọi là "mölkky") để cố gắng vượt qua các chốt gỗ có kích thước gần như tương tự với pin ném, được đánh dấu bằng các số từ 1 đến 12. Vị trí ban đầu của các chân như sau:

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

Mô tả này và các quy tắc dưới đây được dựa trên Wikipedia .

Quy tắc Mölkky đơn giản hóa

  1. Gõ trên một pin sẽ ghi số điểm được đánh dấu trên pin.

  2. 2 chân trở lên sẽ ghi được số chân bị lật (ví dụ: gõ trên 3 chân sẽ ghi được 3 điểm).

  3. Mục tiêu của trò chơi là đạt được chính xác 50 điểm. Ghi hơn 50 điểm bị phạt bằng cách đặt điểm trở lại 25 điểm.

  4. Với mục đích của thử thách này, chúng tôi sẽ đưa ra giả định rằng các chân luôn theo đúng thứ tự được mô tả ở trên. (Trong một trò chơi thực sự, các chân được đứng lên một lần nữa sau mỗi lần ném vào vị trí mà chúng hạ cánh.)

Tất cả các quy tắc Mölkky khác đều bị bỏ qua và chỉ một người chơi duy nhất được xem xét.

Đầu vào

Một danh sách không trống của danh sách 12 booleans. Mỗi danh sách booleans mô tả kết quả của một lần ném: 1 nếu pin bị lật và 0 nếu không. Các booleans được đưa ra theo thứ tự chính xác của các chân, từ trên trái sang dưới phải: 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2 .

Đầu ra

Điểm sau tất cả các lần ném được mô tả trong đầu vào, được tính bằng cách áp dụng quy tắc 1 , 23 .

Ví dụ chi tiết

Hãy xem xét các đầu vào sau:

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

Sản lượng dự kiến ​​là 27 .

Quy tắc thử thách

  • Bạn có thể lấy đầu vào ở bất kỳ định dạng hợp lý. Thay vì danh sách các booleans, bạn có thể sử dụng các số nguyên trong đó bit quan trọng nhất là chân số 7 và bit quan trọng nhất là chân số 2. Trong định dạng này, ví dụ trên sẽ được thông qua dưới dạng [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ].
  • Danh sách đầu vào có thể chứa các cú ném trong đó không có pin nào bị lật đổ, trong trường hợp đó, điểm số sẽ không thay đổi.
  • Bạn không có gì đặc biệt để làm khi điểm đạt chính xác 50 điểm. Nhưng bạn có thể cho rằng sẽ không có cú ném nào khác xảy ra khi nó xảy ra.
  • Đây là , vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng.

Các trường hợp thử nghiệm

Sử dụng danh sách các số nguyên làm đầu vào:

[ 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

Bạn có thể theo liên kết này để có được các trường hợp thử nghiệm này ở định dạng Boolean.


5
Thử thách thú vị, và cũng là một trò chơi tuyệt vời để chơi vào mùa hè cho những người bạn chưa từng thử - hoạt động tuyệt vời cùng với bếp nướng.
Nit

2
@Nit Cảm ơn bạn. :) Tôi phải thú nhận rằng tôi đã không biết trò chơi này cho đến ngày hôm nay. Tôi thấy mọi người chơi nó khi đi dạo trong công viên chiều nay. Bây giờ, tôi muốn thử.
Arnauld

Câu trả lời:


7

Python 2 , 126 111 108 104 byte

-3 byte nhờ Jonathan Allan

-4 byte nhờ 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

Hãy thử trực tuyến!

Xác định hàm đệ quy lấy một mảng 2D gồm 1 giây và 0 và trả về một giá trị nguyên. Không có gì quá đặc biệt trong việc xây dựng, và tôi chắc chắn có một giải pháp đơn giản hơn.

Giải trình:

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))%16lưu 1 ký tự so vớiord('GIHEKLFCJDAB'[A[0].index(1)])-65
Kaya

1
Tối ưu hơn một chút:762447093078/12**A[0].index(1)%12
Kaya

Thứ đó trông giống như ma thuật đen đối với tôi! Cảm ơn @Kaya!
Jo King

1
Đó chỉ là mã hóa với cơ sở 12
enedil

6

Thạch , 25 byte

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

Một liên kết đơn âm chấp nhận một danh sách các danh sách các số và số không (mỗi chiều dài 12) trả về một số nguyên.

Hãy thử trực tuyến!Hoặc xem bộ kiểm tra (sử dụng các giá trị nguyên được đưa ra trong OP)

Làm sao?

Giải pháp này sử dụng œ?, trong đó đưa ra một số, n và một danh sách tìm thấy hoán vị từ vựng thứ n của danh sách trong đó danh sách xác định thứ tự sắp xếp. Đầu tiên chúng ta cần tìm ra điều này 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)

... đó là, Ptại chỉ mục iđược đặt thành chỉ mục ban đầu của giá trị i.
Đây Pcó một chỉ số hoặc null của 438.337.469 (có nghĩa là, nếu bạn mất tất cả 12! Hoán vị của những con số 1 để 12 và sắp xếp chúng thứ tự từ điển, các 438.337.469 thứ sẽ P).
Điều này có thể được tìm thấy bằng cách sử dụng Œ¿nguyên tử của Jelly .
Cả hai bước có thể được thực hiện trong một lần bằng chương trình 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)

Tôi nghĩ rằng lời giải thích của bạn về việc tìm kiếm chỉ số từ điển phù hợp trong số tất cả các hoán vị sẽ có giá trị thêm như một mẹo Jelly . (Thời gian qua tôi đã phải làm điều đó, tôi đã tìm kiếm dichotomic dẫn sử dụng, mà không phải là dài cho chuỗi ngắn nhưng ... kinda tẻ nhạt ^^.)
Arnauld

LOL; Tôi đã có chính xác cùng một giải pháp, ngoại trừ hai byte khác nhau: -> , µ-> Ʋ. Jelly sẽ thực sự được hưởng lợi từ acceppting một liên kết niladic như ¡'s <link>(số đầu tiên), ngoại trừ việc, nếu trên rất bắt đầu của chương trình, tiếp tục hành vi đặc biệt-vỏ.
Erik the Outgolfer

... Và tôi gần như đã sử dụng cả hai!
Jonathan Allan


4

Pyth, 51 48 38 byte

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

Đã lưu 10 byte nhờ Jonathan Allan Lấy đầu vào dưới dạng danh sách các danh sách booleans.
Hãy thử nó ở đây

Giải trình

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.

Không chắc chắn làm thế nào để đưa nó vào chương trình một cách chính xác, nhưng nó sẽ tiết kiệm được 6 hoặc 7 byte nếu bạn có thể ... 7tT8h4hT12h5h2T4h02-> .PC"îO&"S12- sử dụng lập chỉ mục hoán vị từ vựng như câu trả lời Jelly của tôi. (Mã có byte không thể in là 0x0F khi bắt đầu chuỗi.)
Jonathan Allan

))có thể;
Jonathan Allan

4

05AB1E , 29 28 byte

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

Hãy thử trực tuyến!

Giải trình

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


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

Hãy thử trực tuyến!

Gói là thông minh: tôi về cơ bản chỉ mục ở vị trí s+sum(…)vào danh sách ([0..50]++cycle[25]). Tuy nhiên, một cách ngắn hơn để viết đó là lập chỉ mục tại vị trí sum(…)và bắt đầu danh sách tại 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;}

Chứa 10 dấu vết.
Nhập dưới dạng ma trận số nguyên và số không.

-1 byte nhờ @JonathanFrech , thay đổi \tthành một tab thực tế (hoạt động trong TIO, không hoạt động trong IDE cục bộ của tôi).

Hãy thử trực tuyến.

Giải trình:

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

Tôi nghĩ bạn có thể lưu một byte bằng cách sử dụng một ký tự tab thực tế trong "\t\n".
Jonathan Frech

@JonathanFrech Hmm, thực sự có vẻ hoạt động trong TIO. Không hoạt động cục bộ trong IDE của tôi, nhưng ai quan tâm đến điều đó tôi đoán ..;)
Kevin Cruijssen

Khi có một thực hiện làm việc ở đâu đó, nó được cho phép. : @
Jonathan Frech

2

Than , 43 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Đưa đầu vào như một mảng boolean. Giải trình:

≔⁰η

Đặt điểm thành 0.

Fθ«

Vòng qua ném.

⎇⊖Σι

Là số lượng chân 1?

Σι

Nếu không, sau đó lấy số lượng chân.

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

Nếu không, dịch vị trí của pin thành một giá trị.

≧⁺...η

Thêm nó vào điểm số.

¿›η⁵⁰≔²⁵η

Nếu số điểm vượt quá 50 thì đặt lại thành 25.

»Iη

In kết quả cuối cùng sau khi ném tất cả.


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

Cùng chiều dài: f l=foldl(\b a->last$b+m a:[25|b+m a>50])0lthay vì fc

Hãy thử trực tuyến!


Thả đối số l trong f cho 3 byte. f=foldl(\b->c.(b+).m)0
aoemica

2

Chồng , 47 35 byte

-12 byte nhờ H.PWiz (cách tốt hơn để tạo các điểm mã hóa danh sách)!

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

Hãy thử trực tuyến!

Giải trình

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

Thế còn m+3d4652893071?
H.PWiz

1

Màu đỏ , 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]

Hãy thử trực tuyến!

Giải thích về mã không được mã hóa:

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

Các trường hợp thử nghiệm:


Cùng kích thước với (và rất giống với) triển khai tham chiếu của tôi . :)
Arnauld

À, tuyệt. Tôi hạnh phúc bất cứ khi nào tôi có thể phù hợp với kích thước mã của bạn. Chỉ có một lần trong một mặt trăng xanh mà tôi có thể đánh bại nó :)
Rick Hitchcock

0

Stax , 37 byte

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

Chạy và gỡ lỗi nó

Dùng thử trực tuyến!

Giải trình

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

Không phải công việc tốt nhất của tôi, nhưng nó hoạt động. Tôi chắc chắn rằng có một số điều tôi đang thiếu để làm cho nó ngắn hơn một chút.


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

Hãy thử trực tuyến!

Thay thế mà không có chức năng đệ quy.

-2 cảm ơn @Jo King


Bạn có thể xóa các dấu ngoặc quanh chuỗi ký tự
Jo King
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.