최대 작업 찾기


12

문제는 기본 산술 연산자 (더하기, 빼기, 곱하기, 단항 부정)를 사용하여 정수 목록에서 얻을 수있는 최대 수를 찾는 것입니다.

입력

정수 목록

산출

입력의 모든 정수사용 하는 최대 결과 입니다.

입력 순서는 중요하지 않으며 결과는 동일해야합니다.

전체 작업을 출력 할 필요는 없으며 결과 만 표시됩니다.

Input : 3 0 1
Output : 4 (3 + 1 + 0)

Input : 3 1 1 2 2
Output : 27 ((2+1)*(2+1)*3))

Input : -1 5 0 6
Output : 36 (6 * (5 - (-1)) +0)

Input : -10 -10 -10
Output : 1000 -((-10) * (-10) * (-10))

Input : 1 1 1 1 1
Output : 6 ((1+1+1)*(1+1))

규칙

  • 최단 코드 승리

  • 표준 "허점" 적용

  • + *-연산자 (더하기, 곱하기, 빼기, 단항 부정) 만 사용할 수 있습니다

  • 결과가 32 비트 정수에 저장 될 수있는 한 코드가 작동해야합니다.

  • 모든 오버 플로우 동작은 사용자에게 달려 있습니다.

이것이 충분히 명확하기를 바랍니다. 이것이 나의 첫 번째 코드 골프 도전 제안입니다.


예 중 하나는 허용되지 않는 연산을 사용하는 것입니다. 단항 부정이 허용 목록에 포함되도록하려면 빼기가 실제로 필요하지 않습니다.
피터 테일러

단항 부정을 편집하고 추가했습니다. 감산은 화이트리스트에 보관됩니다.
CNicolas

1
전체 프로그램이어야합니까, 아니면 충분한 기능입니까?
ThreeFx

전체 프로그램. 온라인으로 실행할 수 있지만 반드시 필수는 아닙니다
CNicolas

@INSeed 온라인 실행 방법을 추가해야합니까?
자랑스런 Haskeller

답변:


9

C-224 바이트-실행 시간 O (n)

o=0,w=0,n[55],t,*m=n,*p=n;main(r){for(;scanf("%d",++p);t<3?--p,w+=t/2,o+=t&1:t<*m|m==n?m=p:9)t=*p=abs(*p);t=o<w?o:w;o-=t;w-=t;t+=o/3;for(o%3?o%3-2?t?t--,w+=2:++*m:w++:9;t--;)r*=3;for(r<<=w;--p>n;)r*=*p;printf("%d",r>1?r:o);}

선형 시간 문제에 대해 지수 시간 솔루션 만 보는 것이 재미 있었지만 실제로 알고리즘을 갖는 보너스 포인트가 없기 때문에 논리적으로 진행하는 방법이라고 생각합니다.

음수를 양수로 변환하고 0을 버린 후에는 분명히 곱셈에 관심이 있습니다. 최종 숫자의 로그를 최대화하려고합니다.

a = 1 또는 b = 1 인 경우를 제외하고 log (a + b) <log (a) + log (b)이므로, 함께 추가하는 것이 유일한 경우입니다. 일반적으로 1을 더 작은 수에 더하는 것이 좋습니다. 큰 수에 1을 더하는 것보다 로그에 더 큰 증가, 즉 더 큰 백분율 증가를 야기하기 때문입니다. 가장 바람직하지 않은 순서로 시나리오를 활용하기위한 네 가지 시나리오가 있습니다.

  1. 1을 2에 더하면 + log .405가 나타납니다. [log (3)-log (2)]
  2. 1을 3으로 결합하면 1 당 + log .366이됩니다. [log (3) / 3]
  3. 1을 2로 만들면 1 당 + log .347이됩니다. [log (2) / 2]
  4. 3 이상에 1을 더하면 + log .288 이하가됩니다. [log (4)-log (3)]

프로그램은 1의 수, 2의 수 및 2보다 큰 최소 수를 추적하고 그 중 하나를 사용하는 가장 바람직하지 않은 방법의 목록으로 내려갑니다. 마지막으로 나머지 모든 숫자를 곱합니다.


6

