Dimostra che un numero è algebrico


10

Ispirato da questa risposta (enfasi sulla mia):

Faremo una partita. Supponiamo di avere un numero x . Si inizia con x e quindi è possibile aggiungere, sottrarre, moltiplicare o dividere per qualsiasi numero intero, tranne zero. Puoi anche moltiplicare per x . Puoi fare queste cose tutte le volte che vuoi. Se il totale diventa zero, hai vinto.

Ad esempio, supponiamo che x sia 2/3. Moltiplicare per 3, quindi sottrarre 2. Il risultato è zero. Hai vinto!

Supponiamo che x sia 7 ^ (1/3). Moltiplica per x , quindi di nuovo per x , quindi sottrai 7. Hai vinto!

Supponiamo che x sia √2 + √3. Qui non è facile vedere come vincere. Ma si scopre che se si moltiplica per x , si sottrae 10, si moltiplica per x due volte e si aggiunge 1, si vince. (Questo non dovrebbe essere ovvio; puoi provarlo con la tua calcolatrice.)

Ma se inizi con x = π, non puoi vincere. Non è possibile passare da π a 0 se si aggiunge, sottrai, moltiplica o dividi per numeri interi o moltiplica per π, indipendentemente da quanti passi fai. (Anche questo non dovrebbe essere ovvio. È una cosa molto complicata!)

Numeri come √2 + √3 da cui puoi vincere sono chiamati algebrici . Numeri come π con cui non puoi vincere sono chiamati trascendentali.

Perché è interessante? Ogni numero algebrico è correlato aritmeticamente agli interi e le mosse vincenti nel gioco ti mostrano come. Il percorso per zero potrebbe essere lungo e complicato, ma ogni passaggio è semplice e c'è un percorso. Ma i numeri trascendentali sono fondamentalmente diversi: non sono aritmeticamente correlati agli interi tramite semplici passaggi.


In sostanza, utilizzerai i passaggi utilizzati nella domanda sopra citata per "vincere" il gioco per un determinato input.

Data una costante algebrica reale, xconverti il ​​numero in zero usando le seguenti operazioni consentite:

  • Aggiungi o Sottrai un numero intero.
  • Moltiplica o dividi per un numero intero diverso da zero.
  • Moltiplicare per la costante originale x.

L'input è una stringa che può contenere numeri interi, addizione, sottrazione, moltiplicazione, divisione, esponenziale (la tua scelta di **o ^, esponenti sono usati per rappresentare le radici) e parentesi. Gli spazi nell'input sono opzionali, ma non nell'output. Dovresti emettere i passaggi necessari per ottenere un risultato pari a zero, quindi moltiplicando per 7come un passo verrebbe emesso come *7. È consentito uno spazio finale e / o newline.

Esempi

0               ->  +0 (or any other valid, or empty)
5/7 + 42        ->  -42 *7 -5 (or shorter: *7 -299)
2^(1/3)         ->  *x *x -2
5*(3**(1/4))    ->  *x *x *x -1875
2^(1/2)+3^(1/2) ->  *x -10 *x *x +1

Il codice più corto vince.


Quanto vicini 0devono essere i risultati? Dati gli errori di arrotondamento e la precisione del galleggiante, ho potuto facilmente vedere situazioni problematiche ...
AdmBorkBork,

2
@TimmyD La risposta deve essere esatta, in modo da poter eseguire le operazioni e ottenere zero. Visualizza gli esempi forniti. Non esiste aritmetica in virgola mobile.
mbomb007,

1
Come è √2 + √3 algebrico? Se moltiplichi il numero da solo ottieni 5 + 2√6 ... a meno che non mi manchi qualcosa, non puoi mai forzare il radicale.
Mario Ishac,

@ mbomb007 Whoops, le mie scuse, non l'ho preso nel PO.
Mario Ishac,

1
È una soluzione all'equazione x^4-10*x^2+1. Vedi WolframAlpha
mbomb007,

Risposte:


3

SageMath , 108 byte

def f(s):p=map('{:+} '.format,numerator(minpoly(sage_eval(s)/1)));return'*'+p[-1][1:]+'*x '.join(p[-2::-1])

Provalo su SageMathCell .

Spiegazione:

Valuta la stringa simbolicamente come un numero algebrico ( sage_eval()). Ogni numero algebrico è uno zero di alcuni polinomi a [0] + a [1] x ^ 1 + a [2] x ^ 2 + ⋯ + a [n] x ^ n con coefficienti razionali a [0], ..., a [ n ] ( minpoly()). Moltiplica tutti i coefficienti per il loro comune denominatore per trasformarli in numeri interi ( numerator()), quindi scrivi questo polinomio nel formato di output desiderato,

*a[n] +a[n-1] *x +a[n-2] *x … *x +a[1] *x +a[0]

SageMath, 102 byte, quasi

lambda s:(lambda a,*p:'*%d'%a+'*x'.join(map(' {:+} '.format,p)))(*numerator(minpoly(1/sage_eval(s))))

Questo funziona per tutti gli input tranne 0, perché un polinomio per 1 / α è un polinomio per α con i coefficienti invertiti. :-(


1

Matematica, 194 224 192 byte

""<>Cases[HornerForm@MinimalPolynomial[ToExpression@#,x]//.{Times->t,x^a_:>Fold[#2~t~#&,x~Table~a],a_~t~b_~t~c_:>a~t~t[b,c]},a_~b_~_:>{b/.t:>"*"/.Plus:>If[a>0,"+",""],ToString@a," "},{0,∞}]&

Ecco il carattere unicode a tre byte che rappresenta l'infinito in Mathematica.

Poiché l'input è una stringa, si perdono 13 byte su ToExpression@cui interpreta l'input della stringa come espressione algebrica.

HornerForm@MinimalPolynomial[2^(1/2)+3^(1/2), x]

Restituirebbe qualcosa del genere

1 + x^2 (-10 + x^2)

La prossima regola di sostituzione lo massaggia in qualcosa che è strutturalmente simile

1 + (x * (x * (-10 + (x * (x)))))

Questa forma Horner può essere visualizzata come un albero:

TreeForm

Noi, secondo le regole dell'OP, iniziamo con la foglia più profonda a destra.

Cases passa attraverso l'espressione, iniziando dal livello più profondo, prendendo ogni nodo genitore e la sua foglia sinistra e assemblandolo in una tabella come

"*" "x"   " "
""  "-10" " "
"*" "x"   " "
"*" "x"   " "
"+" "1"   " "

""<> concatena tutto con la stringa vuota.


Questo restituisce erroneamente -299per 5/7 + 42.
Anders Kaseorg,

@And quindi omette il * 7 ... ricontrollerò quando sarò a casa
LLlAMnYP

@AndersKaseorg funziona, ma ora ho 30 byte in meno.
LLlAMnYP,
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.