Trova il prodotto punto di Rationals


31

Ero a casa di un amico per cena e mi hanno suggerito l'idea di uno "spazio vettoriale primo fattore". In questo spazio interi positivi sono espressi come vettore tale che l' n -esimo elemento del vettore è il numero di volte che il n ° divide primi il numero. (Nota che questo significa che i nostri vettori hanno un numero infinito di termini.) Ad esempio 20 è

2 0 1 0 0 0 ...

Perché la sua scomposizione in fattori primi è 2 * 2 * 5 .

Poiché la scomposizione in fattori primi è unica, ogni numero corrisponde a un vettore.

Siamo in grado di aggiungere vettori aggiungendo a coppie le loro voci. Ciò equivale a moltiplicare i numeri a cui sono associati. Possiamo anche fare una moltiplicazione scalare, che è simile all'aumento del numero associato ad una potenza.

Il problema è che questo spazio non è in realtà uno spazio vettoriale perché non ci sono inversioni. Se andiamo avanti, aggiungiamo gli inversi e chiudiamo lo spazio vettoriale, ora abbiamo un modo per esprimere ogni numero razionale positivo come vettore. Se manteniamo il fatto che l'aggiunta vettoriale rappresenta la moltiplicazione. Quindi l'inverso di un numero naturale è reciproco.

Ad esempio il numero 20 aveva il vettore

2 0 1 0 0 0 ...

Quindi la frazione 1/20 è il suo inverso

-2 0 -1 0 0 0 ...

Se volessimo trovare il vettore associato a una frazione come 14/15 , ne troveremmo 14

1 0 0 1 0 0 ...

e 1/15

0 -1 -1 0 0 0 ...

e moltiplicarli eseguendo l'aggiunta vettoriale

1 -1 -1 1 0 0 ...

Ora che abbiamo uno spazio vettoriale, possiamo modificarlo per formare uno spazio prodotto interno dandogli un prodotto interno. Per fare ciò rubiamo il prodotto interno che gli spazi vettoriali sono dati in modo classico. Il prodotto interno di due vettori è definito come la somma della moltiplicazione a coppie dei loro termini. Ad esempio 20 · 14/15 verrebbe calcolato come segue

20    =  2  0  1  0  0  0 ...
14/15 =  1 -1 -1  1  0  0 ...
         2  0 -1  0  0  0 ...  -> 1

Come altro esempio il prodotto 2/19 · 4/19

2/19 = 1 0 0 0 0 0 0 -1 0 0 0 ...
4/19 = 2 0 0 0 0 0 0 -1 0 0 0 ...
       2 0 0 0 0 0 0  1 0 0 0 ... -> 3

Il tuo compito è quello di implementare un programma che esegue questo prodotto punto. Dovrebbe prendere due numeri razionali positivi tramite una coppia di numeri interi positivi (numeratore e denominatore) o un tipo razionale (i float non sono consentiti, perché causano problemi di precisione e divisibilità) e dovrebbero generare un numero intero che rappresenta il punto prodotto dei due ingressi.

Si tratta di quindi le risposte verranno classificate in byte con un numero inferiore di byte migliori.

Casi test

4 · 4 = 4
8 · 8 = 9
10 · 10 = 2
12 · 12 = 5
4 · 1/4 = -4
20 · 14/15 = 1
2/19 · 4/19 = 3

Un vettore non ha una dimensione, uno spazio vettoriale ha.
Jonathan Frech,

5
@JonathanFrech Penso che sia un po 'pedante, ma ho apportato la modifica.
Wheat Wizard

I "numeri naturali" sono generalmente considerati contenere 0, che non è rappresentato nel tuo sistema. E questi non sono vettori. Uno spazio vettoriale è su un campo e questo è su un anello, il che renderebbe questo un modulo. E non è uno spazio separato dagli interi, è lo stesso spazio con una rappresentazione diversa.
Accumulo

