3 과일 파이는 몇 개나 만들 수 있습니까?


32

세 과일 파이는 세 가지 다른 과일 로 만들어집니다 . 당신이 가진 5 개의 과일의 양으로 만들 수있는 가장 3 과일 파이는 무엇입니까?

예를 들어

1 apple
1 banana
4 mangoes 
2 nectarines
0 peaches

파이 2 개를 만들 수 있습니다 :

apple, mango, nectarine
banana, mango, nectarine

입력 : 음이 아닌 5 개의 정수 또는 그 목록.

출력 : 그 과일 양으로 만들 수있는 최대 3 개의 과일 파이. 가장 적은 바이트가 이깁니다.

테스트 사례 :

1 1 4 2 0
2
2 2 2 2 2
3
0 6 0 6 0
0
12 5 3 2 1
5
1 14 14 3 2
6
0 0 1 0 50
0

리더 보드 :


귀하의 예에는 Apple, Banana, Mango 및 Apple, Banana, Nectarine의 두 가지 추가 옵션이 누락되었다고 생각합니다. 따라서 1 1 4 2 0테스트 케이스는 다음과 같이 출력을 생성해야합니다. 4.
cobaltduck

@cobaltduck 그러나 첫 번째 파이 (Apple / Banana / Mango)에서 Apple과 바나나를 사용하는 경우 두 번째 파이 (Apple / Banana / Nectarine)에 사용할 Apple 또는 Banana가 없습니다.
AdmBorkBork

2
@Timmy D : 아, 알았습니다. 파이가 동시에 만들어지고 있는지는 확실하지 않았습니다.
cobaltduck

@cobaltduck 나는 그들이 동시에 만들 필요는 없다고 생각하지만 첫 번째 과일에 사용한 과일을 재사용하여 속임수를 쓸 수는 없습니다.
Mr Lister

@씨. 리스터 : 의미론. 모호한 규칙 (적어도 한 명의 독자에게는)이 명확 해 졌으므로 충분합니다.
cobaltduck

답변:


34

Pyth, 19 18 14 바이트

@FryAmTheEggman에 의해 -1 바이트

@isaacg의 14 바이트 프로그램

나는 오름차순 목록에서 형성 할 수있는 파이의 수 [x1,x2,x3,x4,x5]는 다음과 같습니다.

floor(min((x1+x2+x3+x4+x5)/3,(x1+x2+x3+x4)/2,x1+x2+x3))

또는 코드에서 :

JSQhS/Ls~PJ_S3

[TI-BASIC 및 APL 프로그램의 개정 내역 참조]

정확성 증명

방해

s3 = x1+x2+x3
s4 = x1+x2+x3+x4
s5 = x1+x2+x3+x4+x5

우리 는 과일 수 1 ~ 5의 P(X)=floor(min(s5/3,s4/2,s3))목록 x1≤x2≤x3≤x4≤x5에서 항상 가장 많은 파이 수 를 보여주고 싶습니다 .

먼저 세 숫자가 모두 상한임을 보여줍니다.

  • 이 때문에 s5전체 과일, 각각의 파이는 세 가지 과일을 가지고, ⌊s5/3⌋상한이다.

  • 이 때문에 s4있는 과일 없는 과일 (5)는, 적어도 두 개의 비 (5) 과일이 각 파이 필요합니다, ⌊s4/2⌋상한이다.

  • 이 때문에 s3어느 과일 4도 과일 5입니다 과일, 적어도 하나 개의 과일이 각 파이 필요합니다, s3상한이다.

둘째, 우리는 3 개의 가장 큰 더미에서 과일을 섭취하는 방법이 항상 그 한계를 충족한다는 것을 보여줍니다. 우리는 이것을 유도하여 수행합니다.

기본 사례 :로 유효한 모든 목록에서 0 개의 파이를 형성 할 수 있습니다 P(X)>=0.

