+와 *를 사용하여 숫자를 얻으려면 숫자를 찾으십시오.


28

소개

목표는 입력 값을 얻기 위해 함께 더하거나 곱 해야하는 최소 개수를 찾는 것 입니다. 이것은 A005245 입니다.

입력

하나의 양의 정수 N 입니다.

산출

N 을 얻기 위해 더하거나 곱해야하는 가장 적은 수의 것 .

샘플 입력

7

샘플 출력

6

설명

( 1+ 1+ 1) * ( 1+ 1) + 1= 7

이것에는 6하나 가 필요하기 때문에 출력은6

테스트 사례

 1  1
 2  2
 3  3
 5  5
10  7
20  9
50 12

이것이 챌린지이므로 가장 적은 수의 바이트가 이깁니다.



9
프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다! 첫 번째 도전 과제로는 문제가 없지만 다음에는 도전 과제 를 게시하기 전에 샌드 박스 를 사용하여 피드백을 받으십시오.
betseg

4
필요한 최소 개수를 찾고 있음을 명시 적으로 나타내도록 수정하는 것이 좋습니다 . 그렇지 않으면 단순히 원래 숫자를 출력하고 함께 추가 해야하는 숫자라고 주장하는 것이 유효한 솔루션입니다.
얽히고 설킨

2
f(x) != x.primeFactorisation().sum()1을 제외한 예가 있습니까?
jrtapsell

1
@ jrtapsell : 예. $ f (7) = 6 $의 주어진 예는 1입니다. 소수의 $ p $에 대해 $ p-1 $를 인수 분해하여 추가 할 수 있습니다. 아직 더 나아질 수 있습니다.
로스 Millikan

답변:


17

파이썬 2 , 74 70 바이트

f=lambda n:min([n]+[f(j)+min(n%j*n+f(n/j),f(n-j))for j in range(2,n)])

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

대체 버전, 59 바이트 (확인되지 ​​않음)

f=lambda n:min([n]+[f(j)+f(n/j)+f(n%j)for j in range(2,n)])

이것은 적어도 n = 1,000,000 까지 작동 하지만 모든 양수 n에 대해 작동한다는 것을 아직 입증하지 못했습니다 .

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


간단한 것이 누락되어서 죄송하지만 이것이 모든 가능한 표현 트리를 시도한다는 것은 분명하지 않습니다. 특히 n=a*j+b와 함께 외부 레이어 가 b<j있지만 필요 b>=j합니까?
xnor

흠, b>=j그리고 둘 다 실패하는 경우에만 실패합니다 b>=a. 그러나 당신이 옳습니다, 이것이 일어나지 않을 것이라는 것은 분명하지 않습니다.
Dennis

1,000,000까지의 반례가 없다는 사실에 흥미가 있지만 실제로 항상 작동하는지 궁금합니다. 반례에 대한 나의 가장 좋은 생각은 형태의 것이 될 것 a*b+c*d으로 a,b,c,d모든 가산 표현과 매우 효율적입니다.
xnor

10

젤리 , 16 14 바이트

2 바이트를 절약 해 주셔서 감사합니다 Dennis!

ÆḌḊ,Ṗ߀€+U$FṂo

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


논리 설명

숫자 n이 주어지면 :

  • 그렇다면 1대답은 1입니다. 그렇지 않으면:

표현은 a + b또는 a × b, where abexpression입니다.

a및의 가능한 모든 값을 고려하십시오 b.

  • 표현 인 경우 a + b, 다음 ab범위에있다 [1 .. n-1].
  • 표현 인 경우 a × b, a그리고 b적절한 약수이다 n보다 클수록 1.

두 경우 모두 목록 [[<proper divisors of n larger than 1>], [1, 2, ..., n-1]]이 계산되고 ( ÆḌḊ,Ṗ), 각 링크에 현재 링크를 매핑하고 ߀€, 올바른 쌍을 함께 추가하고 ( +U$) 최소값을 얻습니다 ( FṂo).

코드 설명

ÆḌḊ,Ṗ߀€+U$FṂo   Main link. Assume n = 10.
ÆḌ       Proper divisors. [1,2,5]equeue, remove the first element. [2,5]
   ,Ṗ    Pair with op. Auto convert n = 10 to range 
         [1,2,3,4,5,6,7,8,9,10] and remove the last element
         10, get [1,2,3,4,5,6,7,8,9].

߀€      Apply this link over each element.
   +U$   Add with the Upend of itself.

FṂ       Flatten and get the inimum element.
  o      Logical or with n.
         If the list is empty, minimum returns 0 (falsy), so logical or
         convert it to n.

5

자바 스크립트 (ES6), 108 96 바이트

