Il volume di un numero intero


31

È risaputo che ogni numero intero non negativo può essere riscritto come la somma di quattro numeri quadrati. Ad esempio il numero 1 può essere espresso come 02+02+02+12 . O, in generale, per qualsiasi numero intero non negativo n , esistono numeri interi a,b,c,d tali che

n=a2+b2+c2+d2

Joseph-Louis Lagrange lo dimostrò nel 1700 e quindi viene spesso chiamato Teorema di Lagrange .

Questo è talvolta discusso in relazione ai quaternioni - un tipo di numero scoperto da William Hamilton nel 1800, rappresentato come

w+xi+yj+zk
dove w,x,y,z sono numeri reali, e i,j e k sono unità immaginarie distinte che non si moltiplicano commutativamente. In particolare, viene discusso in relazione alla quadratura di ciascun componente del quaternione
w2+x2+y2+z2
Questa quantità è talvolta chiamatanorma, o norma quadrata, o anchequadranza. Alcunedimostrazioni modernedel teorema di Lagrange usano i quaternioni.

Rudolf Lipschitz studiò i quaternioni con solo componenti interi, chiamati quaternioni di Lipschitz. Usando il quadrante, possiamo immaginare che ogni quaternione di Lipschitz possa pensare di avere un amico negli interi. Ad esempio quaternione 0+0i+0j+1k può essere considerato come associato all'intero 1=02+02+02+12 . Inoltre, se torniamo indietro, si può pensare che ogni numero intero abbia un amico nei quaternioni di Lipschitz.

Ma c'è un dettaglio interessante del teorema di Lagrange: la sommatoria non è unica. Ogni numero intero può avere diversi set di quattro quadrati che possono essere sommati per crearlo. Ad esempio, il numero 1 può essere espresso in 4 modi usando numeri interi non negativi (consideriamo solo i non negativi per questa sfida):

1=02+02+02+12
1=02+02+12+02
1=02+12+02+02
1=12+02+02+02

I riepiloghi sono sempre quadrati di 0 o 1, ma possono trovarsi in posizioni diverse nell'espressione.

Per questa sfida, cerchiamo anche di "ordinare" le nostre somme dal più basso al più alto, per eliminare i duplicati, in modo da poter considerare, per questo esercizio, che 1 ha un solo modo di essere rappresentato come la somma di quattro quadrati:

1=02+02+02+12

Un altro esempio è il numero 42, che può essere espresso in quattro modi (di nuovo, considerando solo a, b, c, d non negativi ed eliminando le disposizioni dei componenti duplicati)

42=02+12+42+52
42=12+12+22+62
42=12+32+42+42
42=22+22+32+52

E se immaginiamo che ognuno di questi diversi modi di esprimere un numero intero sia associato a un quaternione specifico? Quindi potremmo dire che il numero 42 è associato a questi quattro quaternioni:

0+1i+4j+5k
1+1i+2j+6k
1+3i+4j+4k
2+2i+3j+5k

Se immaginiamo l'interpretazione standard della computer grafica di un quaternione, dove , e sono vettori nello spazio euclideo tridimensionale , e quindi i componenti , e del quaternione sono coordinate cartesiane tridimensionali , quindi possiamo immaginare che ogni numero intero, attraverso questo processo di pensiero, possa essere associato a un insieme di coordinate tridimensionali nello spazio. Ad esempio, il numero 42 è associato alle seguenti quattro coordinate :ijkxyz(x,y,z)

(1,4,5),(1,2,6),(3,4,4),(2,3,5)

Questo può essere pensato come una nuvola di punti o un insieme di punti nello spazio. Ora, una cosa interessante di un insieme di punti finiti nello spazio è che puoi sempre disegnare un riquadro di delimitazione minimo attorno a loro - un riquadro abbastanza grande da contenere tutti i punti, ma non più grande. Se immagini il riquadro come un normale riquadro allineato con gli assi , viene chiamato riquadro di delimitazione allineato agli assi . Il rettangolo di selezione ha anche un volume, calcolabile determinandone larghezza, lunghezza e altezza e moltiplicandoli insieme.x,y,z

