Minimalna iloczyn skalarny

16

Minimalna iloczyn skalarny

Inspiracją do rozwiązania tego problemu z golfem jest konkurs Google jam jam . Założeniem problemu jest, biorąc pod uwagę wejście dwóch wektorów o różnej długości, znalezienie minimalnego możliwego skalara. Skalar można znaleźć za pomocą następującej formuły:

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

Problem polega jednak na tym, że można znaleźć wiele wartości skalara w zależności od kolejności cyfr w przypadku wprowadzania (patrz poniżej). Twoim celem jest ustalenie minimalnego możliwego skalarnego rozwiązania liczb całkowitych poprzez podłączenie liczb przypadków wejściowych do równania i ich rozwiązanie. Możesz użyć każdej liczby na wejściu tylko raz i musisz użyć wszystkich liczb.

Pozwólcie, że podam przykład z następującymi wektorami.

Wejście

3
1 3 -5
-2 4 1

Wynik

-25

Pierwsza liczba całkowita w linii reprezentuje liczbę liczb, n, w każdym wektorze. W tym przypadku mamy trzy liczby w każdym wektorze.

Liczba n może się różnić w każdym przypadku testowym, ale zawsze będą dwa wektory.

W przykładowym danych wejściowych minimalny iloczyn skalarny wynosiłby -25.

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

Zasady

  • Możesz użyć tylko jednej liczby całkowitej w obu wektorach.
  • Musisz użyć wszystkich liczb całkowitych w wektorach.
  • Twój wynik musi zawierać tylko produkt końcowy
  • Wybiorę rozwiązanie z najmniejszą ilością kodu, zgodną ze wszystkimi powyższymi specyfikacjami, w dowolnym języku!

Wskazówka: nie musisz brutalnie wymuszać tego problemu, chyba że spowoduje to skrócenie kodu. W znalezieniu minimalnego skalara obejmującego jest określona metoda :).

baseman101
źródło
Naprawdę nie chcę zepsuć nikomu, więc nie otwieraj tego, chyba że znasz już odpowiedź. to jest tak dobrze znane, że jest zabawne. en.m.wikipedia.org/wiki/Rearrangement_inequality
dumny haskeller

Odpowiedzi:

8

Galaretka, 6 bajtów

ṢṚ×Ṣ}S

Wypróbuj online!

Używanie brutalnej siły jest równie krótkie:

Œ!×S€Ṃ

Jak to działa

ṢṚ×Ṣ}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
źródło
6

Poważnie , 6 bajtów

,SR,S*

Wypróbuj online!

Wyjaśnienie:

,SR,S*
,SR     input first vector, sort, reverse
   ,S   input second vector, sort
     *  dot product
Mego
źródło
5

APL, 15 bajtów

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

Jest to funkcja dynamiczna, która akceptuje tablice po lewej i prawej stronie i zwraca liczbę całkowitą. Wykorzystuje to samo podejście, co moja odpowiedź Julii : iloczyn iloczynu posortowanych tablic, jednego malejącego i jednego rosnącego.

Wypróbuj tutaj

Alex A.
źródło
5

MATL , 6 bajtów

Kod:

SiSP*s

Moja pierwsza odpowiedź MATL :)

Wyjaśnienie:

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

Wypróbuj online!

Adnan
źródło
1
Cieszę się, że to widzę! :-)
Luis Mendo,
4

Mathematica, 30 17 bajtów

-13 bajtów przez murphy

Sort@#.-Sort@-#2&

Funkcja, dane wejściowe to wektor1 (lista), wektor2 (lista) Kilka wersji:

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
źródło
sprytne rozwiązanie!
baseman101
2
Sort@#.Reverse@Sort@#2&
alephalpha
Sort@#.Sort[#2,#>#2&]&
murphy
1
Sort@#.-Sort@-#2&
murphy
Lub dla twojego rozwiązania 1,Sort@#.SortBy[#2,-#&]
CalculatorFeline
2

Pyth - 14 8 bajtów

Myślę, że wymyśliłem sztuczkę.

s*VSQ_SE

Wypróbuj online tutaj .

Maltysen
źródło
2

Julia, 32 25 bajtów

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

Jest to anonimowa funkcja, która akceptuje dwie tablice i zwraca liczbę całkowitą. Aby go wywołać, przypisz go do zmiennej i zrób f(x)(y).

Do wejścia x i y , po prostu obliczać iloczyn skalarny x sortowane w kolejności odwrotnej do z y sortowane. Otrzymujemy x w odwrotnej kolejności, negując wszystkie wartości, sortując, a następnie ponownie negując.

Zaoszczędzono 7 bajtów dzięki Dennisowi!

Alex A.
źródło
2

JavaScript ES6, 69 bajtów

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

Wow, to za długo.

Mama Fun Roll
źródło
Myślę, że próba ponownego użycia funkcji sortowania kosztuje 3 bajty.
Neil
Uprawiałem więcej golfa. Lepszy?
Mama Fun Roll
Prawdopodobnie możesz zaoszczędzić bajt |izamiast&&i
ETHproductions
Dzięki @ETHproductions
Mama Fun Roll
Tak, właśnie o tym myślałem.
Neil,
2

Perl 6, 33 30 bajtów

{sum @^a.sort Z*@^b.sort.reverse}
Skróty klawiszowe
źródło
Dlaczego nie{sum @^a.sort Z*[R,] @^b.sort}((1,3,-5),(-2,4,1)).say
Aleks-Daniel Jakimenko-A.
1

Python, 139 bajtów

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
rebeliant
źródło
1
Możesz zapisać kilka bajtów, usuwając spacje obok równości, na przykład b = sorted(b)zamienia się b=sorted(b)(2 bajty zapisane). Możesz dodatkowo umieścić wiele instrukcji w tym samym wierszu, oddzielając je średnikiem, na przykłada=list(reversed(sorted(a)));b=sorted(b);res=0
charredgrass,
@charredgrass Jestem tu nowy. Jaka jest potrzeba, aby zapisać każdy możliwy bajt? Starałem się, aby było to czytelne.
rebeliant
Witamy zatem w PPCG! To pytanie jest konkursem golfa , w którym celem jest napisanie kodu, aby ukończyć wyzwanie w jak najmniejszej liczbie bajtów, co zwykle oznacza mniej czytelny kod.
charredgrass
@charredgrass ma to!
rebeliancki
2
Znacznie krótszy: lambda a,b,s=sorted:sum(x*y for x,y in zip(s(a)[::-1],s(b))). Nie wymagamy nazywania funkcji przed nazwami (więc poprawna jest nienazwana lambda), a nparametr jest niepotrzebny (wiele innych funkcji całkowicie go pomija).
Mego
1

C ++, 124 bajty

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

bez golfa:

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

Na początku używałem std::greater<int>()sortowania, bale po prostu odwrócenie kolejności w podsumowaniu jest łatwiejsze.

Karl Napf
źródło
1

Haskell, 59 bajtów

import Data.List
v?u=sum$zipWith(*)(sort v)$reverse$sort u
Zeta
źródło
0

ZWROT , 29 bajtów

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

Try it here.

Wymień dowolny ␆␃␄␇ ich niedrukowalne odpowiedniki.

Anonimowa lambda, która pozostawia wynik na stosie2. Stosowanie:

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

Wyjaśnienie

[                                 ]  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
źródło
0

J, 14 bajtów

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

Stosuje tę samą zasadę, co pozostałe.

Wyjaśnienie

+/@(*|.)&(/:~)  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
mile
źródło