Produto Concatenado Máximo

11

Nos é dada uma lista de números inteiros p1, ..., pk (não necessariamente distintos) em que cada um tem um valor entre 1 e 9, inclusive. Usando cada um dos p1, ..., pk exatamente uma vez, podemos formar concatenações de dígitos, para obter uma nova lista de números; Em seguida, produzimos o produto desta nova lista. O objetivo é maximizar este produto escolhendo as melhores concatenações de dígitos.

Por exemplo, recebemos a lista: 2 3 2 (separados por espaços). Podemos formar as seguintes concatenações:

  • 2 3 2(o produto dessas concatenações é 12)
  • 23 2(o produto é 46)
  • 32 2(o produto é 64)
  • 22 3(o produto é 66)

Como o maior produto que podemos formar de concatenações é 66, produzimos isso.

Regras:

  • Deve haver pelo menos uma multiplicação (ou seja, você não pode simplesmente concatenar todos os dígitos e produzir isso).
  • Você não pode usar outros operadores além da multiplicação ou inserir parênteses etc.
  • Suponha que a lista de números inteiros fornecida seja separada por espaços e que todos os números inteiros tenham valores entre 1 e 9.

O código mais curto (em bytes) vence!

Casos de teste:

Entrada: 1 2 3; Saída: 63(ie, 21*3)

Entrada: 2 5 9; Saída: 468( 52*9)

Entrada: 1 2 3 4; Saída: 1312( 41*32)

Ryan
fonte
Devemos escrever um programa ou uma função inteira, recebendo parâmetros de entrada e retornando o resultado também é bom?
Aleatório # 10/05
@ randomra Sim, tudo bem.
Ryan
Para cada par de números a, b, o produto a * b. é menor que a concatenação simples ab (= a * 10 ^ (dígitos de b) + b). Portanto, apenas 1 produto (como obrigatório). Adicione isto: codegolf.stackexchange.com/q/49854/21348
edc65 11/05

Respostas:

8

CJam, 32 28 23 12 bytes

0le!f{~*}:e>

Experimente on-line no intérprete CJam .

Obrigado a @ user23013 por me ajudar a salvar 16 bytes inteiros!

Idéia

A permissão dos caracteres na sequência de entrada a divide em números inteiros (grupos de dígitos consecutivos) separados por espaços. Pressionando um zero e avaliando a sequência de entrada permutada, pressionamos dois ou mais números inteiros. Multiplicar os dois primeiros mais resultará no produto da entrada dividido em exatamente dois números inteiros ou em algum valor abaixo do ideal.

Código

 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.
Dennis
fonte
1
l2%_,,1>\e!m*{~S+m<~*}%$W=.
Jimmy23013
2
l2%S+e!{0\~*}%$W=.
Jimmy23013
2

CJam, 36 35 bytes

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

Bem direto. Repete todas as combinações possíveis e as classifica por produto. Em seguida, gera o maior. Tudo isso, lembrando que pelo menos 1 multiplicação deve estar presente.

Adicionará explicação em breve.

Experimente online aqui

Optimizer
fonte
1

JavaScript (ES6) 125

Editar Acho que o @oberon acertou: "cada novo dígito deve ser concatenado com o menor número"

Não vou mudar essa resposta roubando a ideia dele. A implementação no ES6 seria de 70 bytes (o sinal foi alterado em comparação para comparar como número e não cadeias)

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

Minha solução

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

Como eu disse nos comentários, para cada par de números a, b, o produto a * b é menor que a concatenação simples ab (= a * 10 ^ (dígitos de b) + b). Portanto, é melhor evitar produtos e preferir a concatenação, mas como pelo menos um produto é solicitado, precisamos criar 2 números e multiplicá-los.

Eu tento todo o agrupamento de dígitos possível, construindo um par de números para multiplicar. Cada número é obviamente construído com dígitos em ordem decrescente.

Por exemplo, com uma lista de 4 números, [1 2 3 4] - tente:

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

O máximo desses valores é o resultado que precisamos.

Os agrupamentos podem ser enumerados em loop em um bitmap de 4 bits, com o valor mínimo 0001 e o valor máximo 0111 (ou seja, 1 << (4 -1) - 1)

Não é tão jogado

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
}

Teste usando o trecho abaixo no 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>

edc65
fonte
1

Python 3, 111 bytes

Provavelmente é muito mais jogável. Mas eu gosto do tempo de execução (O ( n log n ), não é?).

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

Ungolfed com explicação.

# 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])
Oberon
fonte
0

Pitão, 25 bytes

eSsmm*ss<dkss>dkr1ld.pcz)

Eu faço um loop sobre cada permutação da entrada. Então, como toda combinação ótima consiste em dois números inteiros, apenas a divido em todas as posições possíveis e multiplico as divisões concatenadas. Em seguida, ordeno e obtenho o último elemento.

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

Como método, não tenho certeza se isso é robusto. Nos casos que testei, parece funcionar sempre. Eu tentei testá-lo contra a solução otimizadores e parece estar bem contra isso também. Estou mais do que preparado para provar que estou errado :) Há espaço para jogar golfe, mas eu esperava receber algum feedback sobre o método primeiro.

O processo geral é:

  • Classifique a lista em ordem decrescente
  • Troque o primeiro par ímpar / par que difere
  • Concatene os itens pares e ímpares da lista
  • Avalie o produto dos dois resultados

Expandido com alguns comentários

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

E algumas execuções de teste (implementadas como uma função chamada 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
MickyT
fonte