Possiamo quindi immaginare il volume di un rettangolo di selezione per i punti formati dai nostri quaternioni. Per l'intero 1, abbiamo, usando i criteri di questo esercizio, un quaternione il cui quadrante è 1, . Questa è una nuvola di punti molto semplice, ha solo un punto, quindi il suo riquadro di delimitazione ha volume 0. Per l'intero 42, tuttavia, abbiamo quattro quaternioni e quindi quattro punti, attorno ai quali possiamo disegnare un riquadro di delimitazione. Il punto minimo della casella è e il massimo è risultando in larghezza, lunghezza e altezza di 2, 2 e 2, dando un volume di 8.0+0i+0j+1k(1,2,4)(3,4,6)

Diciamo che per un numero intero , il volume è il volume del riquadro di delimitazione allineato all'asse di tutti i punti 3D formati da quaternioni che hanno un quadrante uguale a , dove i componenti del quaternione sono non negativi e .nnw+xi+yj+zkw<=x<=y<=z

Crea un programma o una funzione che, dato un singolo numero intero non negativo , genererà nvolume di .nn

Esempi:

input -> output
0 -> 0
1 -> 0
31 -> 4
32 -> 0
42 -> 8
137 -> 96
1729 -> 10032

Questo è code-golf, il minor numero di byte vince.


cosa devo aggiungere? intendevo indicare che avrebbe vinto il minor numero di byte
don luminoso

3
Hai dimenticato il tag code-golf, ti ho aiutato ad aggiungerlo
Incarnazione dell'ignoranza

1
Questa è una bella sfida, ma sarebbe anche meglio IMHO se fosse un po 'meno prolisso. Inoltre, fai attenzione ai collegamenti irrilevanti (non sto dicendo che tutti i tuoi collegamenti siano irrilevanti, ma solo alcuni di essi portano davvero informazioni significative per la sfida, mentre gli altri sono solo fonte di distrazione).
Arnauld,

1
Sì, ma perché prendere solo i, j, k come spazio 3D ma non spazio 4D?
TSH

1
@tsh perché i Quaternioni non rappresentano necessariamente uno spazio euclideo a 4 dimensioni. Hamilton li ha scoperti mentre cercava un modo di lavorare con lo spazio tridimensionale. Sarebbe stato possibile fare una versione 4d ma stavo meditando sul loro uso nello spazio 3d quando ho fatto la domanda
don Bright

Risposte:


13

Wolfram Language (Mathematica) , 67 58 byte

