Prodotto scalare minimo


16

Prodotto scalare minimo

L'ispirazione per questo problema di golf del codice è dalla competizione di code jam di Google . La premessa alla base del problema è, dato l'ingresso di due vettori di varia lunghezza, trovare il minimo scalare possibile. Uno scalare può essere trovato usando la seguente formula:

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

Il problema, tuttavia, è che è possibile trovare più valori per lo scalare in base all'ordine dei numeri nel caso di input (visto di seguito). Il tuo obiettivo è determinare la soluzione intera scalare minima possibile inserendo i numeri del caso di input nell'equazione e risolvendola. È possibile utilizzare ogni numero nell'input solo una volta e è necessario utilizzare tutti i numeri.

Mi permetta di fornire un esempio con i seguenti vettori.

Ingresso

3
1 3 -5
-2 4 1

Produzione

-25

Il primo numero intero sulla riga rappresenta il numero di numeri, n, in ciascun vettore. In questo caso, abbiamo tre numeri in ciascun vettore.

Il numero n può variare con ogni caso di test, ma ci saranno sempre due vettori.

Nell'input di esempio, il prodotto scalare minimo sarebbe -25.

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

Regole

  • È possibile utilizzare ogni numero intero in entrambi i vettori una sola volta.
  • È necessario utilizzare tutti i numeri interi nei vettori.
  • L'output deve includere solo il prodotto finale
  • Selezionerò la soluzione con la minima quantità di codice, che segue tutte le specifiche sopra elencate, in qualsiasi lingua!

Suggerimento: non è necessario forzare bruscamente questo problema, a meno che non riduca il codice. Esiste un metodo specifico per trovare lo scalare minimo spanning :).


Non voglio davvero rovinare nessuno, quindi non aprirlo se non conosci già la risposta. questo è così noto che è divertente. en.m.wikipedia.org/wiki/Rearrangement_inequality
orgoglioso haskeller

Risposte:


8

Gelatina, 6 byte

ṢṚ×Ṣ}S

Provalo online!

L'uso della forza bruta è altrettanto breve:

Œ!×S€Ṃ

Come funziona

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


5

APL, 15 byte

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

Questa è una funzione diadica che accetta array a sinistra e a destra e restituisce un numero intero. Utilizza lo stesso approccio della mia risposta Julia : punto prodotto degli array ordinati, uno discendente e uno ascendente.

Provalo qui


5

MATL , 6 byte

Codice:

SiSP*s

La mia prima risposta MATL :)

Spiegazione:

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

Provalo online!


1
Sono contento di vederlo! :-)
Luis Mendo,

4

Mathematica, 30 17 byte

-13 byte per murphy

Sort@#.-Sort@-#2&

Funzione, input è vector1 (elenco), vector2 (elenco) Diverse revisioni:

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

soluzione intelligente!
baseman101

2
Sort@#.Reverse@Sort@#2&
alephalpha

Sort@#.Sort[#2,#>#2&]&
Murphy

1
Sort@#.-Sort@-#2&
Murphy

O per la tua soluzione 1,Sort@#.SortBy[#2,-#&]
CalculatorFeline


2

Julia, 32 25 byte

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

Questa è una funzione anonima che accetta due array e restituisce un numero intero. Per chiamarlo, assegnalo a una variabile ed eseguif(x)(y) .

Per gli ingressi x e y , semplicemente calcola il prodotto scalare di x ordinati in ordine inverso con y ordinati. Otteniamo x in ordine inverso negando tutti i valori, ordinando, quindi negando di nuovo.

Risparmiato 7 byte grazie a Dennis!


2

Javascript ES6, 69 byte

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

Wow, è troppo lungo.


Penso che provare a riutilizzare la funzione di ordinamento ti stia costando 3 byte.
Neil,

Ho fatto più golf. Meglio?
Mama Fun Roll

Probabilmente puoi salvare un byte con |iinvece di&&i
ETHproductions

Thx @ETHproductions
Mama Fun Roll

Sì, è quello a cui stavo pensando.
Neil,



1

Python, 139 byte

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

1
È possibile salvare alcuni byte rimuovendo gli spazi accanto a uguale, ad esempio b = sorted(b)si trasforma in b=sorted(b)(2 byte salvati). Puoi inoltre inserire più istruzioni sulla stessa riga separandole con un punto e virgola, ad esempioa=list(reversed(sorted(a)));b=sorted(b);res=0
charredgrass

@charredgrass Sono nuovo qui. Qual è la necessità di salvare ogni possibile byte? Stavo cercando di renderlo leggibile.
ribellione del

Benvenuto in PPCG allora! Questa domanda è una competizione di code-golf in cui l'obiettivo è quello di scrivere il codice per completare la sfida nel minor numero di byte possibile, il che di solito significa meno codice leggibile.
charredgrass,

@charredgrass ha capito!
ribellione del

2
Molto più breve: lambda a,b,s=sorted:sum(x*y for x,y in zip(s(a)[::-1],s(b))). Non abbiamo bisogno di nominare gli invii di funzioni (quindi un lambda senza nome è valido) e il nparametro non è necessario (molti altri invii lo omettono del tutto).
Mego,

1

C ++, 124 byte

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

Inizialmente ho usato std::greater<int>()l'ordinamento, bma è più semplice invertire l'ordine nella somma.


1

Haskell, 59 byte

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

0

INVIO , 29 byte

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

Try it here.

Sostituisci qualsiasi ␆␃␄␇ con le loro controparti non stampabili.

Lambda anonimo che lascia il risultato su stack2. Uso:

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

Spiegazione

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

0

J, 14 byte

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

Utilizza lo stesso principio degli altri.

Spiegazione

+/@(*|.)&(/:~)  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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.