최대 연결 제품


11

각각 1과 9 사이의 값을 갖는 정수 p1, ..., pk (반드시 구별되는 것은 아님)의 목록이 제공됩니다. p1, ..., pk 각각을 정확히 한 번만 사용하면 숫자의 연결을 형성하여 새로운 숫자 목록을 얻을 수 있습니다. 그런 다음이 새 목록의 제품을 출력합니다. 목표는 최상의 숫자 연결을 선택하여이 제품을 최대화하는 것입니다.

예를 들어, 2 3 2 (공백으로 구분) 목록이 제공됩니다. 다음과 같은 연결을 구성 할 수 있습니다.

  • 2 3 2(이러한 연결의 제품은 12)
  • 23 2(상품은 46)
  • 32 2(상품은 64)
  • 22 3(상품은 66)

연결을 구성 할 수있는 가장 큰 제품은 66이므로 출력합니다.

규칙 :

  • 최소한 하나의 곱셈이 있어야합니다 (즉, 모든 숫자를 연결하여 출력 할 수는 없습니다).
  • 곱셈 이외의 다른 연산자를 사용하거나 괄호를 삽입 할 수 없습니다.
  • 주어진 정수 목록이 공백으로 구분되고 모든 정수의 값이 1과 9 사이라고 가정하십시오.

가장 짧은 코드 (바이트)가 이깁니다!

테스트 사례 :

입력 : 1 2 3; 출력 : 63(즉, 21*3)

입력 : 2 5 9; 출력 : 468( 52*9)

입력 : 1 2 3 4; 출력 : 1312( 41*32)


입력 매개 변수를 사용하고 결과를 반환해도 전체 프로그램이나 함수를 작성해야합니까?
randomra

@randomra 네, 괜찮습니다.
Ryan

각 숫자 쌍 a, b에 대해 곱 a * b.는 단순 연결 ab보다 작습니다 (= a * 10 ^ (b의 자리수) + b). 따라서 1 개의 제품 만 필수입니다. 이것을 추가하십시오 : codegolf.stackexchange.com/q/49854/21348
edc65

답변:


8

CJam, 32 28 23 12 바이트

0le!f{~*}:e>

CJam 통역사 에서 온라인으로 사용해보십시오 .

16 바이트 전체를 절약 할 수있게 해준 @ user23013에게 감사드립니다!

생각

입력 문자열에서 문자를 치환하면 공백으로 구분 된 정수 (연속 자릿수 그룹)로 나눕니다. 0을 누른 다음 순열 된 입력 문자열을 평가하여 두 개 이상의 정수를 푸시합니다. 최상위 2를 곱하면 입력 곱이 정확히 2 개의 정수로 나눠 지거나 일부 최적이 아닌 값이됩니다.

암호

 le!         e# Push all possible character permutations of the input.
0   f{  }    e# For each permutation:
             e#   Push 0, then the permuted string.
      ~      e#   Evaluate the string. Pushes one or more integers.
       *     e#   Multiply the two topmost integers.
         :e> e# Retrieve the greatest integer in the array.

1
l2%_,,1>\e!m*{~S+m<~*}%$W=.
jimmy23013

2
l2%S+e!{0\~*}%$W=.
jimmy23013

2

CJam, 36 35 바이트

