Minimales Skalarprodukt

16

Minimales Skalarprodukt

Die Inspiration für dieses Code-Golf-Problem ist der Code-Jam-Wettbewerb von Google . Die Prämisse hinter dem Problem ist, bei der Eingabe von zwei Vektoren unterschiedlicher Länge den minimal möglichen Skalar zu finden. Ein Skalar kann mit der folgenden Formel gefunden werden:

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

Das Problem ist jedoch, dass abhängig von der Reihenfolge der Ziffern im Eingabefall (siehe unten) mehrere Werte für den Skalar gefunden werden können. Ihr Ziel ist es, die minimal mögliche skalare Ganzzahllösung zu bestimmen, indem Sie die eingegebenen Fallnummern in die Gleichung einfügen und danach auflösen. Sie dürfen jede Zahl in der Eingabe nur einmal verwenden und müssen alle Zahlen verwenden.

Gestatten Sie mir ein Beispiel mit den folgenden Vektoren.

Eingang

3
1 3 -5
-2 4 1

Ausgabe

-25

Die erste Ganzzahl in der Zeile gibt die Anzahl der Zahlen n in jedem Vektor an. In diesem Fall haben wir drei Zahlen in jedem Vektor.

Die Anzahl n kann mit jedem Testfall variieren, es gibt jedoch immer zwei Vektoren.

In der Beispieleingabe wäre das minimale Skalarprodukt -25.

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

Regeln

  • Sie dürfen jede Ganzzahl in beiden Vektoren nur einmal verwenden.
  • Sie müssen alle Ganzzahlen in den Vektoren verwenden.
  • Ihre Ausgabe darf nur das Endprodukt enthalten
  • Ich wähle die Lösung mit der geringsten Codemenge, die allen oben aufgeführten Spezifikationen entspricht, in einer beliebigen Sprache aus!

Tipp: Sie müssen dieses Problem nicht brutal erzwingen, es sei denn, Ihr Code wird dadurch kürzer. Es gibt eine spezielle Methode, um den minimalen überspannenden Skalar zu finden :).

baseman101
quelle
Ich möchte wirklich niemanden verderben, also öffne das nicht, es sei denn, du kennst die Antwort bereits. Das ist so bekannt, dass es lustig ist. en.m.wikipedia.org/wiki/Rearrangement_inequality
stolzer Haskeller

Antworten:

8

Gelee, 6 Bytes

ṢṚ×Ṣ}S

Probieren Sie es online!

Brute Force ist ebenso kurz:

Œ!×S€Ṃ

Wie es funktioniert

ṢṚ×Ṣ}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
quelle
6

Im Ernst , 6 Bytes

,SR,S*

Probieren Sie es online!

Erläuterung:

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

APL, 15 Bytes

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

Dies ist eine dyadische Funktion, die Arrays links und rechts akzeptiert und eine Ganzzahl zurückgibt. Es verwendet den gleichen Ansatz wie meine Julia- Antwort : Punktprodukt der sortierten Arrays, eines absteigend und eines aufsteigend.

Probieren Sie es hier aus

Alex A.
quelle
5

MATL , 6 Bytes

Code:

SiSP*s

Meine erste Antwort auf MATL :)

Erläuterung:

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

Probieren Sie es online!

Adnan
quelle
1
Ich bin froh das zu sehen! :-)
Luis Mendo
4

Mathematica, 30 17 Bytes

-13 Bytes von Murphy

Sort@#.-Sort@-#2&

Funktion, Eingabe ist vector1 (Liste), vector2 (Liste) Mehrere Revisionen:

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
quelle
clevere lösung!
baseman101
2
Sort@#.Reverse@Sort@#2&
Alephalpha
Sort@#.Sort[#2,#>#2&]&
Murphy
1
Sort@#.-Sort@-#2&
Murphy
Oder für Ihre Lösung 1,Sort@#.SortBy[#2,-#&]
CalculatorFeline
2

Julia, 32 25 Bytes

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

Dies ist eine anonyme Funktion, die zwei Arrays akzeptiert und eine Ganzzahl zurückgibt. Um es aufzurufen, weisen Sie es einer Variablen zu und machen f(x)(y).

Für die Eingaben x und y berechnen wir einfach das Skalarprodukt von x in umgekehrter Reihenfolge mit y sortiert. Wir erhalten x in umgekehrter Reihenfolge, indem wir alle Werte negieren, sortieren und dann erneut negieren.

7 Bytes gespart dank Dennis!

Alex A.
quelle
2

Javascript ES6, 69 Bytes

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

Wow, das ist viel zu lang.

Mama Fun Roll
quelle
Ich denke, der Versuch, die Sortierfunktion wiederzuverwenden, kostet Sie 3 Byte.
Neil
Ich habe mehr Golf gespielt. Besser?
Mama Fun Roll
Sie können wahrscheinlich ein Byte mit |ianstelle von&&i
ETHproductions
Thx @ETHproductions
Mama Fun Roll
Ja, daran habe ich gedacht.
Neil
2

Perl 6, 33 30 Bytes

{sum @^a.sort Z*@^b.sort.reverse}
Hotkeys
quelle
Warum nicht{sum @^a.sort Z*[R,] @^b.sort}((1,3,-5),(-2,4,1)).say
Aleks-Daniel Jakimenko-A.
1

Python, 139 Bytes

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
quelle
1
Sie können ein paar Bytes speichern, indem Sie Leerzeichen neben Gleichheitszeichen entfernen, z. B. b = sorted(b)wird zu b=sorted(b)(2 Bytes gespeichert). Sie können auch mehrere Anweisungen in dieselbe Zeile setzen, indem Sie sie beispielsweise durch ein Semikolon a=list(reversed(sorted(a)));b=sorted(b);res=0
trennen
@charredgrass Ich bin neu hier. Was ist die Notwendigkeit, jedes mögliche Byte zu speichern? Ich habe versucht, es lesbar zu machen.
Rebelliard
Willkommen bei PPCG! Diese Frage ist ein Code-Golf- Wettbewerb, bei dem das Ziel darin besteht, Code zu schreiben, um die Herausforderung in möglichst wenigen Bytes abzuschließen, was normalerweise weniger lesbaren Code bedeutet.
Charredgrass
@charredgrass hat es verstanden!
Rebelliard
2
Viel kürzer: lambda a,b,s=sorted:sum(x*y for x,y in zip(s(a)[::-1],s(b))). Es ist nicht erforderlich, dass Funktionsübermittlungen benannt werden (daher ist ein unbenanntes Lambda gültig), und der nParameter ist nicht erforderlich (viele andere Übermittlungen lassen ihn vollständig aus).
Mego
1

C ++, 124 Bytes

#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;}

ungolfed:

#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;
}

Zuerst habe ich std::greater<int>()für die Sortierung verwendet, baber es ist einfacher, die Reihenfolge in der Summe umzukehren.

Karl Napf
quelle
1

Haskell, 59 Bytes

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

RETURN , 29 Bytes

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

Try it here.

Ersetzen Sie alle ␆␃␄␇ durch ihre nicht druckbaren Gegenstücke.

Anonymes Lambda, das das Ergebnis auf stack2 verlässt. Verwendung:

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

Erläuterung

[                                 ]  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
quelle
0

J, 14 Bytes

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

Verwendet das gleiche Prinzip wie die anderen.

Erläuterung

+/@(*|.)&(/:~)  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
Meilen
quelle