공정한 왕을위한 8 개의 동전


22

Puzzling.SE 의 공정한 왕위한 8 개의 동전 인 또 다른 퍼즐의 "상대"입니다 .

배경에 대한 위의 퍼즐을 읽을 수 있습니다. 이 퍼즐에 대한 자세한 내용은 다음과 같습니다.

값이 다른 8 종류의 동전 세트가 만들어지면, 왕은 최대 N을 찾아서 0에서 N까지의 가격에 8 개 이하의 동전을 사용하고 요금없이 지불 할 수 있습니다.

예를 들어 (Glorfindel의 답변에서 발췌). 1, 2, 5, 13, 34, 89, 233, 610 값의 코인 세트가 제공되면 0에서 1596 (포함) 사이의 모든 숫자를 더 이상 합계로 표시 할 수 없으므로 프로그램에서 1596을 출력해야합니다. 주어진 목록에서 8 개 이상의 숫자 (숫자가 반복 될 수 있음) 인 반면 1597은 그런 식으로 표현할 수 없습니다.

수학적 방식으로, 입력이 8 개의 양의 정수로 구성된 세트 S 인 경우, 원하는 출력 N 은 0과 N 사이의 임의의 수 n에 대해 x1, x2, x3, ..., x8이 존재 하는 것을 만족시킨다.

x1+x2+...+x8=nandx1,x2,...,x8{0}S

목표는 8 개의 숫자를 입력으로 사용하여 위에서 설명한대로 최대 N을 출력하는 프로그램, 함수 또는 스 니펫을 작성하는 것입니다.

규칙 :

  • 유연한 I / O가 허용되므로 프로그램이 가장 적합한 형식으로 입력을 취할 수 있습니다. 입력 번호가 프로그램에 가장 적합한 방식으로 정렬되어 있다고 가정 할 수 있습니다.
    • 프로그램이 입력 순서에 의존하는 경우 답변에 기재하십시오
  • 입력은 8 개의 양의 정수 (0이 아님)의 집합입니다. 출력은 음이 아닌 정수입니다.
    • 입력 세트에 1이 없으면 0에서 0까지의 숫자가 요구 사항을 충족하므로 프로그램에서 0을 출력해야합니다.
    • 유효하지 않은 입력 (세트에 0, 음수 또는 중복 숫자가 포함 된 경우)이면 프로그램이 무엇이든 할 수 있습니다.
  • 표준 허점은 금지되어 있습니다.
  • 프로그램은 최신 컴퓨터에서 몇 분 안에 실행되어야합니다.

테스트 사례 (주로 퍼즐 링에 대한 링크 된 질문의 답변에서 발췌) :

[1, 2, 3, 4, 5, 6, 7, 8] => 64
[2, 3, 4, 5, 6, 7, 8, 9] => 0
[1, 3, 4, 5, 6, 7, 8, 9] => 72
[1, 2, 5, 13, 34, 89, 233, 610] => 1596
[1, 5, 16, 51, 130, 332, 471, 1082] => 2721
[1, 6, 20, 75, 175, 474, 756, 785] => 3356

이것은 이므로 각 언어에서 가장 짧은 프로그램이나 스 니펫이 승리합니다!


1
좋은 퍼즐이지만 개인적으로 제출 한 내용을 테스트하는 데 더 많은 테스트 사례가 도움이 될 것이라고 생각합니다.
Mr. Xcoder

입력 크기를 매개 변수로 만드는 것이 낫지 않습니까? 브 루트 포스 접근법은 8 투쟁 할 것이다
루이스 Mendo에게

1
@iBug 그러면 일반적인 규칙은 "현대 컴퓨터에서 1 분 안에 제출해야합니다"와 같은 규칙입니다. 무차별 적이지만 일반적으로 충분합니다. 무차별 대입 방식과 효율적인 접근 방식의 차이가 매우 크기 때문에
Luis Mendo

1
"몇 분"의 시간 제한으로 무차별 대입이 가능합니다. 내 대답의 약간 수정 된 버전은 7 세짜리 랩톱에서 1m20s의 마지막 테스트 사례를 실행합니다.
nimi

1
@Arnauld 명확화
iBug

답변:



9

젤리 , 12 바이트

œċⱮ8Ẏ§ṢQJƑƤS

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

