最大連結製品


11

整数p1、...、pkのリストが提供されます(必ずしも個別ではありません)。それぞれの値は1から9までの値です。p1、...、pkをそれぞれ1回だけ使用して、数字の連結を形成し、新しい数字のリストを作成できます。次に、この新しいリストの積を出力します。目標は、数字の最適な連結を選択することにより、この製品を最大化することです。

たとえば、リスト2 3 2(スペースで区切られた)が与えられます。次の連結を形成できます。

  • 2 3 2(これらの連結の積は12
  • 23 2(製品は46
  • 32 2(製品は64
  • 22 3(製品は66

連結を形成できる最大の製品は66なので、出力します。

ルール:

  • 少なくとも1つの乗算が必要です(つまり、すべての桁を連結して出力​​することはできません)。
  • 乗算以外の演算子を使用したり、括弧を挿入したりすることはできません。
  • 指定された整数のリストはスペースで区切られ、すべての整数の値は1〜9であると仮定します。

最短コード(バイト単位)が勝ちます!

テストケース:

入力:1 2 3; 出力:(63つまり、21*3

入力:2 5 9; 出力:46852*9

入力:1 2 3 4; 出力:131241*32


入力パラメーターを取り、結果を返すプログラム全体または関数を作成する必要がありますか?
-randomra

@randomraはい、大丈夫です。
ライアン

数値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インタプリタでオンラインで試してください。

@ user23013に16バイトを節約してくれてありがとう!

考え

入力文字列の文字を並べ替えると、スペースで区切られた整数(連続した数字のグループ)に分割されます。ゼロをプッシュしてから、置換された入力文字列を評価することにより、2つ以上の整数をプッシュします。最上位の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

JavaScript(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

Python 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)

入力のすべての順列をループします。次に、すべての最適な組み合わせは2つの整数で構成されているため、可能なすべての位置でそれを分割し、連結された分割を乗算します。次に、最後の要素をソートして取得します。


0

R、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='')))}

方法として、これが堅牢かどうかはわかりません。私がテストしたケースでは、毎回動作するようです。オプティマイザーソリューションに対してテストしてみましたが、それに対しても問題ないようです。私は間違っていることを証明する準備ができています:)ゴルフの余地はありますが、最初にこの方法に関するフィードバックをもらいたいと思っていました。

一般的なプロセスは次のとおりです。

  • リストを降順に並べ替える
  • 異なる最初の奇数/偶数ペアを交換します
  • リストの偶数と奇数のアイテムを連結します
  • 2つの結果の積を評価する

いくつかのコメントで展開

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.