f=n=>n<6?n:Math.min(...[...Array(n-2)].map((_,i)=>Math.min(f(++i)+f(n-i),n%++i/0||f(i)+f(n/i))))

매우 비효율적입니다. Array(n>>1)바이트 비용으로 약간 속도를 높입니다. 설명 : n%++i경우 제로가 아닌 i요소가 아니므 n%++i/0Infinity경우 (따라서 truthy, 또한 확실히 최소화하지) i요소가 아니라 NaN(따라서 falsy) 경우는 i요소이다. 편집 : @ edc65에서 영감을 얻어 12 바이트를 저장했습니다.


백그라운드에서 실행하여 실제로 계산할 수 f(50)있었지만 불행히도 Windows Update가 내 PC를 재부팅 한 후에 완료 할 수 있는지 확인했습니다.
Neil

배열에서 한 번만 걸어 보셨습니까?
edc65

@ edc65 죄송 합니다만, 귀하가 제안하는 내용과 이유가 확실하지 않습니다.
Neil

두 개의 맵이 있는데, 각 맵은 a배열을 스캔합니다 . 평가를 2 개의 람다로 병합하고 분을 취할 수 없습니까?
edc65

@ edc65 아 네, 어떤 이유로 든 min을 중첩하는 것이 더 저렴하지 않다고 생각했지만 (i+=2)다른 것으로 교체 하여 ++i총 12 바이트를 절약했습니다. 감사합니다!
Neil

5

Pari / GP , 66 바이트

Dennis의 Python 답변 포트 :

f(n)=vecmin(concat(n,[f(j)+min(n%j*j+f(n\j),f(n-j))|j<-[2..n-1]]))

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


Pari / GP , 72 바이트

길지만 효율적입니다.

f(n)=if(n<6,n,vecmin([if(d>1,f(d)+f(n/d),1+f(n-1))|d<-divisors(n),d<n]))

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


1
Dennis는 그의 방법을 개선했으며이를 사용하면 11 바이트를 절약 할 수 있습니다 f(n)=vecmin(concat(n,[f(j)+f(n\j)+f(n%j)|j<-[2..n-1]])).
Jonathan Allan



2

Wolfram Language (Mathematica) , 59 바이트

Martin Ender 덕분에 3 바이트를 절약했습니다. CP-1252 인코딩 사용 (여기서는 ±1 바이트)

±1=1;±n_:=Min[1+±(n-1),±#+±(n/#)&/@Divisors[n][[2;;-2]]]

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


2
소스가 CP 1252로 인코딩되었다고 가정하면 3 바이트 ±f절약하는 대신 사용 : tio.run/##y00syUjNTSzJTE78///QRkNbQ@tDG/PirWx9M/…
Martin Ender

1
입력 353942783에 대해 올바르게 작동하지 않습니다.
Misha Lavrov

1

Perl 5 , -p 78 바이트

이전 스타일 계산의 79 바이트 ( +1for -p)

$이 모든 스칼라 액세스에 엑스트라 를 사용해야한다는 사실은 실제로 많은 산술을하는 골프의 길이를 아프게합니다 ...

이 방법은 대부분 이미 게시 된 다른 방법과 비슷합니다 (목표 수를 만들기 위해 곱셈과 덧셈을 시도하면 가장 저렴합니다). 그러나 반복적으로 재귀하지 않으므로 비교적 큰 입력에 사용할 수 있습니다.

또한 perl 5에는 기본 제공 요소가 없으며 min숫자 정렬이 looooooong이므로 코드에서 정렬에서 볼 수 있듯이 덧셈 또는 곱셈으로 숫자를 작성 하는 비용을 최소화하려고 시도하지 않습니다 . 대신 숫자가 곱셈을 사용할 대상의 요인인지 가정합니다. 예를 들어, 경우 것이 있기 때문에 안전하다는 것을 3의 요인은 12(는 비용 요약 있도록 3하고를 12/3) 나중에 루프가 고려할 것입니다 9=12-3, 그래서 요인이 될 수 없습니다하는 9+3것과 같은 비용으로 3+9어쨌든 시도 얻을 것이다. 그러나 대상에 대해서는 실패 할 수 있습니다 <= 4( 1및 에만 해당 2). $_수정 사항을 최소화하기 위해 목록에 추가 합니다. 내가 이미 초기화했기 때문에 기본 사례에 실제로 필요하지 않기 때문에 불행한 일입니다.@; 올바른 시작 값으로 3 바이트가 소요됩니다.

#!/usr/bin/perl -p
($_)=sort{$a-$b}$_,map{$;[$_]+$;[$'%$_?$'-$_:$'/$_]}//..$_ for@;=0..$_;$_=pop@

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

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