정확히 n까지 합할 최소 숫자 수 수 있습니다. 도전 보다 작거나

첫 번째 질문입니다. 이것이 중복이거나 나쁜 도전이라면 저에게 소리 지르지 마십시오.

소개

나는이 도전에 대해 스스로 생각했고 초보자 코드 골퍼에게는 좋은 기본 퍼즐 인 것 같습니다. 또한 학습 할 코드 골프 언어를 결정하는 데 도움이 될 수 있습니다.

도전

보다 작거나 같은 정수 배열이 주어지면 배열 n에서 정확히 합한 최소 숫자 수를 출력하거나 반환합니다 n.

함수 또는 전체 프로그램을 작성하도록 선택할 수 있습니다.

입력

안전하게 가정 할 수 있습니다 0 <= n < 2^31.

배열 의 길이를 지정 하는 선택적 parameter 와 함께 모든 종류의 배열 또는 목록을 가져옵니다 ( vectorC ++ 또는 Java의 LinkedList경우 허용됨) .nlength

입력을 n쉼표 나 공백으로 구분하여 공백으로 구분 된 문자열로 사용할 수도 있습니다 .

1 5 7 3 7 3 6 3 2 6 3,10

1 5 7 3 7 3 6 3 2 6 3 10

더 쉬운 경우.

산출

배열에서 정확히 합하는 최소 숫자 수를 출력하거나 반환합니다 n. 위의 예를 사용하여 :

1 5 7 3 7 3 6 3 2 6 3,10

프로그램이 인쇄되어야합니다 :

2

합계되는 최소 숫자 102( 73) 이므로

해결책이없는 경우 빈 문자열을 제외 하고 음수, 0“아니오 해결책”(스마트하지는 않지만) (제안 된대로) 또는 다른 잘못된 값을 인쇄하거나 반환 합니다.

입력 및 출력 예

입력:

1 5 7 3 7 3 6 3 2 6 3,10
143 1623 1646 16336 1624 983 122,18102
5 6 9,12

산출:

2
3
-1

채점

이것은 코드 골프이므로 바이트 단위의 가장 짧은 코드가 이깁니다.

최고의 답변은 크리스마스에 허용됩니다.



답변

Pyth, 12 11 바이트

lhafqsTQyEY

이것은 n첫 번째 입력 행과 두 번째 행의 목록으로 사용됩니다.

lhafqsTQyEY     (Implicit: Q = 1st line of input; E = 2nd line)
         E      The list
        yE      Powerset (sorted by increasing length; empty set first)
   f            Filter by lambda T:
     sT         sum(T)
    q                  ==
       Q                  Q
   fqSTQyE      Sublists that sum to Q, sorted by increasing length
  a       Y     append an empty array (in case none match)
lh              take the length of the first element (0 for empty array)

여기서 사용해보십시오 .


답변

Japt , 30 21 18 바이트

훨씬 더 효율적인 방법이 있음이 밝혀졌습니다. 😉

Uà f_x ¥V} ml n- g

온라인으로 테스트하십시오! (참고 : 호환성 이유로 n-변경되었습니다 n@X-Y})

공백이나 쉼표로 구분 된 배열로 숫자를 입력합니다. undefined솔루션이없는 테스트 케이스 출력 .

Uà f_  x ¥ V} ®   l} n- g
UàfmZ{Zx ==V} mZ{Zl} n- g

            // Implicit: U = input array, V = input integer
Uà fZ{   }  // Generate all possible combinations of U, then filter to only items Z where
Zx ==V      //   the sum of Z is equal to V.
mZ{Zl}      // Map each remaining combination to its length.
n-          // Sort by subtraction; smaller items end up in the front.
g           // Take the first item.
            // Implicit: output last expression

나는 원래 이것을 쓸 때이 버전을 생각하지 않았다는 것을 믿을 수 없다 …

그 이후로 여러 가지 최적화가 이루어졌으며 여기에서 유용합니다.

  • U프로그램 시작 부분의 A 는 일반적으로 생략 할 수 있습니다.
  • Ã에 대한 바로 가기입니다 .
  • n 이제 기본적으로 숫자를 올바르게 정렬합니다.