하스켈, 126 자

이것은 입력의 부호를 무시하고 빼기와 단항 부정을 무시하는 것을 제외하고는 무차별 강제입니다.

import Data.List
f[x]=abs x::Int
f l=maximum$subsequences l\\[[],l]>>= \p->[f p+f(l\\p),f p*f(l\\p)]
main=interact$show.f.read

이 코드는 매우 느립니다. 코드는 입력의 각 서브 시퀀스에 대해 4 번 반복적으로 f를 계산합니다 ([] 및 입력 자체는 제외) . 근데 코드 골프 야


5

SWI- 프롤로그-250

오 소년, 나는 이것에 너무 오래 보냈다.

o(A,B,A+B).
o(A,B,A-B).
o(A,B,A*B).
t([],0).
t([A,B|T],D):-t(T,Q),o(A,B,C),o(C,Q,D).
t([A|T],C):-t(T,Q),o(A,Q,C).
a(A):-t(A,B),n(C),B>C,retract(n(C)),assert(n(B)).
m(A):-assert(n(0)),\+p(A),n(R),R2 is R,write(R2).
p(A):-permutation([0|A],B),a(B),0=1.

명령 줄에서 호출 (예 :)

> swipl -s filename.pl -g "m([1, 1, 1, 1, 1])" -t halt
6

(특별한 이유없이, 골프 기능 이름의 철자가 "토마토 냄비"라는 것이 놀랍습니다.)

언 골프 버전 :

% Possible operations
operation(Left, Right, Left + Right).
operation(Left, Right, Left - Right).
operation(Left, Right, Left * Right).

% Possible ways to transform
transform([], 0).
transform([A, B|T], D) :- transform(T, Q), operation(A, B, C), operation(C, Q, D).
transform([A|T], C) :- transform(T, Q), operation(A, Q, C).

% Throw the given array through every possible transformation and update the max
all_transforms(A) :- transform(A, B), n(C), B>C, retract(n(C)), assert(n(B)).

% Find all the permutations and transformations, then fail and continue execution.
prog(A) :- assert(n(0)), !, permutation([0|A], B), all_transforms(B), fail.

% End the program
finished :- n(R), write(R), nl, R2 is R, write(R2), nl.

% Run the program
main(A) :- ignore(prog(A)), finished.

설명:

  1. 배열을 인수로 사용하십시오.
  2. 배열의 모든 순열을 가져옵니다.
  3. 배열에 추가 할 연산자 배열을 찾으십시오. (이것은 동적 프로그래밍을 통해 이루어지며 처음 두 요소를 결합하면 더 나은지 여부를 알 수 있습니다.)
  4. 현재 최대 값과 비교하여 확인하십시오. 더 좋은 경우 교체하십시오.
  5. 우리가 검사를 계속 너무 실패 프로그램에게, 그러나 (사용하여 해당 부정 ignore또는 \+술어 전체 수익을 수 있도록) true계속.
  6. 숫자 대신 술어 문자열이 제공되므로이를 사용하여 할당 is한 다음 쓰십시오.

4

스칼라, 134

print(args.map(Math abs _.toInt)./:(Seq(Array(0)))((l,a)=>l.map(a+:_)++l.flatMap(_.permutations.map{r=>r(0)+=a;r}))map(_.product)max)

언 골프 및 댓글 :

print(
  args
    .map(Math abs _.toInt)                     // to int, ignoring -
    .foldLeft(Seq(Array(0))){ (list,num) =>    // build up a list of sums of numbers
      list.map(num+:_) ++                      // either add the new number to the list
      list.flatMap(_.permutations.map{ copy =>
        copy(0)+=num                           // or add it to one of the elements
        copy
      })
    }
    .map(_.product) // take the maximum of the the products-of-sums
    .max
)

가장 큰 답은 항상 합계의 곱으로 표현 될 수 있다는 사실을 깨닫는 것과는 약간 다른 접근 방식입니다.

너무 가깝지만 라이브러리 어리 석음 (순열은 Seq 대신 Iterator를 반환하고 빈 시퀀스에 대한 끔찍한 유형 유추, Array.update returning Unit)을 사용했습니다.


3

