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 …
любого другого из этих чисел.
Однако, если ваше выражение начинается с выражения, оценка которого равна одному из заданных чисел, вам не повезло. Например, обратите внимание, что 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 ∈ ℕ. F
расшифровывается как «fillable» и описывает, можем ли мы заполнить преобразование слов выражения выражениями длины 8 (т.е. " times one"
), чтобы полученное выражение могло получить свойство N
.
Затем мы действуем следующим образом:
- Преобразуйте введенный номер в слова.
- Проверьте, есть ли у входного номера свойство
K
.
- Если это так, верните слова (
4
к сожалению, это единственное число с этим свойством).
- Если это не так, продолжайте.
- Для всех выражений с двумя операндами (сложения, вычитания и умножения в этом порядке), которые приводят к вводимому номеру, проверьте, имеет ли их оценка свойство
K
.
- Если это так, верните слова.
- Если это не так, проверьте, имеет ли выражение с двумя операндами свойство
N
.
- Если это так, заполните выражение
" times one"
и проверьте, есть ли свойство в полученном выражении 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, макс. 10000)
y : количество вхождений подстроки «times one» в выражении (мин. 0, макс. 1245)
Выводы:
- Выражения имеют тенденцию становиться все более и более скучным в линейной манере.
- Более 99% растворов скучны.
So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.
Вы можете исключить ноль. Вам решать.