JS、1719/1694
理論
残念ながら、提供するルールセットは、数学的な観点からは賢明な決定ではない場合があります。実際、ルールのより小さなサブセットを使用して、指定された間隔内のすべての数値の解決策を見つけることができます
を除いて
解決策はありません。
ルールセットの削減
次のルールのサブセットを検討してください。
- 演算子のみを使用し
plus
、minus
そしてtimes
。
- あなたは、実装する必要はありませんの複数の発生
plus
やminus
、あなたの表情でを。
- あなたは、実装する必要はありませんどちら
division
もoperator associativity
(彼らのソリューションセットは、すでに最初のルールで覆われているもの)を。
これが機能する理由は、前に@Qwixで説明したように、退屈な答え、つまり正規表現で終わる表現を
許可するため( times one)+$
です。これを許可すると、指定された間隔の各数値に解決策があります。
コメントのいずれかで返信すると、
@Qwixはい; つまらない答えは受け入れられますが、それは104、105、106、107、108、109、110、または111では機能しません。
あなたは絶対に正しかった:数字自体、one hundred four times one times one …
または他の数字から始まる式を構築しようとしているとき、これは機能しません。
ただし、式が評価が指定された数値の1つに等しい式で始まる場合、運が悪いです。たとえば、それ17 + 87
は確か104
にですので、次のように書くことができます104
:
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
このサブセットが機能num.js
することを確認するには、このファイルを名前を付けて保存し、コマンドライン用のJavaScriptエンジンであるSpiderMonkeyがシステムにインストールされていることを確認します。
アルゴリズム
K
正の整数のプロパティN
を、文字と値を持つ数値の状態として定義しますN
。
- さらに
F
、式のプロパティを、単語変換の状態が8k
k∈withでの評価よりも1倍短いと定義します。F
"fillable"の略" times one"
で、結果の式がpropertyを取得できるように、式の単語変換を長さ8の式で埋めることができるかどうかを示します(つまり)N
。
次に、次の手順を実行します。
- 入力番号を単語に変換します。
- 入力番号にpropertyがあるかどうかを確認してください
K
。
- 存在する場合、単語を返します(
4
残念ながら、このプロパティを持つ唯一の数字です)。
- そうでない場合は、続行します。
- 入力数が得られるすべての2オペランド式(この順序での加算、減算、乗算)について、それらの評価にpropertyがあるかどうかを確認します
K
。
- もしそうなら、単語を返します。
- そうでない場合は、2つのオペランドの式にpropertyがあるかどうかを確認します
N
。
- 含まれている場合は、
" times one"
式を入力して、結果の式の評価にpropertyがあるかどうかを確認しますK
。
- もしそうなら、言葉を返す
- そうでない場合は、続行します
- そうでない場合は、続行します
- コーヒーを飲みに行く
練習
num.js(SpiderMonkey /コマンドライン用)
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(ブラウザ用)
上記の指定されたコードは、最後のコマンドのためにブラウザーで機能しません。最後のコマンドは、指定されたスクリプトから素敵なコマンドを作成するためにコマンドライン引数を取得します。
ブラウザ内から直接JavaScriptコードを実行するには、上記のコードのこの部分を選択します。
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}
次に、ブラウザのJavaScriptコンソールに貼り付けます。これにより、たとえば次のようにしてブラウザ内から同じ結果を生成できます。
Y(1234);
例(コマンドライン)
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
そして、各番号を機能させるトリックを見るために、次の退屈な答えを見てください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
提供されたコードは、指定された間隔に対して有効なソリューションを生成します(おそらく上記の場合でも、変数の値を上げる必要があるだけですL
)。
統計
この部分は指定された間隔内のすべての数値の解を見つける責任があるため、式が「どれほど退屈な」(またはtimes one
このアルゴリズム内の式ごとに部分文字列が使用されたか)に興味がありました。ご自身でご覧ください:
x:n番目の式(最小0、最大10,000)
y:式内の部分文字列「times one」の出現回数(最小0、最大1245)
結論:
- 式は線形的に退屈になる傾向があります。
- ソリューションの99%以上は退屈です。
So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.
ゼロを除外することもできます。あなた次第。