JS,1719/1694
理论
不幸的是,从数学的角度来看,您提供的规则集可能不是明智的决定。实际上,使用较小的规则子集,您可以找到给定间隔中每个数字的解决方案
![我= [1; 10000]](https://i.stack.imgur.com/KBiqV.gif)
除了
![X = [1; 3]∪[5; 10]∪{12}](https://i.stack.imgur.com/rDCDo.gif)
为此没有解决方案。
简化规则集
请考虑以下规则子集:
- 只能使用运营商
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 …
这些数字或其他任何。
但是,如果您的表达式以其求值等于给定数字之一的表达式开头,则表示您不走运。例如,请注意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
,并确保系统上已安装SpiderMonkey(用于命令行的JavaScript引擎)。
算法
- 让我们将
K
正整数的属性定义为具有N
字母和值为的数字的状态N
。
- 让我们进一步定义
F
一个表达式的属性,因为它的单词转换状态8k
比用k∈evaluation的求值状态短-倍。F
代表“ fillable”并描述我们是否可以使用长度为8(即" times one"
)的表达式来填充表达式的单词转换,以使结果表达式可以获取该属性N
。
然后,我们进行如下操作:
- 将输入数字转换为单词。
- 检查输入的数字是否具有属性
K
。
- 如果是这样,则返回单词(
4
很遗憾,此属性是唯一的数字)。
- 如果不是,请继续。
- 对于所有导致输入数字的二操作数表达式(按此顺序进行加,减和乘),请检查它们的求值是否具有property
K
。
- 如果是这样,则返回单词。
- 如果不是,请检查两个操作数表达式是否具有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:表达式中子字符串“乘以一”的出现次数(最小0,最大1245)

结论:
- 表达式趋于以线性方式越来越无聊。
- 超过99%的解决方案很无聊。
So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.
您可能要排除零。由你决定。