最大串联产品


11

给出了一个整数列表p1,...,pk(不一定是不同的),其中每个值的范围都在1到9之间(含1和9)。仅使用一次每个p1,...,pk,我们就可以形成数字的级联,以获得一个新的数字列表;然后,我们输出此新列表的产品。目的是通过选择最佳的数字级联来最大化此乘积。

例如,我们得到以下列表:2 3 2(用空格分隔)。我们可以形成以下串联:

  • 2 3 2(这些串联的乘积是12
  • 23 2(商品是46
  • 32 2(商品是64
  • 22 3(商品是66

因为我们可以形成的最大乘积是66,所以我们将其输出。

规则:

  • 必须至少有一个乘法(即,您不能只连接所有数字并输出)。
  • 除乘法或插入括号等外,不能使用任何其他运算符。
  • 假定给定的整数列表由空格分隔,并且所有整数的值都在1到9之间。

最短的代码(以字节为单位)获胜!

测试用例:

输入:1 2 3; 输出:(6321*3

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

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


我们应该编写一个带有输入参数并返回结果的完整程序还是一个函数呢?
randomra'5

@randomra是的,很好。
瑞安

对于每对数字a,b,乘积a * b。小于简单串联ab(= a * 10 ^(b的数字)+ b)。所以只有1个产品(这是强制性的)。添加此代码:codegolf.stackexchange.com/q/49854/21348
edc65

Answers:


8

CJam,32 28 23 12个字节

0le!f{~*}:e>

CJam解释器中在线尝试。

感谢@ user23013帮助我节省了16个字节!

理念

对输入字符串中的字符进行置换可将其分为整数(连续数字组),并用空格分隔。通过推零然后评估排列的输入字符串,我们推两个或多个整数。将最高的两个值相乘将导致输入的乘积被精确地分为两个整数或某个次优值。

 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

这些值的最大值是我们需要的结果。

可以在4位的位图上枚举循环,最小值为0001,最大值为0111(即1 <<(4 -1)-1)

不太打高尔夫球

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)

我遍历输入的每个排列。然后,因为每个最佳组合都由两个整数组成,所以我只在每个可能的位置对其进行分割,然后将串联的分割相乘。然后,我进行排序并获取最后一个元素。


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

作为一种方法,我不确定这是否可靠。对于我测试过的情况,它似乎每次都起作用。我尝试针对优化程序解决方案进行测试,并且针对该解决方案似乎也可以。我非常愿意证明自己是错误的:)有打高尔夫球的空间,但是我希望首先从使用方法上获得一些反馈。

一般过程是:

  • 按降序对列表进行排序
  • 交换不同的第一个奇/偶对
  • 连接列表的偶数和奇数项
  • 评估两个结果的乘积

扩展了一些评论

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.