Jouons à Mölkky!


32

Mölkky

Mölkky est un jeu de lancer finlandais. Les joueurs utilisent une goupille en bois (également appelée "mölkky") pour tenter de renverser des goupilles en bois de dimensions presque similaires avec la goupille de lancer, portant les chiffres de 1 à 12. La position initiale des goupilles est la suivante:

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

Cette description et les règles ci-dessous sont basées sur Wikipedia .

Règles Mölkky simplifiées

  1. Le renversement d' une épingle marque le nombre de points marqués sur l'épingle.

  2. Frapper deux ou plus de quilles marque le nombre de quilles renversées (par exemple, frapper sur trois quilles rapporte 3 points).

  3. Le but du jeu est d’atteindre exactement 50 points. Marquer plus de 50 est pénalisé en ramenant le score à 25 points.

  4. Pour les besoins de ce défi, nous supposerons que les broches sont toujours dans l'ordre exact décrit ci-dessus. (Dans un vrai jeu, les quilles sont relevées après chaque lancer à l'endroit où elles ont atterri.)

Toutes les autres règles de Mölkky sont ignorées et un seul joueur est pris en compte.

Contribution

Une liste non vide de listes de 12 booléens. Chaque liste de booléens décrit le résultat d'un lancer: 1 si l'épingle a été renversée et 0 sinon. Les booléens sont donnés dans l'ordre exact des quilles, de haut en bas à droite: 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2 .

Sortie

Le score après tous les jets décrits dans l’entrée, calculé en appliquant les règles 1 , 2 et 3 .

Exemple détaillé

Considérons l'entrée suivante:

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

La sortie attendue est 27 .

Règles du challenge

  • Vous pouvez prendre des entrées dans n'importe quel format raisonnable. Au lieu de listes de booléens, vous pouvez utiliser des entiers où le bit le plus significatif est la broche n ° 7 et le bit le moins significatif est la broche n ° 2. Dans ce format, l'exemple ci-dessus serait transmis en tant que [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ].
  • La liste de saisie peut contenir des jets où aucune broche n'est renversée, auquel cas le score reste inchangé.
  • Vous n'avez rien de spécial à faire lorsque le score atteint exactement 50 points. Mais vous pouvez supposer qu’aucun autre coup ne suivra quand cela se produira.
  • C'est du , donc la réponse la plus courte en octets est gagnante.

Cas de test

Utiliser des listes d'entiers en entrée:

[ 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

Vous pouvez suivre ce lien pour obtenir ces cas de test au format booléen.


5
Cool challenge, et aussi un bon jeu à jouer en été pour ceux qui ne l'ont pas essayé - fonctionne très bien avec un grill.
Nit

2
@Nit Merci. :) Je dois avouer que je ne connaissais pas ce jeu jusqu'à aujourd'hui. J'ai vu des gens en train de jouer en marchant dans un parc cet après-midi. Maintenant, j'aimerais essayer.
Arnauld

Réponses:


7

Python 2 , 126 111 108 104 octets

-3 octets grâce à Jonathan Allan

-4 octets grâce à 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

Essayez-le en ligne!

Définit une fonction récursive qui prend un tableau 2D de 1 et de 0 et renvoie une valeur entière. Rien de spécial dans la construction, et je suis sûr qu'il existe une solution plus simple.

Explication:

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))%16enregistre 1 personnage contreord('GIHEKLFCJDAB'[A[0].index(1)])-65
Kaya

1
Un peu plus optimal:762447093078/12**A[0].index(1)%12
Kaya

Cela ressemble à de la magie noire pour moi! Merci @Kaya!
Jo King

1
C'est juste l'encodage avec la base 12
Enedil

6

Gelée , 25 octets

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

Un lien monadique acceptant une liste de listes de uns et de zéros (de longueur 12 chacun) qui renvoie un entier.

Essayez-le en ligne! Ou voir la suite de tests (en utilisant les valeurs entières indiquées dans l'OP)

Comment?

Cette solution utilise œ?, qui donne un nombre, n, et une liste trouve la n ième permutation lexicographique de la liste où la liste définit l’ordre de tri. Nous devons d’abord résoudre ce problème 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)

... c'est-à-dire, Pat index iest défini sur l'index d'origine de la valeur i.
Cela Pa un indice lexicographique de 438.337.469 (qui est, si vous avez pris toutes les 12! Permutations des numéros 1 à 12 et les lexicographique triées, la 438337469 e serait P).
Cela peut être trouvé en utilisant l' Œ¿atome de Jelly .
Les deux étapes peuvent être effectuées en une fois en utilisant le programme 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)