귀납적 단계 : 로 목록 을 남기고 파이 하나를 구울 수 X있는 모든 목록 이 주어 집니다 . 우리는 가장 큰 3 개의 더미에서 과일을 가져온 다음 필요한 경우 리조트를 이용하여이를 수행합니다. 나와 함께 참 아라. 몇 가지 사건이 있습니다.P(X) > 0X'P(X') >= P(X)-13,4,5

  • 인 경우 x2<x3과일을 제거한 후 목록을 정렬 할 필요가 없습니다. 우리는 이미 유효한 X'입니다. 우리는 알고 P(X') = P(X)-1있기 때문에 s5'(유형 1 ~ 5 세 과일이 제거 되었기 때문에) 3 이하, s4'적은 2이고, s3'1 이하입니다. 그래서 P(X')정확히 하나의 작은 P (X)보다.
  • 인 경우 x3<x4유사하게 수행됩니다.
  • 이제 우리는 어디에서 사건을 해결 x2=x3=x4합니다. 이번에는 목록을 다시 정렬해야합니다.

    • 경우에 x5>x4, 우리는 (4) 및 더미 2 스위칭 목록을 재 배열 s5'하고 s4', 각각 3 및 2 정지의 감소하지만 s3'=s3-2. if x2=x3=x4이면 2*x4<=s3-> 2*x4+s3 <= 2*s3-> 이므로 문제가되지 않습니다 (x4 + s4)/2 <= s3. 우리는 두 가지 하위 사례가 있습니다.
    • 평등, 즉 (x4,x3,x2,x1)=(1,1,1,0),이 경우 P(X)= 1우리는 더미 5,4,3에서 파이를 명확하게 만들 수 있습니다 .

    • (s4+1)/2 <= s3이 경우 s4추가 1가 감소한다고해서 P (X)가 추가로 감소하는 것은 아닙니다.

  • 이제 우리는 어디에 사건이 남아있다 x1<x2=x3=x4=x5. 이제 s3우리가 필요로하는, 그래서 또한, 1 감소 될 (s5/3+1)것으로 <=s4/2; 즉 8x5+2x1+2<=9x5+3x1, 또는 x5+x1>=2. 이보다 작은 모든 사례는 수동으로 확인할 수 있습니다.

  • 모든 숫자가 같으면의 한계를 달성 할 수 있음이 분명합니다.의 한계 ⌊s5/3⌋는 항상 다른 두 숫자보다 작습니다. 우리는 단순히 숫자를 순서대로 진행합니다.

마지막으로 끝났습니다. 내가 빠진 것이 있으면 의견을 말하고 좀 더 우아한 증거를 위해 작은 현상금을 줄 것입니다.


귀하의 주장은 @fryamtheeggman의 반복 솔루션과 일치한다고 생각합니다.
Sparr

@Sparr fryamtheeggman의 방법을 사용하여 내 경계에 도달 할 수 있음을 증명하려고합니다.
lirtosiast

2
루프로 바꾸면 4 바이트 씩 골프를 뛸 수 있습니다.JSQhS/Ls~PJ_S3
isaacg

3
나는 파이 당 n재료와 k재료에 대한 증거를 찾았다 고 생각 하지만이 주석 상자에는 너무 깁니다 . 발견 할 수있는 모든 오류를 지적하여이를 입증 할 수 있도록하십시오.
Mego

7

CJam, 34

