Produit scalaire minimum

16

Produit scalaire minimum

L'inspiration pour ce problème de golf de code vient de la compétition de jam de code de Google . La prémisse derrière le problème est, étant donné l'entrée de deux vecteurs de longueurs variables, de trouver le scalaire minimum possible. Un scalaire peut être trouvé en utilisant la formule suivante:

x1 * y1 + x2 * y2 + ... + xn * yn

Le problème, cependant, est que plusieurs valeurs pour le scalaire peuvent être trouvées en fonction de l'ordre des chiffres dans le cas d'entrée (voir ci-dessous). Votre objectif est de déterminer la solution d'entier scalaire minimale possible en branchant les nombres de cas d'entrée dans l'équation et en les résolvant. Vous ne pouvez utiliser chaque numéro de l'entrée qu'une seule fois et devez utiliser tous les numéros.

Permettez-moi de fournir un exemple avec les vecteurs suivants.

Contribution

3
1 3 -5
-2 4 1

Production

-25

Le premier entier de la ligne représente le nombre de nombres, n, dans chaque vecteur. Dans ce cas, nous avons trois nombres dans chaque vecteur.

Le nombre n peut varier avec chaque cas de test, mais il y aura toujours deux vecteurs.

Dans l'exemple d'entrée, le produit scalaire minimum serait -25.

(-5 * 4) + (1 * 1) + (3 * -2) = 25

Règles

  • Vous ne pouvez utiliser chaque entier dans les deux vecteurs qu'une seule fois.
  • Vous devez utiliser tous les entiers dans les vecteurs.
  • Votre sortie ne doit inclure que le produit final
  • Je vais sélectionner la solution avec le moins de code, qui suit toutes les spécifications énumérées ci-dessus, dans n'importe quelle langue!

Astuce: vous n'avez pas besoin de forcer brutalement ce problème, sauf s'il raccourcit votre code. Il existe une méthode spécifique impliquée dans la recherche du scalaire couvrant minimum :).

baseman101
la source
Je ne veux vraiment gâcher personne, alors n'ouvrez pas cela à moins que vous ne connaissiez déjà la réponse. c'est tellement connu que c'est drôle. en.m.wikipedia.org/wiki/Rearrangement_inequality
fier haskeller

Réponses:

8

Gelée, 6 octets

ṢṚ×Ṣ}S

Essayez-le en ligne!

L'utilisation de la force brute est également courte:

Œ!×S€Ṃ

Comment ça fonctionne

ṢṚ×Ṣ}S  Main link. Arguments: u (vector), v (vector)

Ṣ       Sort the components of u.
 Ṛ      Reverse.
   Ṣ}   Sort the components of v.
  ×     Multiply the results, element by element.
     S  Compute the sum of the products.
Dennis
la source
6

Sérieusement , 6 octets

,SR,S*

Essayez-le en ligne!

Explication:

,SR,S*
,SR     input first vector, sort, reverse
   ,S   input second vector, sort
     *  dot product
Mego
la source
5

APL, 15 octets

{+/⍺[⍒⍺]×⍵[⍋⍵]}

Il s'agit d'une fonction dyadique qui accepte les tableaux à gauche et à droite et renvoie un entier. Il utilise la même approche que ma réponse Julia : produit scalaire des tableaux triés, un descendant et un ascendant.

Essayez-le ici

Alex A.
la source
5

MATL , 6 octets

Code:

SiSP*s

Ma première réponse MATL :)

Explication:

S       # Sort the first array
 iS     # Take the second array and sort it
   P    # Flip the array
    *   # Multiply both arrays with each other
     s  # Sum of the result

Essayez-le en ligne!

Adnan
la source
1
Je suis content de voir ça! :-)
Luis Mendo
4

Mathematica, 30 17 octets

-13 octets par murphy

Sort@#.-Sort@-#2&

Fonction, l'entrée est vector1 (liste), vector2 (liste) Plusieurs révisions:

