Mölkky를하자!


33

lk 키

Mölkky 는 핀란드어 던지는 게임입니다. 플레이어는 나무 핀 ( "mölkky"라고도 함)을 사용하여 1에서 12까지의 숫자로 표시된 던지는 핀과 거의 비슷한 치수의 나무 핀을 두 드리려고 시도합니다. 핀의 초기 위치는 다음과 같습니다.

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

이 설명과 규칙은 Wikipedia를 기반으로 합니다.

단순화 된 Mölkky 규칙

  1. 한 핀을 두드리면 핀에 표시된 점수가 표시됩니다.

  2. 두 개 이상의 핀을 두드리면 넘어진 수가 점수가 매겨집니다 (예 : 3 개 이상의 핀을 두드리면 3 점).

  3. 게임의 목표는 정확히 50 점 에 도달하는 것 입니다. 점수를 25 점으로 다시 설정하면 50 점 이상의 점수가 부과됩니다 .

  4. 이 문제를 해결 하기 위해 핀은 항상 위에서 설명한 순서대로되어 있다고 가정합니다 . (실제 게임에서는 핀이 착륙 한 위치에 던져 질 때마다 핀이 다시 일어납니다.)

다른 모든 Mölkky 규칙은 무시되며 단일 플레이어 만 고려됩니다.

입력

비어 있지 않은 12 개의 부울 목록 목록입니다. 각 부울 목록은 던지기 결과를 나타냅니다. 핀이 넘어지면 1 , 그렇지 않으면 0 입니다. 부울은 핀의 정확한 순서대로 왼쪽 상단에서 오른쪽 하단으로 : 7 , 9 , 8 , 5 , 11 , 12 , 6 , 3 , 10 , 4 , 1 , 2 입니다.

산출

규칙 1 , 23 을 적용하여 계산 한 입력에 설명 된 모든 드로우 후의 점수 입니다.

자세한 예

다음 입력을 고려하십시오.

// 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
멋진 도전과 여름에도 시도해 보지 못한 훌륭한 게임은 그릴과 함께 잘 작동합니다.
Nit

2
@Nit 감사합니다. :) 오늘까지이 게임을 몰랐다고 고백해야합니다. 오늘 오후에 공원에서 산책하는 동안 사람들이 연주하는 것을 보았습니다. 이제 시도해보고 싶습니다.
Arnauld

답변:


7

파이썬 2 , 126111108104 바이트

Jonathan Allan 덕분에 -3 바이트

카야 덕분에 -4 바이트!

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

온라인으로 사용해보십시오!

1과 0의 2D 배열을 가져 와서 정수 값을 반환하는 재귀 함수를 정의합니다. 건설에 특별한 것은 없으며 더 간단한 해결책이 있다고 확신합니다.

설명:

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))%161시 ord('GIHEKLFCJDAB'[A[0].index(1)])-65
카야

1
조금 더 최적 :762447093078/12**A[0].index(1)%12
카야

그 물건은 나에게 흑 마법처럼 보인다! 감사합니다 @Kaya!
조 왕

1
그것은 단지 기본 12로 인코딩 된 것입니다.
nedil

6

젤리 , 25 바이트

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

정수를 리턴하는 1과 0 (각 길이 12의 목록) 목록을 승인하는 모나드 링크.

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오(OP에 제공된 정수 값 사용)

방법?

이 솔루션은 œ?, 숫자 n 을 제공하고 목록이 정렬 순서를 정의하는 목록 의 n 번째 사전 순열을 찾습니다 . 먼저 우리는 이것을 해결해야합니다 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)

... 즉, Pat 인덱스 i는 값의 원래 인덱스로 설정됩니다 i.
이것은 P의 사전 편찬 지수가 438337469를 (모든했다 경우 즉, 12! 숫자의 순열 (1)(12) 와, 사 전적으로 그들을 분류 438,337,469을 일이 될 것이다 P).
이것은 Jelly 's Œ¿atom을 사용하여 찾을 수 있습니다 .
두 단계 모두 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)

모든 순열 중에서 적절한 사전 색인을 찾는 방법에 대한 설명은 젤리 팁으로 추가 할 가치가 있다고 생각합니다 . (지난 번에 내가 내가 아닌 수동 이분법 검색,했다, 그렇게했다 좀 지루한 짧은 시퀀스하지만 ...에 대한 긴 ^^.)
Arnauld