q~L{J2be!\f{\.-_W#){j)7}|;}0+:e>}j

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

설명:

q~          read and evaluate the input array
L{…}j       calculate with memoized recursion and no initial values
             using the input array as the argument
  J2b       convert 19 to base 2 (J=19), obtaining [1 0 0 1 1]
  e!        get permutations without duplicates
             these are all the combinations of three 1's and two 0's
             which represent the choices of fruit for one pie
  \         swap with the argument array
  f{…}      for each combination and the argument
    \       swap to bring the combination to the top
    .-      subtract from the argument array, item by item
    _       duplicate the resulting array
    W#)     does it contain the value -1? (calculate (index of W=-1) + 1)
    {…}|    if not
      j     recursively solve the problem for this array
      )7    increment the result, then push a dummy value
    ;       pop the last value (array containing -1 or dummy value)
  0+        add a 0 in case the resulting array is empty
             (if we couldn't make any pie from the argument)
  :e>       get the maximum value (best number of pies)

재귀를 기억하는 데 바이트가 필요합니까? 런타임 제한이 없습니다.
xnor

2
@xnor 나는 그것이 실제로 1 여기 바이트 : 저장 생각
aditsu

7

하스켈, 62 바이트

f x=maximum$0:[1+f y|y<-mapM(\a->a:[a-1|a>0])x,sum y==sum x-3]

f과일 목록을 가져 와서 x최대 파이 수를 반환 하는 함수 를 정의합니다 .

설명

파이 수를 재귀 적으로 계산합니다. 부품 mapM(\a->a:[a-1|a>0])xx양수 항목을 줄임으로써 얻은 모든 목록의 목록으로 평가됩니다 . 인 경우 x = [0,1,2]결과

[[0,1,2],[0,1,1],[0,0,2],[0,0,1]]

바깥 쪽 사이의 부분 []은 목록 이해입니다. 우리 y는 위 목록의 모든 항목 을 반복 하고 합계가 같지 않은 것을 필터링하여 sum(x)-33 개의 다른 과일이 파이로 만들어진 모든 목록을 얻습니다. 그런 다음 f이 목록 을 재귀 적으로 평가 하고 각 목록에 추가 1하고 최대 값을 0얻습니다 (파이를 만들 수없는 경우 기본 사례).


7

C #, 67

소진 될 때까지 가장 많은 과일을 반복적으로 반복하여 파이를 하나씩 만듭니다.

int f(List<int>p){p.Sort();p[3]--;p[4]--;return p[2]-->0?1+f(p):0;}

여기에서 테스트 사례


C #에 익숙하지 않지만 p[2]--확인과 동시에 할 수 p[2]>-1있습니까?
xnor

좋은 점은 잠시 후 답변을 업데이트하겠습니다.
AXMIM

6

피 이스, 29

Wtt=QS-Q0=Q+tPPQtM>3.<Q1=hZ;Z

테스트 스위트

입력 목록을 정렬하고 0을 제거합니다. 그런 다음 3 개의 과일이있는 한 첫 번째와 두 개의 마지막 요소를 줄이고 나머지 요소를 목록에 추가하여 정렬하고 0을 다시 제거하십시오. 그런 다음 카운터를 1 씩 증가시킵니다.

과일이 5 개 밖에없는 한 실제로는 매우 빠릅니다 1000,1000,1000,1000,1000. 즉, 매우 큰 과일 통, 즉 1 초 이내에 해결할 수 있습니다 .


그것이 옳다는 것을 증명할 수 있습니까?
aditsu

@aditsu 나는 그것을 입증하지 못했지만 몇 가지 추가 값을 확인했습니다. 나는 전에 이와 같은 것에 대한 증거를 실제로 작성하지는 않았지만 시도 할 것입니다. 지금은 작은 과일을 소진 할 때까지 항상 가장 큰 과일 더미에서만 가져 오기 때문에 효과가 있다고 말하겠습니다. 욕심 많은 전략이 본질적으로 항상 올바른 것은 아니지만, 왜 그것이 효과가 없는지 생각할 수 없습니다.
FryAmTheEggman

@FryAmTheEggman 가장 일반적인 과일 2 개와 가장 희귀 한 과일을 섭취한다는 것을 이해합니까?
xnor

@xnor 예, 맞습니다. 작동하지 않습니까?
FryAmTheEggman

1
@TimmyD 아니요, 생각하지 않아도되지만이 기능을 제거하는 데 바이트가 필요하지 않습니다 (실제로 더 비쌉니다). 그게 내가 기대했다 레토 Koradi의 솔루션은 대부분의 언어에서 짧은, 분명 토마스의이 훨씬 더 간결하다. 나는 당신이 다시 정렬 할 필요가없는 이유는 당신이 가져 오는 3 개의 작은 더미 중 어느 것이 중요하지 않은 것과 관련이 있다고 생각합니다.
FryAmTheEggman

6

Python, 일반 솔루션, 128 92 바이트

@xnor에서 -36 바이트, 당신은 진짜 mvp

g=lambda l,k:0if k>sum(l)else-(-1in l)or-~g(map(sum,zip(sorted(l),[0]*(len(l)-k)+[-1]*k)),k))

def g(a,k):b=[i for i in a if i];return 0if len(b)<k;c=sorted(b,reverse=True);return 1+g([c[i]-(k-1>i)for i in range(len(c))],k)

내 증거 가 올바른 한 작동 합니다. 그렇지 않은 경우 이유를 알려 주시면 문제를 해결할 수 있습니다. 이해할 수 없으면 알려주세요. 커피 몇 잔을 마시면 공격하겠습니다.


지금은 모든 것이 나에게 딱딱 해 보입니다.
lirtosiast

@Mego이 작업을 해주셔서 감사합니다! SE 게시물에 증거를 포함시킬 수 있습니까? 몇 년 후 누군가가 죽은 링크를 발견 할 수 있다는 일반적인 우려가 있습니다. LaTeX 형식은 대부분 MathJax에서만 작동합니다.
xnor

@ Mego 죄송합니다. MathJax가 활성화되어 있지 않은 것을 잊었습니다. 흠, 어떻게해야하는지 물어 볼게요.
xnor

이 증명에 대한 현상금을 수여합니다. 축하합니다!
xnor

@ Mego Nope, MathCloud 링크가 가장 좋습니다.
xnor

5

파이썬 2, 78 바이트

5 개의 숫자를 입력으로 사용 : 91 89 88 바이트

s=sorted([input()for x in[0]*5])
while s[2]:s[2]-=1;s[3]-=1;s[4]-=1;s.sort();x+=1
print x

편집 : 변경 하면 1 바이트 s=sorted([input()for x in[0]*5])s=sorted(map(input,['']*5));x=0저장됩니다.

5 개의 숫자를 입력으로 받아 가능한 파이 수를 인쇄합니다. 바이트 수를 개선하지 않고 Reto Koradi의 답변과 동일한 접근 방식을 취하지 만이 질문에 Python에서 답변이 누락 된 것처럼 느꼈습니다.

귀하의 제안에 감사합니다 @ThomasKwa 및 @xsot.

작동 원리

 s=sorted([input()for x in[0]*5]) takes 5 numbers as input, puts them in a list 
                                  and sorts it in ascending order. The result
                                  is then stored in s 

 while s[2]:                      While there are more than 3 types of fruit 
                                  we can still make pies. As the list is                     
                                  sorted this will not be true when s[2] is 0. 
                                  This takes advantage of 0 being equivalent to False.

 s[2]-=1;s[3]-=1;s[4]-=1          Decrement in one unit the types of fruit 
                                  that we have the most

 s.sort()                         Sort the resulting list

 x+=1                             Add one to the pie counter

 print x                          Print the result

변수 x는 정의되어 있지 않지만 프로그램은 python 2.7의 누출을 유리하게 취합니다. s리스트 이해로리스트를 정의 할 때 , 이터 러블의 마지막 값 ( [0]*5이 경우)은 반복에 사용 된 변수에 저장됩니다.

더 명확하게하려면 :

>>>[x for x in range(10)]
>>>x
9

목록을 입력으로 사용 : 78 바이트

입력을 목록으로 변경할 것을 제안하는 @xnor @xsot 및 @ThomasKwa에게 감사합니다.

s=sorted(input());x=0
while s[2]:s[2]-=1;s[3]-=1;s[4]-=1;s.sort();x+=1
print x

작동 원리

위의 코드와 동일한 방식으로 작동하지만이 경우 입력은 이미 목록이므로 작성할 필요가 없으며 변수 x를 정의해야합니다.

면책 조항 : 이것은 골프를 처음 시도한 것으로 여전히 골프를 칠 수 있다고 생각하므로 바이트 수를 줄이기 위해 변경할 수있는 사항을 제안하십시오.


1
입력을 이미 목록에 보유 할 수 있습니다. s[2]>0-> s[2], 파일의 숫자는 항상 음수가 아니기 때문에.
lirtosiast

Thomas Kwa는 입력이 이미 목록으로 제공되어 있다고 가정 할 수 있다고 지적했습니다 s=sorted(input()). 또한 현재 바이트 수는 89입니다. 줄 바꿈은 단일 문자로 계산됩니다.
xnor

@ThomasKwa는 이미 입력을 목록으로 수락 할 수 있다고 지적했지만 여러 줄 입력을 수락하려면 첫 번째 줄을 다음으로 바꾸어 바이트를 저장하십시오 s=sorted(map(input,['']*5));x=0.
xsot

4

CJam, 23 바이트

0l~{\)\$2/~+:(+_2=)}g;(

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

이것은 각 반복에서 가장 큰 3 개의 더미에서 과일을 가져 와서 반복 횟수를 계산합니다.

이것이 항상 올바른 결과를 제공한다는 수학적 증거는 없습니다. 주어진 테스트 예제에서 수행되며 누군가 내게 반대 예제를 제공 할 때까지 모든 경우에 작동한다고 생각합니다.

내가 설득하는 데 사용한 직관적 인 설명 : 파이의 수를 최대화하려면 가능한 한 많은 더미를 비워 두어야합니다. 빈 더미가 3 개 이상이면 더 많은 파이를 만들 수있는 능력이 없어지기 때문입니다.

이것은 항상 가장 큰 더미에서 과일을 섭취함으로써 달성됩니다. 작은 더미에서 과일을 섭취하는 것이 큰 더미에서 과일을 섭취하는 것보다 더 나은 상황을 초래할 수 있다고 생각할 수 없습니다.

나는 머리에 약간 더 공식적인 추론이있다. 나는 그것을 단어 / 공식에 넣는 방법을 생각하려고 노력할 것입니다.


나는 유도를 사용하려고 노력했다. 아이디어를 결합하여 공식적인 증거를 찾을 수도 있습니다.
lirtosiast

@ThomasKwa 나는 그것을 적어두면 설득력이있을만한 명확한 것을 찾지 못했습니다. 모든 것이 더 큰 스택보다 작은 스택에서 가져 오는 것이 더 좋은 이유가 전혀 없다는 사실에 달려 있습니다. 더 작은 스택을 사용하는 것이 더 나빠질 상황이 분명히 있지만 나는 또한 광산과 아디 츠의 솔루션에 중간 정도의 많은 숫자를 입력했으며 동일한 결과를 얻었습니다. 내 솔루션은 내가 시도한 예제에 대한 공식과 일치합니다.
Reto Koradi

3

> <>, 76 바이트

0&4\/~}&?!/
@:@<\!?:}$-1@@$!?&+&:)@:@
,:&:@(?$n;/++:&+::2%-2,:&:@(?$&~+:3%-3

> <>에서 정렬이 쉽지 않습니다! 이 프로그램은 토마스 콰 (Thomas Kwa)이 제시 한 증거가 사실임을 입증하는데, 이는 확실히 테스트 사례의 경우처럼 보입니다.

프로그램 시작시 5 개의 입력 번호가 스택에 나타날 것으로 예상됩니다.

처음 두 줄은 스택에서 숫자를 정렬하고 세 번째 줄은 floor(min((x1+x2+x3+x4+x5)/3,(x1+x2+x3+x4)/2,x1+x2+x3))Thomas의 답변에서 가져온 계산을 수행합니다 .


3/4 요소의 합과 최소값을 모두 계산하면 더 짧을까요?
lirtosiast

@ThomasKwa 나는 입력 세트의 순열을 찾아서 각각의 최상위 3과 4 요소를 합하고 가장 작은 요소를 취하는 것과 관련이 있습니까? 나는 특히 스택 기반 언어에서 순열을 찾는 것이 정렬 / 계산 접근법보다 짧다고 생각하지 않습니다. 스택 기반 언어로 순열을 생성하는 편리한 알고리즘을 알고 있다면 다음을 참조하십시오. : o)
Sok

2

파이썬 2, 59 바이트

h=lambda l,k=3:k*'_'and min(h(sorted(l)[:-1],k-1),sum(l)/k)

어떤을 위해 작동하는 일반적인 방법 nk. 는 k=33 파이 기본적 당 과일하게,하지만 당신은 다른 값으로 전달할 수 있습니다. 재귀는 파이썬 2에서 문자열이 숫자보다 크다는 사실을 사용하여 빈 문자열이 무한대의 기본 사례를 나타냅니다.

이 방법은 항상 가장 일반적인 과일을 섭취하는 것이 최적이라는 사실을 사용하므로 가능한 모든 과일 등급을 제한 요인으로 간주합니다. 아래의 사실을 책망했습니다.


Mego의 증거를 통해 나는 가장 일반적인 과일을 반복적으로 섭취하는 것이 최적이라는 더 직접적인 증거를 생각하게되었습니다. 이것은 k과일 파이로 표시 됩니다.

정리 :k 가장 일반적인 과일을 반복적으로 섭취 하면 최적의 파이 수를 얻을 수 있습니다.

증명 :N 파이가 가능하다면 가장 일반적인 과일 전략은 최소한 N파이를 생산 한다는 것을 보여줄 것입니다 . 우리는 N파이 사이에서 과일을 바꾸어 파이를 유효하게 유지 하면서이 전략으로 생산 된 과일 과 일치하도록 과일을 전환 합니다.

첫 번째 파이 (이것이라고 부름 p)가 가장 일반적인 과일을 함유하도록하십시오. 그렇지 않은 경우 과일을 포함해야 i하지만 더 일반적인 과일 은 포함하지 않아야합니다 j. 그런 다음, 나머지 파이 과일의 엄격 이상이 j과일 이상을 i, 그리고 몇몇 다른 파이 있도록 q메시지 있어야 j하지만 i. 그런 다음, 우리는 열매를 교환 할 수 i파이에서 p과일 j파이에서 q유지 N별개의 열매를 가진 파이.

때까지이 과정을 반복 pk가장 일반적인 과일.

그런 다음 파이를 p따로두고 다음 파이에이 과정을 반복하여 가장 일반적인 남은 과일을 만듭니다. 파이가 가장 일반적인 과일 상태에서 생성되는 순서가 될 때까지 계속하십시오.


1

PowerShell, 92 바이트

$a=($args|sort)-ne0;while($a.count-ge3){$a[0]--;$a[-1]--;$a[-2]--;$a=($a-ne0;$c++}($c,0)[!$c]

FryAmTheEggman의 답변 과 동일한 욕심 기반 알고리즘을 사용합니다 ...

$a=($args|sort)-ne0  # Take input arguments, sort them, remove any 0's
while($a.count-ge3){ # So long as we have 3 or more fruit piles
  $a[0]--            # Remove one from the first element...
  $a[-1]--           # ... the last element ...
  $a[-2]--           # ... and the second-to-last.
  $a=$a-ne0          # Remove any 0's from our piles
  $c++               # Increment how many pies we've made
}                    #
($c,0)[!$c]          # Equivalent to if($c){$c}else{0}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.