Vamos jogar Mölkky!


32

Mölkky

Mölkky é um jogo de tiro finlandês. Os jogadores usam um pino de madeira (também chamado de "mölkky") para tentar derrubar pinos de madeira de dimensões quase semelhantes ao pino de lançamento, marcados com números de 1 a 12. A posição inicial dos pinos é a seguinte:

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

Esta descrição e as regras abaixo são baseadas na Wikipedia .

Regras de Mölkky simplificadas

  1. Bater sobre um pino marca o número de pontos marcados no pino.

  2. Bater 2 ou mais pinos marca o número de pinos derrubados (por exemplo, bater 3 pinos ganha 3 pontos).

  3. O objetivo do jogo é atingir exatamente 50 pontos. Marcar mais de 50 pontos é penalizado definindo a pontuação de volta para 25 pontos.

  4. Para o propósito deste desafio, assumiremos que os pinos estão sempre na ordem exata descrita acima. (Em um jogo real, os pinos são levantados novamente após cada lançamento no local em que aterrissaram.)

Todas as outras regras de Mölkky são ignoradas e apenas um jogador é considerado.

Entrada

Uma lista não vazia de listas de 12 booleanos. Cada lista de booleanos descreve o resultado de um arremesso: 1 se o pino foi derrubado e 0 em caso contrário. Os booleanos são fornecidos na ordem exata dos pinos, do canto superior esquerdo para o canto inferior direito: 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2 .

Saída

A pontuação após todos os lances descritos na entrada, calculada aplicando as regras 1 , 2 e 3 .

Exemplo detalhado

Vamos considerar a seguinte entrada:

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

A saída esperada é 27 .

Regras do desafio

  • Você pode receber informações em qualquer formato razoável. Em vez de listas de booleanos, você pode usar números inteiros em que o bit mais significativo é o pino 7 e o bit menos significativo é o pino 2. Nesse formato, o exemplo acima seria passado como [ 256, 2304, 127, 64, 64, 128, 2048, 3072 ].
  • A lista de entrada pode conter arremessos em que nenhum pino é derrubado; nesse caso, a pontuação é mantida inalterada.
  • Você não tem nada de especial para fazer quando a pontuação atinge exatamente 50 pontos. Mas você pode assumir que nenhum outro lance se seguirá quando isso acontecer.
  • Isso é , então a resposta mais curta em bytes vence.

Casos de teste

Usando listas de números inteiros como entrada:

[ 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

Você pode seguir este link para obter esses casos de teste no formato booleano.


5
Desafio bacana e também um ótimo jogo para quem não experimentou no verão - funciona muito bem com uma churrasqueira.
Nit

2
@ Obrigado. :) Tenho que confessar que não conhecia esse jogo até hoje. Vi pessoas tocando enquanto passeava em um parque esta tarde. Agora, eu gostaria de tentar.
Arnauld

Respostas:


7

Python 2 , 126 111 108 104 bytes

-3 bytes graças a Jonathan Allan

-4 bytes graças ao 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

Experimente online!

Define uma função recursiva que pega uma matriz 2D de 1s e 0s e retorna um valor inteiro. Nada de muito especial na construção, e tenho certeza de que há uma solução mais simples.

Explicação:

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

1
Um pouco mais ideal:762447093078/12**A[0].index(1)%12
Kaya

Esse material parece magia negra para mim! Obrigado @Kaya!
Jo Rei

1
Isso é apenas codificação com base 12
enedil

6

Gelatina , 25 bytes

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

Um link monádico que aceita uma lista de listas de uns e zeros (cada um com comprimento 12) que retorna um número inteiro.

Experimente online! Ou veja o testes (usando os valores inteiros fornecidos no OP)

Quão?

Esta solução faz uso de, œ?, que dado um número, n, e uma lista encontra o n th léxicografica permutação da lista onde a lista define a ordem de classificação. Primeiro, precisamos resolver isso 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)

... ou seja, Pno índice ié definido como o índice original do valor i.
Isso Ptem um índice lexicográfico de 438.337.469 (ou seja, se você pegasse todas as 12 permutações dos números de 1 a 12 e as classificasse lexicograficamente, seria o 438.337.469 thP ).
Isso pode ser encontrado usando o Œ¿átomo de Jelly .
Ambas as etapas podem ser executadas de uma só vez usando o programa 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)