Je pense que votre explication sur la recherche de l'index lexicographique approprié parmi toutes les permutations mériterait d'être ajoutée en tant que gélule . ( La dernière fois que je devais le faire, je l' ai fait une recherche manuelle dichotomique, qui ne sont pas que de temps pour des séquences courtes , mais ... un peu fastidieux ^^.)
Arnauld

LOL; J'avais exactement la même solution, à l'exception de deux octets différents: -> , µ-> Ʋ. Jelly serait vraiment bénéficier de acceppting un lien niladic comme ¡de » <link>(premier argument), sauf que, si le début du programme, garder le comportement boîtier spécial.
Erik the Outgolfer

... et j'ai presque utilisé les deux!
Jonathan Allan


4

Pyth, 51 48 38 octets

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

Sauvegardé 10 octets grâce à Jonathan Allan Extrait la liste des booléens.
Essayez-le ici

Explication

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.

Vous ne savez pas exactement comment l'introduire exactement dans le programme, mais vous devriez économiser 6 ou 7 octets si vous le pouvez ... 7tT8h4hT12h5h2T4h02-> .PC"îO&"S12- utilise l'indexation par permutation lexicographique comme ma réponse Jelly. (Le code a un octet non imprimable de 0x0F au début de la chaîne.)
Jonathan Allan

))peut être;
Jonathan Allan

4

05AB1E , 29 28 octets

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

Essayez-le en ligne!

Explication

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 octets

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

Essayez-le en ligne!

Prend les entrées comme une série de chaînes de bits séparées par une nouvelle ligne.


3

Haskell , 96 octets

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

Essayez-le en ligne!

L'habillage est intelligent: j'indexe essentiellement les positions s+sum(…)dans la liste ([0..50]++cycle[25]). Cependant, un moyen plus court d’écrire est l’indexation à la position sum(…)et le début de la liste à s.


3

Java 10, 131 130 129 octets

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

Contient 10 non imprimables.
Entrée sous forme de matrice entière de zéros et de uns.

-1 octet grâce à @JonathanFrech , qui est \tdevenu un onglet réel (fonctionne dans TIO, ne fonctionne pas dans mon IDE local).

Essayez-le en ligne.

Explication:

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

Je pense que vous pouvez enregistrer un octet en utilisant un caractère de tabulation dans "\t\n".
Jonathan Frech

@ JonathanFrech Hmm, semble en effet fonctionner dans TIO. Ne travaille pas localement dans mon IDE, mais qui se soucie de ça, je suppose ..;)
Kevin Cruijssen

Lorsqu'il y a une implémentation fonctionnelle quelque part, cela est autorisé. : @
Jonathan Frech

2

Charbon de bois , 43 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Prend les entrées sous forme de tableau booléen. Explication:

≔⁰η

Définir le score à 0.

Fθ«

Boucle sur les lancers.

⎇⊖Σι

Le nombre de broches est-il 1?

Σι

Sinon, prenez le nombre de broches.

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

Sinon, traduisez la position de la broche en une valeur.

≧⁺...η

Ajoutez-le à la partition.

¿›η⁵⁰≔²⁵η

Si le score dépasse 50, réglez-le à 25.

»Iη

Imprimez le résultat final après tous les lancers.


2

Haskell , 110 octets

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

Même longueur: f l=foldl(\b a->last$b+m a:[25|b+m a>50])0lau lieu de fetc

Essayez-le en ligne!


Supprimez l'argument l dans f pour 3 octets. f=foldl(\b->c.(b+).m)0
aoemica

2

Décortiquer , 47 35 octets

-12 octets grâce à H.PWiz (meilleur moyen de générer des points d'encodage en liste)!

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

Essayez-le en ligne!

Explication

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

Que diriez- m+3d4652893071vous
H.PWiz

1

Rouge , 189 172 octets

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]

Essayez-le en ligne!

Explication du code non-golfé:

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 octets

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

Cas de test:


Même taille que (et très similaire à) mon implémentation de référence . :)
Arnauld

Ah cool. Je suis heureux chaque fois que je peux correspondre à la taille de votre code. Ce n'est qu'une fois dans une lune bleue que je peux le battre :)
Rick Hitchcock

0

Stax , 37 octets

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

Exécuter et déboguer

Essayez-le en ligne!

Explication

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

Ce n'est pas mon meilleur travail, mais ça marche. Je suis sûr qu'il me manque quelque chose pour le raccourcir un peu.


0

Python 2 , 109 105 103 octets

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

Essayez-le en ligne!

Alternative sans fonction récursive.

-2 grâce à @Jo King


Vous pouvez supprimer les crochets autour de la chaîne littérale
Jo King
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.