6
@Accumulazione "Numeri naturali" non è un termine ben definito, a seconda di chi lo chiedi può contenere o meno zero. Hai ragione nel dire che la "moltiplicazione scalare" nella mia domanda forma un G-set con un monoide piuttosto che un gruppo, ma che è stato semplificato allo scopo di rendere appetibile la domanda. Non sono sicuro di cosa fare del tuo ultimo commento, certo che abbia la stessa cardinalità degli interi, ma l'azione è davvero ciò che definisce uno spazio, non la sua dimensione. Forse intendi qualcosa di più specifico che mi manca. Se è così sarei felice di continuare questa discussione (in chat potrebbe essere la cosa migliore).
Wheat Wizard

2
Un'altra terminologia nit-pick: gli spazi vettoriali sono generalmente richiesti per avere una moltiplicazione scalare da un campo, quindi usare solo numeri interi non è sufficiente. Questo perché vogliamo che i vettori paralleli siano multipli l'uno dell'altro, non solo con un multiplo in comune. Ad esempio, $ 4 $ e $ 8 $ sono "vettori" paralleli in questo spazio (sono entrambi della forma (a, 0, 0, ...)), ma nessuno dei due è un multiplo scalare (ovvero una potenza intera) del altro. Non ci sono molti altri termini che potresti usare, tuttavia, che sarebbero conosciuti dalle persone in generale. "Modulo libero sugli interi" è il massimo che posso fare.
Arthur,

Risposte:


4

MATL , 12 byte

YF2:&Y)dwd*s

L'input è un array [num1 den1 num2 den2].

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

Considera un esempio di input [20 1 14 15].

YF      % Implicit input: array of 4 numbers. Exponents of prime factorization.
        % Gives a matrix, where each row corresponds to one of the numbers in
        % the input array. Each row may contain zeros for non-present factors
        % STACK: [2 0 1 0
                  0 0 0 0
                  1 0 0 1
                  0 1 1 0]
2:&Y)   % Push a submatrix with the first two rows, then a submatrix with the
        % other two rows
        % STACK: [2 0 1 0
                  0 0 0 0],
                 [1 0 0 1
                  0 1 1 0]
d       % Consecutive difference(s) along each column
        % STACK: [2 0 1 0
                  0 0 0 0],
                 [-1 1 -1 1]
wd      % Swap, and do the same for the other submatrix
        % STACK: [-1 1 -1 1]
                 [-2 0 -1 0]
*       % Element-wise product
        % STACK: [2 0 -1 0]
s       % Sum. Implicit display
        % STACK: 1

4

C (gcc) , 99 + 32 = 131 byte

  • Utilizzando una bandiera compilatore richiede 32 byte, -D=F(v,V,e)for(;v%p<1;V+=e)v/=p;.
T,p,A,C;f(a,b,c,d){T=0;for(p=2;a+b+c+d>4;p++){A=C=0;F(a,A,1)F(b,A,~0)F(c,C,1)F(d,C,~0)T+=A*C;}a=T;}

Provalo online!


Penso che sia meglio specificare esplicitamente che -D=F(v,V,e)for(;v%p<1;V+=e)v/=p;viene utilizzato il flag aggiuntivo (32 byte) (quindi 99 + 32 = 131); altrimenti il ​​solo codice ha poco senso.
Gorgogliatore


3

Python 2 , 110 byte

l=input()
p=t=2
while~-max(l):r=i=0;exec"while l[i]%p<1:l[i]/=p;r+=1j**i\ni+=1\n"*4;t+=r*r;p+=1
print t.imag/2

Provalo online!

Accetta input come [num1, num2, den1, den2]. Utilizza un numero complesso rper memorizzare le voci come prime pper i due razionali ed (r*r).imag/2estrarre il loro prodotto r.real*r.imagall'interno della somma complessiva t. Aggiungendo 1j**iper i=0,1,2,3ogni combinazione di incremento o decremento della parte reale o immaginaria per i quattro numeri di input.

Bubbler ha salvato 2 byte combinando i valori iniziali p=t=2.