파이썬 278 (O (n!))

from itertools import*
def f(n):
 f,n,m=lambda n:[(n,)]+[(x,)+y for x in range(1,n)for y in f(n-x)],map(abs,map(int,n.split())),0
 for p,j in product(permutations(n),f(len(n))):
  i=iter(p)
  m=max(m,reduce(lambda e,p:e*p,(sum(zip(*zip([0]*e,i))[1])for e in j)))
 return m

설명

  1. 단항 Negate는 모든 음수를 양수로 변환하는 데 신중하게 사용해야합니다.
  2. 숫자의 가능한 모든 순열을 구합니다
  3. 정수 파티션을 사용하여 주어진 순열의 모든 전력 세트 찾기
  4. 합계의 곱을 구합니다
  5. 합계의 곱의 최대 값을 반환

3

하스켈 - 295 290 265 246 203 189 182 바이트


마침내 작동합니다! 또한 이제는 동적 솔루션이 아닌 무차별 대입입니다.


일부 골프 팁에 대해 proudhaskeller에게 감사합니다.

이것은 실제로 골프를 먹기 때문에 완전히 골프 솔루션이 아니지만 아마도 내가 얻을 수있는 최선입니다 (그리고 복잡해 보이므로 나에게 도움이됩니다).

import Data.List
main=interact$show.g.read
g x=maximum[product$a#b|a<-sequence$replicate(length x-1)[0,1],b<-permutations x]
(a:b)#(c:d:e)|a>0=b#(c+d:e)|0<1=c:b#(d:e)
_#x=x

새로운 테스트 사례 :

[1,1,1,2,2]
12

[1,1,3,3,3]
54

[1,1,1,1,1,1,1,1,5,3]
270

솔루션 설명 :

main함수는 입력을 받아 실행 g합니다.

g 입력을 취하고 가능한 모든 합계 및 목록 순서 조합의 최대 값을 반환합니다.

# 다음과 같이 목록의 합계를 계산하는 함수입니다.

a = [1,0,0,1]
b = [1,1,1,2,2]
a#b = [2,1,4]

이것은 성능 중심 솔루션처럼 보입니다.
자랑스런 Haskeller

;가능할 때 대신 줄 바꿈을 작성해 주 시겠습니까? 그것은 바이트 수를 변경하지 않지만 가독성을 엄청나게 도와줍니다
자랑스러운 Haskeller

@proudhaskeller 나는 이것을 무차별 대입하는 방법을 전혀 몰랐다. 그래서 나는 다른 것을 생각해 내야했다. D
ThreeFx

골프에 대한 나의 조언-1) 한 번만 사용되는 모든 기능을 인라인합니다 (패턴 일치 또는 가드를 사용하지 않는 한). 2) d n=[0,2,1]!!n또는으로 d를 구현할 수 있습니다 d n=mod(3-n)3. 3) 확인 o하고 g그들은 단지 길이에 따라대로 (분명이)가 인라인되지 않는 한 오직 한 의미, 목록 자체를 복용하는 대신리스트의 길이를 취할. 4) 교체 otherwise와 함께 0<1. 5) r의 마지막 정의를로 만드십시오 r$o x:y. 6)를 제거하고 a@로 교체하십시오 x:y. 골프와 함께 행운을 빕니다!
자랑스런 Haskeller

알고리즘이 [3,3,3,2,2,2,1,1,1]에 대해 잘못된 답변을 제공합니다. 코드를 실행했으며 216을 반환했습니다 (내가 얻을 수 있었던 가장 큰 결과는 729였습니다).
Brilliand

1

GolfScript (52 자)

~]0-{abs}%.1-.1,or@,@,-,-1%{!\$.0=3<@+{()}1if+}/{*}*

온라인 데모

feersum의 분석 은 꽤 좋지만 목표가 효율성이 아니라 골프라면 더 나아갈 수 있습니다. 의사 코드에서 :

filter zeros from input and replace negatives with their absolute value
filter ones to get A[]
count the ones removed to get C
while (C > 0) {
    sort A
    if (A[0] < 3 || C == 1) A[0]++
    else A.append(1)
    C--
}
fold a multiply over A
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.