q~]_,([SL]m*{s},\e!\m*{z[s~]:*}%$W=

꽤 직설적 인. 가능한 모든 조합을 반복하고 제품별로 정렬합니다. 그런 다음 가장 큰 출력합니다. 이 모든 것은 적어도 1 곱셈이 있어야 함을 명심하십시오.

곧 설명을 추가 할 것입니다.

여기에서 온라인으로 사용해보십시오


1

자바 스크립트 (ES6) 125

편집 @oberon이 올바른 것으로 생각합니다. "각각의 새로운 숫자는 가장 작은 숫자로 연결되어야합니다."

나는 그의 아이디어를 훔치는이 답변을 바꾸지 않을 것이다. ES6의 구현은 70 바이트입니다 (문자열이 아닌 숫자로 비교하기 위해 부호가 변경됨)

f=l=>l.split(' ').sort().reverse().map(d=>-a>-b?a+=d:b+=d,a=b='')||a*b

내 솔루션

f=l=>(i=>{for(r=0;a=b='',k=--i;r<a*b?r=a*b:0)for(v of l)k&1?a+=v:b+=v,k/=2})(1<<~-(l=l.split(' ').sort().reverse()).length)|r

주석에서 언급했듯이, 각 숫자 쌍 a, b에 대해 곱 a * b는 단순 연결 ab보다 작습니다 (= a * 10 ^ (b의 자리수) + b). 따라서 제품을 피하고 연결을 선호하는 것이 더 좋지만 적어도 1 개의 제품이 요청되면 2 개의 숫자를 만들어 곱해야합니다.

가능한 모든 숫자 그룹을 시도하여 곱할 숫자 쌍을 만듭니다. 각 숫자는 분명히 숫자를 내림차순으로 작성합니다.

예를 들어, 4 개의 숫자 목록이있는 [1 2 3 4]-다음을 시도하십시오.

  • 4 * 321
  • 43 * 21
  • 42 * 31
  • 41 * 32
  • 432 * 1
  • 431 * 2
  • 421 * 3

이 값의 최대 값은 필요한 결과입니다.

그룹화는 최소값 0001 및 최대 값 0111 (즉, 1 << (4-1)-1) 인 4 비트의 비트 맵에서 루핑을 열거 할 수 있습니다.

그렇게 골프되지 않은

f=l=>{
  l = l.split(' '); // string to array
  l.sort().reverse(); // decreasing order 
  m = 1 << (l.length-1); starting value fro loop
  r = 0 
  // loop from m-1 down to 1
  for(i=m; --i; )
  {
    a = b = '';
    k = i;
    for(v of l) // divide the digits base on bits of i
    {
      k & 1 ? a+=v : b+=v;
      k /= 2;
    }
    if (r < a*b) r = a*b; // remember max value in r
  }
  return r
}

Firefox에서 아래 스 니펫을 사용하여 테스트하십시오.

f=l=>(i=>{for(r=0;a=b='',k=--i;r<a*b?r=a*b:0)for(v of l)k&1?a+=v:b+=v,k/=2})(1<<~-(l=l.split(' ').sort().reverse()).length)|r

t=l=>(i=>{for(x=r='';a=b='',k=--i;r<a*b?(r=a*b,x=' = '+a+'x'+b):0)for(v of l)k&1?a+=v:b+=v,k/=2})
(1<<~-(l=l.split(' ').sort().reverse()).length)|| x

function go()
{
  R.value = f(I.value) // TEST AS IS
   + t(I.value) // Some more info
}

test=['1 2 3 4','1 2 3','2 5 9','8 9 8']

test.forEach(t => O.innerHTML = O.innerHTML + (t + ' -> ' + f(t)) + '\n')
Type your list: <input id=I><button onclick='go()'>-></button><input readonly id=R><br>
<pre id=O></pre>


1

파이썬 3, 111 바이트

아마 훨씬 더 골프입니다. 그래도 실행 시간이 마음에 듭니다 (O ( n log n )입니까?).

l=sorted(map(int,input().split()),reverse=1);m=[0,0]
for x in l:i=m[0]>m[1];m[i]=m[i]*10+x
print(m[0]*m[1])

설명이 담겨 있지 않습니다.

# edc65 has already explained that the optimal solution can be found applying a single
# multiplication. thus, given that
#     (10x + d)y > (10y + d)x
# where x, y are the two numbers and d is the next digit to insert, it follows that
#     y > x
# and thus each new digit must be concatenated to the smallest number. obviously, digits
# should be added in descending order.
l = sorted(map(int, input().split()), reverse=1)
m = [0,0]
for x in l:
    i = m[0] > m[1]
    m[i] = m[i]*10 + x
print(m[0] * m[1])

0

Pyth, 25 바이트

eSsmm*ss<dkss>dkr1ld.pcz)

입력의 모든 순열을 반복합니다. 그런 다음 모든 최적의 조합은 두 개의 정수로 구성되므로 가능한 모든 위치에서 분할하고 연결된 분할을 곱합니다. 그런 다음 마지막 요소를 정렬하고 가져옵니다.


0

제 164 화

function(n){l=length(n);a=sort(n,T);i=1;while(a[i]==a[i+1]&&i<l-2)i=i+2;a[c(i,i+1)]=a[c(i+1,i)];eval(parse(t=paste0(c(a[1:l%%2==1],"*",a[1:l%%2==0]),collapse='')))}

방법으로 이것이 강력한 지 확실하지 않습니다. 내가 테스트 한 경우 매번 작동하는 것처럼 보입니다. 나는 최적화 솔루션에 대해 테스트를 시도했지만 그것에 대해서도 괜찮은 것처럼 보입니다. 나는 틀린 것으로 증명 될 준비가되어있다. :) 골프를 할 여지가 있지만, 그 방법에 대한 피드백을 먼저 받기를 바랐다.

일반적인 과정은 다음과 같습니다.

  • 내림차순으로 목록 정렬
  • 첫 번째 홀수 / 짝수 쌍을 바꾸십시오
  • 목록의 짝수 및 홀수 항목 연결
  • 두 결과의 곱을 평가

일부 의견으로 확대

function(n){
    l=length(n);
    a=sort(n,T);    # sort descending order
    # Determine which pair to swap
    i=1;
    while(a[i]==a[i+1]&&i<l-2)i=i+2;
    a[c(i,i+1)]=a[c(i+1,i)];  # swap pair   
    # concatenate the even and odd indices items around a * and evaluate    
    eval(parse(t=paste0(c(a[1:l%%2==1],"*",a[1:l%%2==0]),collapse=''))) 
}

그리고 일부 테스트 실행 (g라는 함수로 구현 됨)

> g(c(1,2,3))
[1] 63
> g(c(2,5,9))
[1] 468
> g(c(1,2,3,4))
[1] 1312
> g(c(1,2,3,5,5,5))
[1] 293132
> g(c(1,5,7,7,9,9))
[1] 946725
> g(c(1,7,8,9,9,9))
[1] 978117
> g(c(7,8,9,9,9))  #Test case provided edc65 to randomra
[1] 97713
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.