LOL; -> , -> 두 개의 다른 바이트를 제외하고 는 정확히 동일한 솔루션을 가졌습니다 . 젤리는 프로그램의 맨 처음에 특별한 케이싱 동작을 유지한다는 점을 제외하고 는 닐라 딕 링크를 ' (첫 번째 논점) 으로 채택함으로써 실제로 이익을 얻을 것입니다. µƲ¡<link>
Outgolfer Erik

... 그리고 나는 둘 다 거의 사용했습니다!
Jonathan Allan


4

Pyth, 51 48 38 바이트

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

Jonathan Allan 덕분에 10 바이트를 절약했습니다. 부울 목록으로 입력을받습니다.
여기 사용해보십시오

설명

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.

프로그램에 정확하게 넣는 방법을 모르지만 가능한 경우 6 또는 7 바이트를 저장해야합니다 ...- 7tT8h4hT12h5h2T4h02> .PC"îO&"S12-내 젤리 답변과 같은 사전 순열 색인을 사용합니다. (코드는 문자열의 시작에서 0x0F의의 인쇄 할 수없는 바이트가 있습니다.)
조나단 앨런

));
Jonathan Allan

4

05AB1E , 29 28 바이트

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

온라인으로 사용해보십시오!

설명

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

하스켈 , 96 바이트

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

온라인으로 사용해보십시오!

줄 바꿈은 영리합니다. 본질적으로 s+sum(…)list 에 위치 를 색인 합니다 ([0..50]++cycle[25]). 그러나 작성하는 더 짧은 방법은 위치에서 색인을 생성하고에서 sum(…)목록을 시작하는 것 s입니다.


3

자바 10 131 130 129 바이트

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

인쇄 할 수없는 10 개가 들어 있습니다.
0과 1의 정수 행렬로 입력하십시오.

@JonathanFrech 덕분에 -1 바이트 덕분에 \t실제 탭으로 변경 되었습니다 (TIO에서는 작동하지만 로컬 IDE에서는 작동하지 않습니다).

온라인으로 사용해보십시오.

설명:

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

에 실제 탭 문자를 사용하여 1 바이트를 절약 할 수 있다고 생각합니다 "\t\n".
Jonathan Frech

@JonathanFrech Hmm, 실제로 TIO에서 작동하는 것 같습니다. 내 IDE에서 로컬로 작동하지 않지만 그 점에 관심이있는 사람은 ..;)
Kevin Cruijssen

어딘가에 작동하는 구현이 있으면 허용됩니다. : @
Jonathan Frech

2

, 43 바이트

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

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 부울 배열로 입력을받습니다. 설명:

≔⁰η

점수를 0으로 설정하십시오.

Fθ«

던지기를 반복합니다.

⎇⊖Σι

핀 수가 1입니까?

Σι

그렇지 않은 경우 핀 수를 가져옵니다.

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

그렇지 않으면 핀 위치를 값으로 변환하십시오.

≧⁺...η

점수에 추가하십시오.

¿›η⁵⁰≔²⁵η

점수가 50을 초과하면 다시 25로 설정하십시오.

»Iη

모든 던지기 후에 최종 결과를 인쇄하십시오.


2

하스켈 , 110 바이트

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

동일 길이 : f l=foldl(\b a->last$b+m a:[25|b+m a>50])0l대신 f하고c

온라인으로 사용해보십시오!


l 인수를 f에서 3 바이트 동안 삭제하십시오. f=foldl(\b->c.(b+).m)0
aoemica

2

껍질 , 47 35 바이트

H.PWiz 덕분에 -12 바이트 (목록 인코딩 포인트를 생성하는 더 좋은 방법)!

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

온라인으로 사용해보십시오!

설명

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

어때요 m+3d4652893071?
H.PWiz

1

빨강 , 189 172 바이트

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]

온라인으로 사용해보십시오!

ungolfed 코드에 대한 설명 :

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 바이트

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

테스트 사례 :


참조 구현 과 크기가 같고 매우 유사합니다 . :)
Arnauld

아, 멋지다. 코드 크기와 일치 할 때마다 행복합니다. 푸른 달에 한 번만 이길 수 있습니다 :)
Rick Hitchcock

0

Stax , 37 바이트

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

실행 및 디버깅

온라인으로 사용해보십시오!

설명

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

내 최고의 작품은 아니지만 작동합니다. 좀 더 짧게 만들기 위해 누락 된 somehting이 있다고 확신합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.