휴대 전화의 TIO에서 모든 테스트 사례를 실행하는 데 평균 ~ 3.7 초가 걸리므로 놀랍게도 매우 빠릅니다.

설명

œċⱮ8Ẏ§ṢQJƑƤS     Monadic link / Full program.
  Ɱ8             Promote 8 to [1 ... 8] and for each value k:
œċ                    Generate all combinations of k elements from the list.
    Ẏ§           Tighten, then sum. Flatten to a 2D list then sum each.
      ṢQ         Sort the result and remove equal entries.
        JƑƤ      For each prefix of this list, return 1 if it is equal to its length range, 0 otherwise.
           S     Finally, sum the result (counts the 1's which is equivalent to what is being asked).

7

하스켈, 56 50 바이트

g c=[x|x<-[1..],all((/=x).sum)$mapM(0:)$c<$c]!!0-1

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

무차별 대입 접근. 0동전 목록에 추가 하고 8 개의 픽을 모두 조합 해보십시오. npicks 및 return의 합과 같지 않은 첫 번째 숫자 를 찾으십시오 n-1.

[1, 2, 5, 13, 34, 89, 233, 610]7 년 된 랩톱 하드웨어에서 약 5m30을 사용 합니다.

편집 : @ Ørjan Johansen 덕분에 -6 바이트

더 짧은 버전 (-2 바이트, @ Ørjan Johansen 덕분에 다시 한 번)은

하스켈, 48 바이트

g c=[x|x<-[1..],all((/=x).sum)$mapM(:0:c)c]!!0-1

그러나 그것은 훨씬 더 많은 메모리를 사용하고 내 컴퓨터에서 많은 페이징을 겪고 "몇 분 안에"끝나지 않습니다.


1
사용할 수 있습니다 mapM(0:)$c<$c. (사실에서 mapM(:0:c)c주어진 테스트 케이스에 대한 TIO에 있지만, 시간을 작동합니다.)
Ørjan 요한센

4

젤리 , 9 바이트

Żœċ8§ḟ’$Ṃ

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

작동 원리

Żœċ8§ḟ’$Ṃ  Main link. Argument: A (array)

Ż          Prepend a 0 to A.
 œċ8       Take all combinations of length 8, with repetitions.
    §      Take the sum of each combination.
       $   Combine the two links to the left into a monadic chain.
      ’      Decrement all sums.
     ḟ       Filterfalse; keep only sums that do not appear in the decremented sums.
        Ṃ  Take the minimum.

2
Żṗ8§ḟ’$Ṃ1 바이트를 저장하지만 8.5 분이 개로 계산되는지 확실하지 않습니다 .
Dennis


4

자바 스크립트 (ES6),  100 88 80  76 바이트

이것은 본질적으로 무차별 검색이지만 속도를 높이기 위해 가지 치기로 향상되었습니다. 테스트 사례의 평균 실행 시간은 TIO에서 1 초에 가깝습니다.

입력 배열이 가장 높은 값에서 가장 낮은 값으로 정렬되었다고 가정합니다.

a=>[...Array(a[0]*9)].findIndex(g=(i=8,s)=>s*i>0?a.every(x=>g(i-1,s-x)):s)-1

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

댓글

a =>                      // a[] = input array
  [...Array(a[0] * 9)]    // create an array of 9 * max(a) entries
  .findIndex(             // find the position of the first truthy result
    g = (i = 8, s) =>     // g = recursive function taking a counter i, initialized to 8
                          //     and a sum s, initialized to the position in the above array
      s * i > 0 ?         //   if s is positive and i is not equal to 0:
        a.every(x =>      //     for each value x in a[]:
          g(i - 1, s - x) //       do a recursive call with i - 1 and s - x
        )                 //     end of every()
      :                   //   else:
        s                 //     yield s (s = 0 means success and makes findIndex go on)
  ) - 1                   // end of findIndex(); decrement the result



2

파이썬 (2) , 125 (115) 111 바이트

lambda c:sum(i==j for i,j in enumerate(sorted(set(map(sum,product([0]+c,repeat=8))))))-1
from itertools import*

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

정수 목록을 입력으로 예상합니다.

설명:

# an anonymous function
lambda c:
                                                          # get all length-8 combinations of values, from (0,0,0,0,0,0,0,0) to (8,8,8,8,8,8,8,8)
                                                          # zero is added to ensure that combinations of fewer than 8 coins are represented Ex:(1,0,0,0,0,0,0,0)
                                                          product([0]+c,repeat=8)
                                                  # for each combination, sum the values
                                                  map(sum,.......................)
                                       # get unique values, then sort them smallest to largest
                                       sorted(set(................................))
             # for each index, value pair, return if the index is equal to the value
             i==j for i,j in enumerate(.............................................)
         # in Python arithmetic, False is 0 and True is 1. So, count how many items match their index.
         # Since zero was added to the list, there will always be one extra match (0==0). So offset by one.
         sum(........................................................................)-1
from itertools import*

2

Perl6, 65 63 41 바이트 ( 39 37 자)

{@_=(0,|@_)X+(0,|@_)for ^3;($_ if $_==$++for @_.sort.unique)-1}

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

데이터를 배열로 전달하는 익명 블록입니다. 는 (0,|@_)를 추가하는 빠른 방법입니다 0@_, 그리고 두 번 다, 비록 그것보다 여전히 약간 짧다 @_.push: 0;후 후 공간을해야한다 _. 이것은 8 조합이라는 사실에 약간의 치즈를 적용하는 무차별 대입 방식입니다. 교차 추가 후, 순차 값에 대한 익명 목록이 작성됩니다. 수학 연산자를 사용하면 목록의 길이가 평가되므로 -1은 이중 의무를 취합니다. 0을 고려하고 Int를 강제합니다.

이 달콤한 시간이 걸릴 수 있지만, 하나 또는 둘 모두 변경하여 수 (0,|@_)에를 (0,|@_.unique)처음 전에 for이 상당히 가속화 될 수있다. 즉 추가 +7 (런타임 <60) 또는 +14 당신이 먼저 (I 60 초 후에 피하기 제한 시간에 링크 된 코드에 대한 이런 짓을) 너무 느린 느낌이 경우 점수 (런타임 <10 초)을.

편집 : 주석에서 JoKing은 놀라운 39 문자 (41 바이트)로 개선했습니다 (동일한 아이디어, 교차 추가 및 마지막 연속 결과 반환).

{(@_=@_ X+0,|@_)xx 3;first *+1@_,^∞}

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

최종 표에는 0이 필요하지 않으며 0을 한 번만 추가하면 몇 바이트가 절약됩니다. xx 3루프 모방은 (여전히 2의 거듭 제곱 인 동전 치즈). first서브 무한리스트의 첫 번째 숫자는 리턴 0..*( ^Inf도 가능하지만, 공간을 저장하지 않음), 그 +1교차 부가리스트의 일원이 아니다. 내 것과 마찬가지로 속도가 느리므로 가이드 라인에 비해 너무 느리다고 생각되면 첫 번째 동등한 후에 +7 을 추가하십시오 unique.


1
48 바이트 . 기술적으로는 unique필요하지 않지만 속도가 훨씬 빨라집니다.
Jo King

@ JoKing 좋은, 나는 왜 사용에 대해 생각하지 않았는지 모르겠다 xx. 나는 정해진 함수를 사용하여 훨씬 짧은 방법으로 최종 도표를 작성하는 방법이 있어야한다는 것을 알고 있었지만 뇌는 작동하지 않았습니다.
user0721090601

xx 1해야한다xx 3
조 왕

@JoKing이 수정되었습니다. 또한 다음을 사용하여 두 개의 문자 (바이트는 아님)를 저장할 수 있음을 깨달았습니다.^∞
user0721090601

실제로,을 (1...*∉@_)-1사용 하는 대신 일부 바이트를 절약 할 수 있습니다 first( 여기에서 사용한 것과 동일한 방법입니다 )
Jo King

1

자바 스크립트 (Node.js를) , 171 (145) 115 바이트

f=(s,n=3)=>n?f(s=new Set(a=[0,...s]),n-1,a.map(m=>a.map(n=>s.add(m+n)))):Math.min(...[...s].filter(m=>!s.has(m+1)))

온라인으로 사용해보십시오! @ Mark의 Python 3 답변 포트. Firefox 30-57에서 108 바이트 :

f=(s,n=3)=>n?f(new Set((for(n of s=[0,...s])for(m of s)n+m)),n-1):Math.min(...[...s].filter(m=>!s.has(m+1)))


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