JS, 1719/1694
Teoria
Sfortunatamente, il set di regole che fornisci potrebbe non essere una decisione saggia da un punto di vista matematico. In effetti, usando un sottoinsieme di regole più piccolo, puoi trovare una soluzione per ogni numero nell'intervallo dato
![I = [1; 10000]](https://i.stack.imgur.com/KBiqV.gif)
eccetto per
![X = [1; 3] ∪ [5; 10] ∪ {12}](https://i.stack.imgur.com/rDCDo.gif)
per il quale non esiste soluzione.
Set di regole ridotto
Considera il seguente sottoinsieme di regole:
- Utilizzare solo gli operatori
plus, minuse times.
- Non è necessario implementare più occorrenze di
pluso minusnelle tue espressioni.
- Non è necessario implementare né
divisionné operator associativity(poiché il loro set di soluzioni è già coperto dalla prima regola).
Il motivo per cui funziona è che, come discusso in precedenza con @Qwix, si consentono risposte noiose , ovvero espressioni che terminano nell'espressione regolare
( times one)+$. Consentendo ciò, ogni numero nell'intervallo indicato avrà una soluzione.
Quando hai risposto in uno dei tuoi commenti,
@Qwix Sì; risposte noiose sono accettabili, anche se non si lavora per 104, 105, 106, 107, 108, 109, 110 o 111. -
avevi assolutamente ragione: questo non funziona quando stai cercando di costruire la tua espressione iniziando con i numeri stessi, cioè one hundred four times one times one …o con qualsiasi altro di quei numeri.
Se tuttavia, la tua espressione inizia con un'espressione la cui valutazione è uguale a uno dei numeri indicati, sei sfortunato. Ad esempio, nota che 17 + 87è davvero 104, quindi potremmo scrivere 104come:
104: seventeen plus eighty seven times one times one times one times one times one times one times one times one times one times one
Per vedere che questo sottoinsieme funziona, salva questo file num.jse assicurati che SpiderMonkey, un motore JavaScript per le linee di comando, sia installato sul tuo sistema.
L'algoritmo
- Definiamo la proprietà
Kper numeri interi positivi come lo stato del numero che ha Nlettere e ha un valore di N.
- Definiamo ulteriormente la proprietà
Fdi un'espressione come lo stato della sua conversione di parole essendo 8kvolte più breve della sua valutazione con k ∈ ℕ. Fsta per "compilabile" e descrive se possiamo riempire o meno la parola conversione dell'espressione con espressioni di lunghezza 8 (cioè " times one") tali che l'espressione risultante possa ottenere la proprietà N.
Quindi procediamo come segue:
- Converti il numero di input in parole.
- Controlla se il numero di input ha proprietà
K.
- In tal caso, restituisci le parole (
4purtroppo è l'unico numero con questa proprietà).
- In caso contrario, procedere.
- Per tutte le espressioni a due operandi (aggiunte, sottrazioni e moltiplicazioni in questo ordine) che risultano nel numero di input, verificare se la loro valutazione ha proprietà
K.
- In tal caso, restituisci le parole.
- In caso contrario, controlla se l'espressione a due operandi ha proprietà
N.
- In tal caso, riempire l'espressione con
" times one"e verificare se la valutazione dell'espressione risultante ha proprietà K.
- In tal caso, restituisci le parole
- In caso contrario, procedere
- In caso contrario, procedere
- Vai a bere un caffè
Pratica
num.js (per SpiderMonkey / righe di comando)
function X(e,t){return e+": "+t}function P(e){var n,t;for(n=1;.5*e+(e%2===0?1:0)>n;++n){if(t=C.s(n)+" plus "+C.s(e-n),t.replace(/\s/g,"").length===e)return t;if(F(e,t)&&e>t.length)return G(e,t)}return!1}function M(e){var t,n;for(t=L;t>1;--t){if(0>t-e)return!1;if(n=C.s(t)+" minus "+C.s(t-e),n.replace(/\s/g,"").length===e)return n;if(F(e,n)&&e>n.length)return G(e,n)}return!1}function F(e,t){return(e-t.replace(/\s/g,"").length)%8===0}function G(r,t){var e,i=(r-t.replace(/\s/g,"").length)/8,n="";for(e=0;i>e;++e)n+=" times one";return t+n}function T(e){var t,n,r;if(F(e,C.s(e)))return G(e,C.s(e));for(t=1,n=1;t<Math.floor(Math.sqrt(e));++t){for(;e>tn;)++n;if(tn===e&&(r=C.s(t)+" times "+C.s(n),r.replace(/\s/g,"").length===e))return r}return!1}function Y(e){var n,r,t;return e===C.s(e).length?X(e,C.s(e)):(n=P(e))?X(e,n):(r=M(e))?X(e,r):(t=T(e),t?X(e,t):X(e,"impossible"))}var L=1e4,C=new function(){return this.o=["","one","two","three","four","five","six","seven","eight","nine"],this.t=["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],this.T=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],this.s=function(e){return e?this.m(e):"zero"},this.m=function(e){return e>=1e6?this.m(Math.floor(e/1e6))+" million"+(e%1e6!==0?" "+this.Z(e%1e6):""):this.Z(e)},this.Z=function(e){return e>=1e3?this.h(Math.floor(e/1e3))+" thousand"+(e%1e3!==0?" "+this.h(e%1e3):""):this.h(e)},this.h=function(e){return e>99?this.o[Math.floor(e/100)]+" hundred"+(e%100!==0?" "+this.U(e%100):""):this.U(e)},this.U=function(e){return 10>e?this.o[e]:e>=10&&20>e?this.T[e-10]:this.t[Math.floor(e/10)]+(e%10!==0?" "+this.o[e%10]:"")},this};print(Y(0|arguments[0]))
num.js (per browser)
Il codice dato dall'alto non può funzionare per i browser a causa del suo ultimo comando, che afferra gli argomenti della riga di comando per fare un bel comando dallo script dato.
Per eseguire il codice JavaScript direttamente dal tuo browser, seleziona questa parte del codice sopra:
function X(e,t){return e+": "+t}function P(e){var n,t;for(n=1;.5*e+(e%2===0?1:0)>n;++n){if(t=C.s(n)+" plus "+C.s(e-n),t.replace(/\s/g,"").length===e)return t;if(F(e,t)&&e>t.length)return G(e,t)}return!1}function M(e){var t,n;for(t=L;t>1;--t){if(0>t-e)return!1;if(n=C.s(t)+" minus "+C.s(t-e),n.replace(/\s/g,"").length===e)return n;if(F(e,n)&&e>n.length)return G(e,n)}return!1}function F(e,t){return(e-t.replace(/\s/g,"").length)%8===0}function G(r,t){var e,i=(r-t.replace(/\s/g,"").length)/8,n="";for(e=0;i>e;++e)n+=" times one";return t+n}function T(e){var t,n,r;if(F(e,C.s(e)))return G(e,C.s(e));for(t=1,n=1;t<Math.floor(Math.sqrt(e));++t){for(;e>tn;)++n;if(tn===e&&(r=C.s(t)+" times "+C.s(n),r.replace(/\s/g,"").length===e))return r}return!1}function Y(e){var n,r,t;return e===C.s(e).length?X(e,C.s(e)):(n=P(e))?X(e,n):(r=M(e))?X(e,r):(t=T(e),t?X(e,t):X(e,"impossible"))}var L=1e4,C=new function(){return this.o=["","one","two","three","four","five","six","seven","eight","nine"],this.t=["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],this.T=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],this.s=function(e){return e?this.m(e):"zero"},this.m=function(e){return e>=1e6?this.m(Math.floor(e/1e6))+" million"+(e%1e6!==0?" "+this.Z(e%1e6):""):this.Z(e)},this.Z=function(e){return e>=1e3?this.h(Math.floor(e/1e3))+" thousand"+(e%1e3!==0?" "+this.h(e%1e3):""):this.h(e)},this.h=function(e){return e>99?this.o[Math.floor(e/100)]+" hundred"+(e%100!==0?" "+this.U(e%100):""):this.U(e)},this.U=function(e){return 10>e?this.o[e]:e>=10&&20>e?this.T[e-10]:this.t[Math.floor(e/10)]+(e%10!==0?" "+this.o[e%10]:"")},this}
Ora incollalo nella console JavaScript del tuo browser, in modo da poter produrre gli stessi risultati dal tuo browser con, ad esempio:
Y(1234);
Esempi (riga di comando)
chiru@chiru ~ $ js num.js 28
28: fourteen plus fourteen times one
chiru@chiru ~ $ js num.js 7
7: impossible
chiru@chiru ~ $ js num.js 42
42: nine thousand sixty minus nine thousand eighteen
E per vedere il trucco con cui puoi far funzionare ogni numero, dai un'occhiata alla noiosa risposta per js num.js 1337:
1337: ten plus one thousand three hundred twenty seven times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one times one
I codici forniti generano soluzioni valide per l'intervallo dato (e probabilmente anche sopra, dovresti solo aumentare il valore della variabile L).
statistica
Ero interessato a "quanto noiose " fossero le espressioni (o: quanto la sottostringa times onefosse usata per espressione all'interno di questo algoritmo), poiché questa parte era responsabile di trovare una soluzione per ogni numero all'interno dell'intervallo dato. Guardate voi stessi:
x : espressione n-esima (min. 0, max. 10.000)
y : numero di occorrenze della sottostringa "volte una" all'interno dell'espressione (min. 0, max. 1245)

conclusioni:
- Le espressioni tendono a diventare sempre più noiose in modo lineare.
- Oltre il 99% delle soluzioni è noioso.
So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.Potresti voler escludere zero. Sta a te.