JS, 1719/1694
Théorie
Malheureusement, l'ensemble de règles que vous fournissez n'est peut-être pas une sage décision d'un point de vue mathématique. En fait, en utilisant un plus petit sous-ensemble de règles, vous pouvez trouver une solution pour chaque nombre dans l'intervalle donné
à l'exception de
pour lequel il n'y a pas de solution.
Jeu de règles réduit
Considérez le sous-ensemble de règles suivant:
- Utilisez uniquement les opérateurs
plus
, minus
et times
.
- Vous n'avez pas besoin d'implémenter plusieurs occurrences de
plus
ou minus
dans vos expressions.
- Vous n'avez pas besoin d'implémenter ni
division
ni operator associativity
(car leur ensemble de solutions est déjà couvert par la première règle).
La raison pour laquelle cela fonctionne est que, comme vous l'avez expliqué précédemment avec @Qwix, vous autorisez des réponses ennuyeuses , c'est-à-dire des expressions qui se terminent par l'expression régulière
( times one)+$
. En permettant cela, chaque nombre dans l'intervalle donné aura une solution.
Lorsque vous avez répondu dans l'un de vos commentaires,
@Qwix Oui; des réponses ennuyeuses sont acceptables, bien que celle-ci ne fonctionne pas pour 104, 105, 106, 107, 108, 109, 110 ou 111. -
vous aviez absolument raison: cela ne fonctionne pas lorsque vous essayez de construire votre expression en commençant par les nombres eux-mêmes, c'est-à-dire one hundred four times one times one …
ou tout autre de ces nombres.
Si toutefois, votre expression commence par une expression dont l'évaluation est égale à l'un des nombres donnés, vous n'avez pas de chance. Par exemple, notez que 17 + 87
c'est effectivement le cas 104
, donc nous pourrions écrire 104
comme:
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
Pour voir que ce sous-ensemble fonctionne, enregistrez ce fichier sous num.js
et assurez-vous que SpiderMonkey, un moteur JavaScript pour les lignes de commande, est installé sur votre système.
L'algorithme
- Définissons la propriété
K
des entiers positifs comme l'état du nombre ayant des N
lettres et ayant une valeur de N
.
- Définissons en outre la propriété
F
d'une expression comme l'état de sa conversion de mots étant 8k
-temps plus court que son évaluation avec k ∈ ℕ. F
signifie "fillable" et décrit si nous pouvons ou non remplir la conversion de mots de l'expression avec des expressions de longueur 8 (c'est-à-dire " times one"
) de telle sorte que l'expression résultante puisse obtenir la propriété N
.
Nous procédons ensuite comme suit:
- Convertissez le nombre saisi en mots.
- Vérifiez si le numéro saisi a une propriété
K
.
- Si c'est le cas, renvoyez les mots (
4
c'est le seul numéro avec cette propriété, malheureusement).
- Si ce n'est pas le cas, continuez.
- Pour toutes les expressions à deux opérandes (additions, soustractions et multiplications dans cet ordre) qui aboutissent au numéro d'entrée, vérifiez si leur évaluation a une propriété
K
.
- Si c'est le cas, renvoyez les mots.
- Si ce n'est pas le cas, vérifiez si l'expression à deux opérandes a une propriété
N
.
- Si c'est le cas, remplissez l'expression avec
" times one"
et vérifiez si l'évaluation de l'expression résultante a une propriété K
.
- Si c'est le cas, renvoyez les mots
- Si ce n'est pas le cas, continuez
- Si ce n'est pas le cas, continuez
- Va boire un café
Entraine toi
num.js (pour SpiderMonkey / lignes de commande)
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 (pour les navigateurs)
Le code donné ci-dessus ne peut pas fonctionner pour les navigateurs en raison de sa dernière commande, qui saisit les arguments de la ligne de commande afin de faire une belle commande à partir du script donné.
Afin d'exécuter le code JavaScript directement à partir de votre navigateur, sélectionnez cette partie du code ci-dessus:
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}
Maintenant, collez-le dans la console JavaScript de votre navigateur, afin de pouvoir produire les mêmes résultats à partir de votre navigateur avec, par exemple:
Y(1234);
Exemples (ligne de commande)
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
Et pour voir l'astuce avec laquelle vous pouvez faire fonctionner chaque numéro, jetez un œil à la réponse ennuyeuse pour 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
Les codes fournis génèrent des solutions valides pour l'intervalle donné (et probablement même au-dessus, vous n'auriez qu'à augmenter la valeur de la variable L
).
Statistiques
Je m'intéressais à "l' ennui " des expressions (ou: à quel point la sous-chaîne times one
était utilisée par expression dans cet algorithme), car cette partie était chargée de trouver une solution pour chaque nombre dans l'intervalle donné. Voyez par vous-même:
x : n-ième expression (min. 0, max. 10 000)
y : nombre d'occurrences de la sous-chaîne "fois un" dans l'expression (min. 0, max. 1245)
Conclusions:
- Les expressions ont tendance à devenir de plus en plus ennuyeuses de manière linéaire.
- Plus de 99% des solutions sont ennuyeuses.
So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.
Vous souhaiterez peut-être exclure zéro. Dépend de vous.