Acho que sua explicação sobre como encontrar o índice lexicográfico apropriado entre todas as permutações valeria a pena adicionar como uma dica de geléia . (Da última vez que eu tinha que fazer isso, eu fiz uma busca dicotômica manual, o que não é que por muito tempo para seqüências curtas mas ... meio tediosas ^^.)
Arnauld

RI MUITO; Eu tinha exatamente a mesma solução, exceto por dois bytes diferentes: -> , µ-> Ʋ. O Jelly realmente se beneficiaria de aceitar um link niládico como ¡o <link>primeiro argumento, exceto que, se no início do programa, mantiver o comportamento de revestimento especial.
Erik the Outgolfer

... e eu quase usei os dois!
Jonathan Allan


4

Pitão, 51 48 38 bytes

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

Economizou 10 bytes graças a Jonathan Allan Toma como entrada uma lista de listas de booleanos.
Experimente aqui

Explicação

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.

Não sei exatamente como inseri-lo no programa exatamente, mas ele deve salvar 6 ou 7 bytes se você puder ... 7tT8h4hT12h5h2T4h02-> .PC"îO&"S12- usa indexação de permutação lexicográfica como minha resposta Jelly. (O código tem um byte não imprimível de 0x0F no início da string.) #
Jonathan Allan

))pode ser;
Jonathan Allan

4

05AB1E , 29 28 bytes

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

Experimente online!

Explicação

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 bytes

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

Experimente online!

Recebe entrada como uma série de cadeias de bits separadas por nova linha.


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

Experimente online!

A embalagem é inteligente: eu essencialmente indexo a posição s+sum(…)na lista ([0..50]++cycle[25]). No entanto, uma maneira mais curta de escrever é indexar na posição sum(…)e iniciar a lista em 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;}

Contém 10 não imprimíveis.
Entrada como matriz inteira de zeros e uns.

-1 byte graças a @ JonathanFrech , mudando \tpara uma guia real (funciona no TIO, não funciona no meu IDE local).

Experimente online.

Explicação:

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

Eu acho que você pode salvar um byte usando um caractere de tab real "\t\n".
Jonathan Frech

@ JonathanFrech Hmm, de fato parece funcionar no TIO. Não funciona localmente no meu IDE, mas quem se importa com isso eu acho ..;)
Kevin Cruijssen

Quando há uma implementação funcionando em algum lugar, é permitida. : @
Jonathan Frech

2

Carvão vegetal , 43 bytes

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

Experimente online! Link é a versão detalhada do código. Recebe a entrada como uma matriz booleana. Explicação:

≔⁰η

Defina a pontuação como 0.

Fθ«

Laço sobre os lances.

⎇⊖Σι

O número de pinos é 1?

Σι

Caso contrário, pegue o número de pinos.

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

Caso contrário, traduza a posição do pino para um valor.

≧⁺...η

Adicione à pontuação.

¿›η⁵⁰≔²⁵η

Se a pontuação exceder 50, defina-a novamente como 25.

»Iη

Imprima o resultado final após todos os lances.


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

Mesmo comprimento: em f l=foldl(\b a->last$b+m a:[25|b+m a>50])0lvez de fec

Experimente online!


Solte o argumento l em f por 3 bytes. f=foldl(\b->c.(b+).m)0
Aoemica

2

Casca , 47 35 bytes

-12 bytes graças ao H.PWiz (melhor maneira de gerar os pontos de codificação da lista)!

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

Experimente online!

Explicação

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 tal m+3d4652893071?
H.PWiz

1

Vermelho , 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]

Experimente online!

Explicação do código não destruído:

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

Casos de teste:


Mesmo tamanho que (e muito semelhante) à minha implementação de referência . :)
Arnauld

Ah legal. Fico feliz sempre que posso corresponder ao seu tamanho de código. É apenas uma vez em uma lua azul que eu possa vencê-lo :)
Rick Hitchcock

0

Stax , 37 bytes

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

Execute e depure

Experimente online!

Explicação

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

Não é o meu melhor trabalho, mas funciona. Tenho certeza de que falta algo para torná-lo um pouco mais curto.


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

Experimente online!

Alternativa sem uma função recursiva.

-2 com agradecimentos a @Jo King


Você pode remover os suportes em torno da cadeia literal
Jo rei
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.