Plus@@(Sort@#*Reverse@Sort@#2)&(*me*)
Total[Sort@#*Reverse@Sort@#2]& 
Sort@#.Reverse@Sort@#2&        (*alephalpha*)
Sort@#.Sort[#2,#>#2&]&         (*murphy*)
Sort@#.SortBy[#2,-#&]          (*me*)
Sort@#.-Sort@-#2&              (*murphy*)
CalculatorFeline
la source
solution intelligente!
baseman101
2
Sort@#.Reverse@Sort@#2&
alephalpha
Sort@#.Sort[#2,#>#2&]&
murphy
1
Sort@#.-Sort@-#2&
murphy
Ou pour votre solution 1,Sort@#.SortBy[#2,-#&]
CalculatorFeline
2

Pyth - 14 8 octets

Je pense que j'ai compris l'astuce.

s*VSQ_SE

Essayez-le en ligne ici .

Maltysen
la source
2

Julia, 32 25 octets

x->y->-sort(-x)⋅sort(y)

Il s'agit d'une fonction anonyme qui accepte deux tableaux et renvoie un entier. Pour l'appeler, affectez-le à une variable et faitesf(x)(y) .

Pour les entrées x et y , nous calculons simplement le produit scalaire de x trié dans l'ordre inverse avec y trié. Nous obtenons x dans l'ordre de tri inverse en annulant toutes les valeurs, en triant, puis en annulant à nouveau.

7 octets enregistrés grâce à Dennis!

Alex A.
la source
2

Javascript ES6, 69 octets

a=>b=>a.sort((x,y)=>x-y).map((x,y)=>i+=b.sort((x,y)=>y-x)[y]*x,i=0)|i

Wow, c'est beaucoup trop long.

Mama Fun Roll
la source
Je pense qu'essayer de réutiliser la fonction de tri vous coûte 3 octets.
Neil
J'ai fait plus de golf. Mieux?
Mama Fun Roll
Vous pouvez probablement enregistrer un octet avec |iau lieu de&&i
ETHproductions
Thx @ETHproductions
Mama Fun Roll
Oui, c'est à ça que je pensais.
Neil
2

Perl 6, 33 30 octets

{sum @^a.sort Z*@^b.sort.reverse}
Raccourcis clavier
la source
Pourquoi pas{sum @^a.sort Z*[R,] @^b.sort}((1,3,-5),(-2,4,1)).say
Aleks-Daniel Jakimenko-A.
1

Python, 139 octets

def mdp(n, a, b):
    a = list(reversed(sorted(a)))
    b = sorted(b)
    res = sum([a[i] * b[i] for i in range(len(a))])
    return res
rebelliard
la source
1
Vous pouvez enregistrer quelques octets en supprimant les espaces à côté de égaux, par exemple b = sorted(b)se transforme en b=sorted(b)(2 octets enregistrés). Vous pouvez également mettre plusieurs instructions sur la même ligne en les séparant par un point-virgule, par exemplea=list(reversed(sorted(a)));b=sorted(b);res=0
charredgrass
@charredgrass Je suis nouveau ici. Quelle est la nécessité de sauvegarder chaque octet possible? J'essayais de le rendre lisible.
rebelliard
Bienvenue chez PPCG alors! Cette question est une compétition de golf de code où le but est d'écrire du code pour relever le défi dans le moins d'octets possible, ce qui signifie généralement un code moins lisible.
charredgrass
@charredgrass l'a compris!
rebelliard
2
Beaucoup plus courte: lambda a,b,s=sorted:sum(x*y for x,y in zip(s(a)[::-1],s(b))). Nous n'exigeons pas que les soumissions de fonctions soient nommées (donc un lambda sans nom est valide), et le nparamètre est inutile (de nombreuses autres soumissions l'omettent complètement).
Mego
1

C ++, 124 octets

#include<algorithm>
int m(int*a,int*b,int n){std::sort(a,a+n);std::sort(b,b+n);int r=0;while(--n>=0)r+=a[n]**b++;return r;}

non golfé:

#include<algorithm>
int m(int*a,int*b,int n){
 std::sort(a,a+n);
 std::sort(b,b+n);
 int r=0;
 while(--n>=0)
  r+=a[n]*(*b++);
return r;
}

Au début, j'ai utilisé std::greater<int>()pour le tri, bmais simplement inverser l'ordre dans la somme est plus facile.

Karl Napf
la source
1

Haskell, 59 octets

import Data.List
v?u=sum$zipWith(*)(sort v)$reverse$sort u
Zeta
la source
0

RETOUR , 29 octets

[{␆␃}\{␆}␄␅[¤¥][×␌]#}␁[¤][+]#]

Try it here.

Remplacez-les ␆␃␄␇par leurs homologues non imprimables.

Lambda anonyme qui laisse le résultat sur stack2. Usage:

""{1 3 0 5-}""{0 2- 4 1}[{␆␃}\{␆}␄␅[¤¥][×␌]#}␁[¤][+]#]!

Explication

[                                 ]  lambda
 {␆␃}                              sort and reverse first stack
       \{␆}                         sort second stack
            ␄␅                     transpose and flatten
               [  ][  ]#             while loop
                ¤¥                     check if 2 items exist in stack
                    ×                  if so, multiply top 2 items
                     ␌                 and push to stack2
                        }␁          switch to stack2
                           [¤][+]#   sum stack2
Mama Fun Roll
la source
0

J, 14 octets

+/@(*|.)&(/:~)

Utilise le même principe que les autres.

Explication

+/@(*|.)&(/:~)  Input: x on LHS and y on RHS
        &(/:~)  Sort both x and y
     |.         Reverse the sorted y
    *           Multiply the sorted x and reversed sorted y elementwise
+/@             Reduce the products using addition and return
miles
la source