चलो Mölkky खेलते हैं!


32

Mölkky

मोल्ककी एक फिनिश फेंकने वाला खेल है। खिलाड़ी एक समान पिन के साथ लगभग समान आयामों के लकड़ी के पिन पर दस्तक देने की कोशिश करने के लिए एक लकड़ी के पिन (जिसे "मोल्कस्की" भी कहा जाता है) का उपयोग करते हैं, 1 से 12. की संख्या के साथ चिह्नित पिन की प्रारंभिक स्थिति निम्नानुसार है:

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

यह विवरण और नीचे दिए गए नियम हैं विकिपीडिया

सरलीकृत मोल्ककी नियम

  1. एक पिन पर दस्तक पर अंकित अंकों की संख्या ।

  2. दस्तक 2 या अधिक पिन स्कोर पिन की संख्या पर दस्तक (जैसे, पर 3 पिंस स्कोर 3 अंक दस्तक)।

  3. खेल का उद्देश्य ठीक 50 अंक तक पहुंचना है । 50 से अधिक स्कोर करने पर स्कोर को 25 अंक पर सेट करके दंडित किया जाता है।

  4. इस चुनौती के उद्देश्य के लिए, हम यह अनुमान लगाएंगे कि पिंस हमेशा ऊपर वर्णित सटीक क्रम में हैं। (वास्तविक गेम में, पिन उस स्थान पर प्रत्येक फेंकने के बाद फिर से खड़े हो जाते हैं, जहां वे उतरे थे।)

अन्य सभी मोल्ककी नियमों की अनदेखी की जाती है और केवल एक ही खिलाड़ी को माना जाता है।

इनपुट

12 बूलियनों की सूची की एक गैर-खाली सूची। बूलियन्स की प्रत्येक सूची में एक फेंक के परिणाम का वर्णन किया गया है: 1 यदि पिन पर खटखटाया गया था और अन्यथा 0 । बूलियन को पिन के सटीक क्रम में दिया जाता है, ऊपर से नीचे दाएं: 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2

उत्पादन

इनपुट में वर्णित सभी फेंकता के बाद का स्कोर, नियम 1 , 2 और 3 लागू करके गणना की जाती है ।

विस्तृत उदाहरण

आइए निम्नलिखित इनपुट पर विचार करें:

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

अपेक्षित आउटपुट 27 है

चुनौती के नियम

  • आप किसी भी उचित प्रारूप में इनपुट ले सकते हैं। बूलियन्स की सूचियों के बजाय, आप पूर्णांक का उपयोग कर सकते हैं जहां पिन # 7 सबसे महत्वपूर्ण बिट है और सबसे कम बिट बिट पिन # 2 है। इस प्रारूप में, उपरोक्त उदाहरण के रूप में पारित किया जाएगा [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ]
  • इनपुट सूची में ऐसे थ्रो शामिल हो सकते हैं, जहाँ कोई भी पिन नहीं खटखटाया जाता है, जिस स्थिति में स्कोर को अपरिवर्तित रहने दिया जाता है।
  • जब स्कोर ठीक 50 अंक तक पहुंच जाए तो आपके पास करने के लिए कुछ खास नहीं होता है । लेकिन आप यह मान सकते हैं कि ऐसा होने पर कोई अन्य थ्रो नहीं होगा।
  • यह , इसलिए बाइट्स में सबसे कम जवाब जीतता है।

परीक्षण के मामलों

इनपुट के रूप में पूर्णांकों की सूची का उपयोग करना:

[ 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

आप बूलियन प्रारूप में इन परीक्षण मामलों को प्राप्त करने के लिए इस लिंक का अनुसरण कर सकते हैं ।


5
Cool challenge, and also a great game to play in the summer for those of you who haven't tried it out — works great along with a grill.
Nit

2
@Nit Thank you. :) I have to confess that I didn't know this game until today. I saw people playing it while walking in a park this afternoon. Now, I'd like to give it a try.
Arnauld

जवाबों:


7

Python 2, 126 111 108 104 bytes

-3 bytes thanks to Jonathan Allan

-4 bytes thanks to 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

Try it online!

Defines a recursive function that takes a 2D array of 1s and 0s and returns an integer value. Nothing too special in the construction, and I'm sure there's a simpler solution.

Explanation:

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))%16 saves 1 character versus ord('GIHEKLFCJDAB'[A[0].index(1)])-65
Kaya

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