각각 15 바이트 씩 바이트를 제거합니다.

à f_x ¥VÃml n g

온라인으로 테스트하십시오!


답변

Mathematica, 73 65 바이트

Min[Length/@Select[IntegerPartitions[#2,#2,#],Sort@#==Union@#&]]&

순수한 함수, 솔루션이 없으면 반환 합니다.


답변

파이썬 3, 128 바이트

이것은 내가 원하는만큼 골프는 아니지만 나중에 작업 할 것입니다.

from itertools import*
def s(a,n):
 for i in range(len(a)):
  for j in permutations(a,i+1):
   if sum(j)==n:return i+1
 return 0

답변

Mathematica, 45 바이트

Min@Cases[Subsets@#,i_/;Tr@i==12:>Length@#2]&

답변

CJam, 34 바이트

0q~_,2,m*\f.*{:+1$=},\;0f-{,}$0=,+

온라인으로 사용해보십시오 . 입력 형식은 다음에 값 목록이 오는 합계입니다. 예 :

18102 [143 1623 1646 16336 1624 983 122]

해결책을 찾지 못하면 예외가 발생합니다. CJam이 명령 행에서 실행될 때 예외는 stderr로 이동하고 올바른 결과 ( 0)는 여전히 stdout으로 인쇄됩니다. 따라서 제출이 오류와 함께 종료되어야합니까? 에서 설정된 합의를 충족합니다 .

코드가 예상보다 오래 보일 수 있습니다. 주된 이유는 CJam에 조합 생성을위한 내장 기능이 없기 때문입니다. 또는 적어도 그것은 내 변명이며, 나는 그것을 고집하고 있습니다.

설명:

0       Push 0 result for exception case.
q~      Get and interpret input.
_,      Copy and get length of input value list.
2,      Push [0 1].
m*      Cartesian power. This generates all possible lists of 0/1 values with the
        same length as the input value list.
\       Swap input value list to top.
f.*     Apply element-wise product of input value list with all 0/1 lists.
        We now have all combinations of values, with 0 in place of unused values.
{       Start filter block.
  :+      Sum values.
  1$      Copy target sum to top.
  =       Compare.
},      Filter.
\;      Swap target sum to top and discard.
0f-     Remove 0 values. We now have all solution lists.
{,}$    Sort by length.
0=      Get first solution, which after sorting is the shortest.
        This will raise an exception if the list of solutions is empty, bailing
        out with the initial 0 on the stack.
,       Get length of solution.
+       Add the 0 we initially pushed for the exception case.

답변

자바 스크립트 (ES6), 84 바이트

f=(a,n,m=1e999,x)=>n&&a.map((v,i)=>(x=[...a],x.splice(i,1),x=f(x,n-v)+1)<m?m=x:0)&&m

설명

ArrayNumber의와 Number인수로합니다. Infinity결과가 없으면 숫자를 반환합니다 . 이 함수는 n까지 배열에서 각 요소 를 빼고 하나씩 제거 하는 재귀 함수입니다 n == 0.

f=(a,n,m=1e999,x)=> // m and x are not passed, they are here to declare them in the local
                    //     scope instead of globally, initialise m to Infinity
  n&&               // if n == 0, return 0
  a.map((v,i)=>     // iterate over each number in a
    (x=[...a],      // x = copy of a
    x.splice(i,1),  // remove the added number from the array
    x=f(x,n-v)+1)   // x = result for the numbers in this array
      <m?m=x:0      // set m to minimum result
  )
  &&m               // return m

테스트

이 테스트는 Firefox가 아닌 Chrome에서 작동하도록 기본 인수 대신 나중에 설정 m합니다 Infinity.

var solution = f=(a,n,m,x)=>n&&a.map((v,i)=>(x=[...a],x.splice(i,1),x=f(x,n-v)+1)<m?m=x:0,m=1e999)&&m
Array (space-delimited) = <input type="text" id="array" value="143 1623 1646 16336 1624 983 122" /><br />
n = <input type="number" id="N" value="18102" /><br />
<button onclick="result.textContent=solution(array.value.split` `,N.value)">Go</button>
<pre id="result"></pre>