Produit concaténé maximum

11

On nous donne une liste d'entiers p1, ..., pk (pas nécessairement distincts) où chacun a une valeur comprise entre 1 et 9 inclus. En utilisant chacun des p1, ..., pk exactement une fois, nous pouvons former des concaténations de chiffres, pour obtenir une nouvelle liste de nombres; nous sortons ensuite le produit de cette nouvelle liste. L'objectif est de maximiser ce produit en choisissant les meilleures concaténations de chiffres.

Par exemple, on nous donne la liste: 2 3 2 (séparés par des espaces). Nous pouvons former les enchaînements suivants:

  • 2 3 2(le produit de ces concaténations est 12)
  • 23 2(le produit est 46)
  • 32 2(le produit est 64)
  • 22 3(le produit est 66)

Puisque le plus grand produit que nous pouvons former des concaténations est 66, nous le sortons.

Règles:

  • Il doit y avoir au moins une multiplication (c'est-à-dire que vous ne pouvez pas simplement concaténer tous les chiffres et les afficher).
  • Vous ne pouvez pas utiliser d'autres opérateurs que la multiplication, ni insérer des parenthèses, etc.
  • Supposons que la liste des entiers donnée est séparée par des espaces et que tous les entiers ont des valeurs comprises entre 1 et 9.

Le code le plus court (en octets) gagne!

Cas de test:

Entrée: 1 2 3; Sortie: 63(c.-à-d. 21*3)

Entrée: 2 5 9; Sortie: 468( 52*9)

Entrée: 1 2 3 4; Sortie: 1312( 41*32)

Ryan
la source
Devrions-nous écrire un programme entier ou une fonction en prenant des paramètres d'entrée et renvoyer le résultat est également très bien?
randomra
@randomra Oui, ça va.
Ryan
Pour chaque paire de nombres a, b, le produit a * b. Est inférieur à la concaténation simple ab (= a * 10 ^ (chiffres de b) + b). Donc juste 1 produit (car c'est obligatoire). Ajoutez ceci: codegolf.stackexchange.com/q/49854/21348
edc65

Réponses:

8

CJam, 32 28 23 12 octets

0le!f{~*}:e>

Essayez-le en ligne dans l' interpréteur CJam .

Merci à @ user23013 de m'avoir aidé à économiser 16 octets entiers!

Idée

Permutation des caractères dans la chaîne d'entrée le divise en entiers (groupes de chiffres consécutifs) séparés par des espaces. En poussant un zéro puis en évaluant la chaîne d'entrée permutée, nous poussons deux ou plusieurs entiers. En multipliant les deux premiers, le produit de l'entrée sera divisé en deux entiers exactement ou en une valeur sous-optimale.

Code

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

CJam, 36 35 octets

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

Assez simple. Itère toutes les combinaisons possibles et les trie par produit. Sort ensuite le plus grand. Tout cela, en gardant à l'esprit qu'au moins 1 multiplication doit être présente.

Ajoutera bientôt une explication.

Essayez-le en ligne ici

Optimiseur
la source
1

JavaScript (ES6) 125

Edit Je pense que @oberon a bien compris: "chaque nouveau chiffre doit être concaténé au plus petit nombre"

Je ne changerai pas cette réponse en volant son idée. L'implémentation dans ES6 serait de 70 octets (le signe a changé par rapport à la comparaison sous forme de nombre et non de chaînes)

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

Ma solution

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

Comme je l'ai dit dans les commentaires, pour chaque paire de nombres a, b, le produit a * b est inférieur à la concaténation simple ab (= a * 10 ^ (chiffres de b) + b). Il vaut donc mieux éviter les produits et préférer la concaténation, mais comme au moins 1 produit est demandé, nous devons construire 2 nombres et les multiplier.

J'essaie tous les regroupements possibles de chiffres, construisant une paire de chiffres à multiplier. Chaque numéro est construit de manière évidente en prenant des chiffres dans l'ordre décroissant.

Par exemple, avec une liste de 4 nombres, [1 2 3 4] - essayez:

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

Le maximum de ces valeurs est le résultat dont nous avons besoin.

Les regroupements peuvent être énumérés en boucle sur un bitmap de 4 bits, avec la valeur min 0001 et la valeur max 0111 (soit 1 << (4 -1) - 1)

Pas si golfé

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
}

Testez en utilisant l'extrait de code ci-dessous dans 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
la source
1

Python 3, 111 octets

C'est probablement beaucoup plus golfable. J'aime son temps d'exécution, cependant (O ( n log n ), n'est-ce pas?).

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

Non golfé avec explication.

# 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
la source
0

Pyth, 25 octets

eSsmm*ss<dkss>dkr1ld.pcz)

Je boucle sur chaque permutation de l'entrée. Ensuite, parce que chaque combinaison optimale se compose de deux nombres entiers, je la divise simplement à chaque position possible et multiplie les divisions concaténées. Je trie et récupère ensuite le dernier élément.

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

En tant que méthode, je ne sais pas si cela est robuste. Avec les cas que j'ai testés, cela semble fonctionner à chaque fois. J'ai essayé de le tester contre une solution d'optimiseurs et cela semble être correct contre cela également. Je suis plus que prêt à me tromper :) Il y a de la place pour le golf, mais j'espérais d'abord obtenir des commentaires sur la méthode.

Le processus général est le suivant:

  • Trier la liste par ordre décroissant
  • Échangez la première paire paire / paire différente
  • Concaténer les éléments pairs et impairs de la liste
  • Évaluer le produit des deux résultats

Développé avec quelques commentaires

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

Et quelques tests (implémentés comme une fonction appelée 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
la source