1
p=t=2invece di p=2;t=0as t.realviene ignorato comunque ( TIO ).
Gorgogliatore

@Bubbler Bello, aggiungendo!
xnor


1

JavaScript (Node.js) , 104 ... 100 94 byte

F=(A,i=2)=>A.some(x=>x>1)&&([a,b,c,d]=A.map(G=(x,j)=>x%i?0:1+G(A[j]/=i,j)),a-b)*(c-d)+F(A,i+1)

Provalo online!

Passa i numeri come una matrice di [Num1, Den1, Num2, Den2].

Grazie per Arnauld per aver risolto il problema F=senza byte extra e 2 byte in più in meno.

Spiegazione e non golfato

function F(A, i = 2) {                 // Main function, recursing from i = 2
 if (A.some(function(x) {              // If not all numbers became 1:
  return x > 1;
 })) {
  var B = A.map(G = function(x, j) {   // A recursion to calculate the multiplicity
   if (x % i)
    return 0;
   else
    return 1 + G(A[j] /= i, j);        // ...and strip off all powers of i
  });
  return (B[0] - B[1]) * (B[2] - B[3]) // Product at i
   + F(A, i + 1);                      // Proceed to next factor. All composite factors 
 }                                     // will be skipped effectively
 else 
  return 0;                            // Implied in the short-circuit &&
}

1

J , 19 byte

1#.*/@,:&([:-/_&q:)

Provalo online!

Spiegazione:

Un verbo diadico, gli argomenti sono sia a sinistra che a destra

         &(        ) - for both arguments (which are lists of 2 integers)
               _&q:  - decompose each number to a list of prime exponents
           [:-/      - and find the difference of these lists
       ,:            - laminate the resulting lists for both args (to have the same length)
   */@               - multiply them
1#.                  - add up 

1

Stax , 11 byte

ä÷ß½♂←√:=Ü]

Esegui ed esegui il debug

La corrispondente rappresentazione ASCII dello stesso programma è questa.

{|nmMFE-~-,*+

Fondamentalmente, ottiene gli esponenti della scomposizione in fattori primi per ogni parte. Prende la differenza di ogni coppia, quindi del prodotto e infine somma tutti i risultati.


1

Python 2 , 133 127 byte

a=input();s=0;p=2;P=lambda n,i=0:n%p and(n,i)or P(n/p,i+1)
while~-max(a):a,(w,x,y,z)=zip(*map(P,a));s+=(w-x)*(y-z);p+=1
print s

Provalo online!

Ha rubato la condizione del loop dall'invio di xnor .

Grazie per il consiglio di @mathmandan di modificare la funzione in un programma (Sì, in effetti ha salvato alcuni byte).

Soluzione obsoleta, errata (124 byte):

lambda w,x,y,z:sum((P(w,p)-P(x,p))*(P(y,p)-P(z,p))for p in[2]+range(3,w+x+y+z,2))
P=lambda n,p,i=1:n%p and i or P(n/p,p,i+1)

Non ptesterà valori non primi come 9?
xnor

Oops, lo riparerò presto.
Bubbler,

3
Puoi sostituirlo returncon print, e puoi anche salvare gli spazi di rientro se scrivi come programma invece che come funzione.
Mathmandan,

@mathmandan Grazie per le informazioni. Sembra utile per gli altri miei invii Py2, non sono sicuro per Py3 (ci vuole extra a eval()meno che l'input della funzione stessa non sia una stringa).
Gorgogliatore

1

Haskell , 153 byte

(2%)
n%m|all(<2)m=0|(k,[a,b,c,d])<-unzip[(,)=<<div x.max 1.(n*)$until((>0).mod x.(n^))(+1)1-1|x<-m]=(a-b)*(c-d)+[i|i<-[n..],all((>0).rem i)[2..i-1]]!!1%k

Provalo online! Esempio di utilizzo per 20 · 14/15: (2%) [20,1,14,15].

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.