Volume@BoundingRegion[Rest/@PowersRepresentations[#,4,2]]&

Provalo online!

                         ...&   Pure function:
PowersRepresentations[#,4,2]    Get the sorted reprs. of # as sums of 4 2nd powers
Rest/@                         Drop the first coordinate of each
BoundingRegion[...]            Find the bounding region, a Cuboid[] or Point[].
                               By default Mathematica finds an axis-aligned cuboid.
Volume                         Find volume; volume of a Point[] is 0.

4
wow, non avevo idea che qualcosa come PowersRepresentations sarebbe stato incorporato in una lingua. in realtà ho pensato di fare una sfida per mostrare i diversi modi di sommare un numero intero come quattro quadrati, ma sono contento di non averlo fatto.
don luminoso

4
Lol, Mathematica ha anche un incorporato per determinare le capre in un'immagine , quindi avere un incorporato per questo davvero non mi sorprende. xD
Kevin Cruijssen,

8

Gelatina , 17 byte

Żœċ4²S⁼ɗƇ⁸ZḊṢ€I§P

Provalo online! (piuttosto lento - rendilo abbastanza veloce per tutti i casi di test con un vantaggio½ )

Come?

Żœċ4²S⁼ɗƇ⁸ZḊṢ€I§P - Link: non-negative integer, n    e.g. 27
Ż                 - zero-range                            [0,1,2,...,27]
   4              - literal four                          4
 œċ               - combinations with replacement         [[0,0,0,0],[0,0,0,1],...,[0,0,0,27],[0,0,1,1],[0,0,1,2],...,[27,27,27,27]]
        Ƈ         - filter keep those for which:          e.g.: [0,1,1,5]
       ɗ          -   last three links as a dyad:
    ²             -     square (vectorises)                     [0,1,1,25]
     S            -     sum                                     27
      ⁼  ⁸        -     equal to? chain's left argument, n      1
                  -                                       -> [[0,1,1,5],[0,3,3,3],[1,1,3,4]]
          Z       - transpose                             [[0,0,1],[1,3,1],[1,3,3],[5,3,4]]
           Ḋ      - dequeue                               [[1,3,1],[1,3,3],[5,3,4]]
            Ṣ€    - sort each                             [[1,1,3],[1,3,3],[3,4,5]]
              I   - incremental differences (vectorises)  [[ 0,2 ],[ 2,0 ],[ 1,1 ]]
               §  - sum each                              [2,2,2]
                P - product                               8

6

Haskell , 132 123 byte

z=zipWith
(!)=foldr1.z
h n=[0..n]
f n|p<-[[c,b,a]|a<-h n,b<-h a,c<-h b,d<-h c,a^2+b^2+c^2+d^2==n]=product$z(-)(max!p)$min!p

Provalo online!

Soluzione piuttosto semplice. Forza bruta tutte le possibili soluzioni ripetendo su tutti i valori da 0 a n (eccessivo, ma più breve). Ho emesso il punto come un elenco in modo da poter usare l' (!)operatore magico di @ Lynn . Tale operatore comprime ogni dimensione con la funzione sul lato sinistro, quindi max!prestituisce un elenco di dimensioni 3 che consiste dei massimi lungo ciascuna dimensione e min!pfa lo stesso per il minimo. Quindi troviamo solo la dimensione minima in ogni dimensione (sottraendo il valore minimo dal massimo con z(-)) e moltiplicandoli insieme.

Grazie mille a @Lynn per il decollo di 9 byte con un po 'di magia con zip pieghevole!


1
Mi sono rasato alcuni byte rinunciando alla trasposizione a favore di una zipWithlogica. 123 byte
Lynn

5

Mazza 0,2, 12 byte

⡌⢎⣟⡊⢘⣚⡏⡨⠍⠁⡇⠨

Utilizzare con Mathematica 11.2 e questa versione di Sledgehammer, che precede la sfida. Vedi la cronologia delle modifiche per una versione che funziona nella versione 0.3, che ha una GUI e genera un'espressione Mathematica.

Questo spinge l'input nello stack e chiama la sequenza di comandi

{intLiteral[4], intLiteral[2], call["PowersRepresentations", 3], call["Thread", 1], call["Rest", 1], call["Thread", 1], call["BoundingRegion", 1], call["Volume", 1]}

che equivale a valutare il seguente codice Wolfram derivato dalla mia risposta in lingua Wolfram :

Volume[BoundingRegion[Thread@Rest@Thread@PowersRepresentations[#, 4, 2]]]&

Provalo online!


questo richiede matematica per testarlo?
don luminoso

@don luminoso Sì, il repository ha istruzioni. È un work in progress, quindi non ancora molto user-friendly. Dopo aver eseguito setup.wls puoi testare con wolframscript o interactive_app.wls.
lirtosiast

2
@Downgoat Sì. Ho in programma di implementare una biblioteca di golf, ma attualmente si decomprime alla semplice Mathematica.
lirtosiast

2
@pipe La versione precedente dovrebbe funzionare (ora che ci penso, il codice è esattamente lo stesso su una versione precedente), ma dovrei scaricarlo ed eseguire nuovamente l'installazione. (Le modifiche da allora hanno principalmente scritto la GUI e il codice di refactoring senza grandi cambiamenti nella funzionalità.) Poiché questa risposta è più breve, sembra importante dimostrare l'idoneità, quindi lo farò domani mattina.
lirtosiast

1
qualcun altro può eseguire questo? vorrei verificare che funzioni prima di dare il vecchio segno di spunta.
don luminoso

4

Python 2 , 138 byte

q=lambda n,x=0,*t:[t]*(n==0)if t[3:]else q(n-x*x,x,x,*t)+q(n,x+1,*t+(0,)*(x>n))
p=1
for l in zip(*q(input()))[:3]:p*=max(l)-min(l)
print p

Provalo online!

Genera ricorsivamente i quaternioni in ordine inverso con la norma data, quindi prende il prodotto tra il massimo e il minimo di tutti i valori possibili nei primi tre indici.

itertools avrebbe potuto sparare se non avesse usato nomi ridicolmente lunghi come itertools.combinations_with_replacement

Python 2 , 161 byte

from itertools import*
n=input();p=1
for l in zip(*[t[1:]for t in combinations_with_replacement(range(n+1),4)if sum(x*x for x in t)==n]):p*=max(l)-min(l)
print p

Provalo online!

Questo è il motivo per cui itertoolsnon è mai la risposta .


3

JavaScript (ES6),  148  143 byte

n=>(r=[[],[],[]]).map(a=>p*=a.length+~a.indexOf(1),(g=(s,k=0,a=[])=>a[3]?s||r.map(r=>r[a.pop()]=p=1):g(s-k*k,k,[...a,++k],k>s||g(s,k,a)))(n))|p

Provalo online!

Commentate

r

r = [ [], [], [] ]

x1x+1yz

1

Passo 1

rg

g = (              // g is a recursive function taking:
  s,               // s   = current sum, initially set to the input n
  k = 0,           // k   = next value to be squared
  a = []           // a[] = list of selected values
) =>               //
  a[3] ?           // if we have 4 values in a[]:
    s ||           //   if s is equal to zero (we've found a valid sum of 4 squares):
      r.map(r =>   //     for each array r[] in r[]:
        r[a.pop()] //       pop the last value from a[]
        = p = 1    //       and set the corresponding value in r[] to 1
                   //       (also initialize p to 1 for later use in step 2)
      )            //     end of map()
  :                // else:
    g(             //   do a recursive call:
      s - k * k,   //     subtract k² from s
      k,           //     pass k unchanged
      [...a, ++k], //     increment k and append it to a[]
      k > s ||     //     if k is less than or equal to s:
        g(s, k, a) //       do another recursive call with s and a[] unchanged
    )              //   end of outer recursive call

Passo 2

p

r.map(a =>         // for each array a[] in r[]:
  p *=             //   multiply p by:
    a.length +     //     the length of a[]
    ~a.indexOf(1)  //     minus 1, minus the index of the first 1 in a[]
) | p              // end of map(); return p



1

Haskell , 108 byte

n%i=sum[maximum[t!!i*b|t<-mapM([0..n]<$f)[0..3],sum(map(^2)t)==n,scanr1 max t==t]|b<-[-1,1]]
f n=n%0*n%1*n%2

Provalo online! (timeout sui casi di test più grandi)

Ci sono alcune strane ottimizzazioni qui. Per calcolare maximum l-minimum ll'elenco ldi elementi in una determinata posizione, risulta più breve nel contesto per convertirli entrambi in valori massimi negando il secondo termine: maximum l+maximum(map((-1)*))lo equivalentemente sum[maximum$map(b*)l||b<-[-1,1]].

Per moltiplicare le tre dimensioni, risulta più breve scrivere semplicemente il prodotto f n=n%0*n%1*n%2che utilizzare qualsiasi tipo di loop. Qui n%ic'è la differenza tra il minimo e il massimo dei i'valori delle coordinate, che vengono estratti con l'indicizzazione !!i.

Per generare le quattro tuple valide, prendiamo le liste di quattro numeri dai [0..n]cui quadrati si sommano ne sono in ordine decrescente. Controlliamo l'ordinamento inverso di tcon scanr1 max t==t, che vede se il massimo corrente del contrario è stesso, poiché Haskell non ha un ordinamento incorporato senza un'importazione costosa. Ho provato vari modi per generare ricorsivamente le quattro tuple come nelle mie risposte di Python, ma erano tutte più lunghe di questa modalità di generazione e filtro di forza bruta.

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.