That stuff looks like black magic to me! Thanks @Kaya!
Jo King

1
That's just encoding with base 12
enedil

6

Jelly, 25 bytes

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

A monadic link accepting a list of lists of ones and zeros (each of length 12) which returns an integer.

Try it online! Or see the test-suite (using the integer values given in the OP)

How?

This solution makes use of, œ?, which given a number, n, and a list finds the nth lexicographical permutation of the list where the list defines the sort order. First we need to work out this 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)

...that is, P at index i is set to the original index of the value i.
This P has a lexicographical index of 438,337,469 (that is, if you took all 12! permutations of the numbers 1 to 12 and sorted them lexicographically, the 438,337,469th would be P).
This may be found using Jelly's Œ¿ atom.
Both steps may be performed in one go using the Jelly program ĠŒ¿

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

I think your explanation about finding the appropriate lexicographical index among all permutations would be worth adding as a Jelly tip. (Last time I had to do that, I did a manual dichotomic search, which is not that long for short sequences but ... kinda tedious. ^^)
Arnauld

LOL; I had exactly the same solution, except for two different bytes: -> , µ -> Ʋ. Jelly would really benefit from acceppting a niladic link as ¡'s <link> (first argument), except that, if on the very start of the program, keep the special-casing behavior.
Erik the Outgolfer

...and I almost used both!
Jonathan Allan


4

Pyth, 51 48 38 bytes

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

Saved 10 bytes thanks to Jonathan Allan Takes input as a list of lists of booleans.
Try it here

Explanation

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.

Not sure how to get it into the program exactly, but it should save 6 or 7 bytes if you can... 7tT8h4hT12h5h2T4h02 -> .PC"îO&"S12 - uses lexicographical permutation indexing like my Jelly answer. (The code has an unprintable byte of 0x0F at the start of the string.)
Jonathan Allan

)) can be ;
Jonathan Allan

4

05AB1E, 29 28 bytes

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

Try it online!

Explanation

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 bytes

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

Try it online!

The wrapping is clever: I essentially index at position s+sum(…) into the list ([0..50]++cycle[25]). However, a shorter way to write that is indexing at position sum(…) and beginning the list at s.


3

Java 10, 131 130 129 bytes

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

Contains 10 unprintables.
Input as integer-matrix of zeros and ones.

-1 byte thanks to @JonathanFrech, changing \t into an actual tab (works in TIO, doesn't work in my local IDE).

Try it online.

Explanation:

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

I think you can save one byte by using an actual tab character in "\t\n".
Jonathan Frech

@JonathanFrech Hmm, indeed seems to work in TIO. Doesn't work locally in my IDE, but who cares about that I guess.. ;)
Kevin Cruijssen

When there is a working implementation somewhere, it is allowed. :@
Jonathan Frech

2

Charcoal, 43 bytes

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

Try it online! Link is to verbose version of code. Takes input as a boolean array. Explanation:

≔⁰η

Set the score to 0.

Fθ«

Loop over the throws.

⎇⊖Σι

Is the number of pins 1?

Σι

If not, then take the number of pins.

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

Otherwise, translate the position of the pin to a value.

≧⁺...η

Add it to the score.

¿›η⁵⁰≔²⁵η

If the score exceeds 50 then set it back to 25.

»Iη

Print the final result after all the throws.


2

Haskell, 110 bytes

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

Same length: f l=foldl(\b a->last$b+m a:[25|b+m a>50])0l instead of f and c

Try it online!


Drop the l argument in f for 3 bytes. f=foldl(\b->c.(b+).m)0
aoemica

2

Husk, 47 35 bytes

-12 bytes thanks to H.PWiz (better way of generating the list encoding points)!

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

Try it online!

Explanation

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

How about m+3d4652893071?
H.PWiz

1

Red, 189 172 bytes

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]

Try it online!

Explanation of the ungolfed code:

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 bytes

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 cases:


Same size as (and very similar to) my reference implementation. :)
Arnauld

Ah, cool. I'm happy whenever I can match your code size. It's only once in a blue moon that I can beat it :)
Rick Hitchcock

0

Stax, 37 bytes

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

Run and debug it

Try It online!

Explanation

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

Not my best work, but it works. I'm sure there is somehting I'm missing to make it a bit shorter.


0

Python 2, 109 105 103 bytes

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

Try it online!

Alternative without a recursive function.

-2 with thanks to @Jo King


You can remove the brackets around the string literal
Jo King
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.