Выражение, равное его длине


14

По заданному числу найдите в словах выражение, равное этому числу, с длиной этого числа.

Таким образом, для ввода 15вы можете вывести sixteen minus one, который имеет пятнадцать символов (не считая пробелов). Если существует несколько решений, распечатайте, сколько хотите. Если ничего не существует, выведитеimpossible

Используйте только операторы plus, minus, times, и divided by. Операторы оцениваются слева направо.

Формат 1234 как one thousand two hundred thirty four. Обратите внимание на отсутствие «и» и на то, что нет тире или запятых.

Входные данные и все числа, используемые в выходных данных, должны быть натуральными числами, меньшими 10 000.

Ввод будет дан как аргумент командной строки. Печать на стандартный вывод.

Примеры

1: impossible
4: four
7: impossible
13: eight plus five (you could also output "five plus eight")
18: one plus two times six (note that operators are evaluated from left to right)
25: one thousand divided by forty

4
неотрицательные целые числа? So for 1234 we can do (massive expression) times zero plus one thousand two hundred thirty four.Вы можете исключить ноль. Вам решать.
Уровень Река St

@steveverrill Хороший вопрос; Я изменил его на "положительные целые числа".
Ypnypn

4
ооочень ... one hundred three times one times one times one times one times one times one times one times one times one times one times oneдействует?
Qwix

@Qwix Да; скучные ответы приемлемы, хотя это не работает для 104, 105, 106, 107, 108, 109, 110 или 111.
Ипныпн

Ответы:


1

Javascript, 434 символа

function f(s){return s.replace(/[A-Z]/g,function(t){return{O:'one',T:'two',H:'three',F:'four',I:'five',S:'six',E:'seven',G:'eight',N:'nine',Z:'ten',P:' plus ',M:' minus ',U:' times ',X:'teen',A:'thir',B:'twenty'}[t]})}A='TPAX|GeenMT|EXUO|B FMS|F|GPSUT|ZPHPG|BPFMT|AXPFPS|BPGMF|EUOPGeen|NPT|B GMSPI|GPI|EPE'.split('|');O=26640;function S(n){return n<15&&!(O>>n&1)?'Invalid':f(A[v=n%15])+(new Array(~~(n/15)+(O>>v&1))).join(f('PSPN'))}

Возвращает функцию в глобальном пространстве имен, Sкоторая принимает любое неотрицательное целое число и возвращает требуемую строку, или "Invalid"если целое число не может быть представлено в спецификациях.

Я, кажется, использовал тот же подход, что и @optokopper, сделав то же самое наблюдение, которое "plus six plus nine"является самой короткой возможной строкой заполнения, и что все числа больше 27 могут быть выражены путем объединения одной из 15 базовых строк с повторными копиями панели.

Сказав это, таблицы базовых строк, которые мы используем, отличаются, и мое решение опирается на битовый твидлинг и оператор остатка ( %). Это также включает "multiplied by"в себя в качестве возможной операции. И, естественно, механика того, как строятся строки, совершенно различна из-за различий между C и Javascript.

Во всяком случае, это моя лучшая попытка. ;)

Особая благодарность @chiru, чье обсуждение того, какие цифры были достижимы, помогло предотвратить бесплодный поиск.


22

JS, 1719/1694

теория

К сожалению, набор правил, который вы предоставляете, не может быть мудрым решением с математической точки зрения. Фактически, используя меньшее подмножество правил, вы можете найти решение для каждого числа в данном интервале

Я = [1;  10000]

кроме

Х = [1;  3] ∪ [5;  10] ∪ {12}

для которого нет решения.

Сокращенный набор правил

Рассмотрим следующую часть правил:

  • Используйте только оператор 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% растворов скучны.

2
Существует решение для 4four
FUZxxl

@FUZxxl Я никогда не отрицал это. Если вы отвечаете, возможно If it does, return the words (4 is the only number with this property, unfortunately), вы неправильно поняли этот раздел. Он говорит, что 4это единственное выражение без оператора, которое формирует свое собственное решение.
Чиру

@FUZxxl О, хорошо. Я только что заметил, что в начале раздела я сказал, что в X = [0; 10] ∪ {12}, хотя позже я скажу, что 4есть решение. Я исправил интервал, спасибо. :)
Чиру

6

C, 450 знаков

Редактировать: удалено zero

Редактировать: используя только plusиminus

Я искал самое короткое выражение, которое добавляет символы и сохраняет условие истинным. Я нашел plus ten plus five15 длинных и добавляет 15 к строке.

Мне нужны только выражения для первых 15 чисел, которые не являются невозможными, чтобы выразить любое возможное число. 12 - самое большое невозможное число, поэтому достаточно жестко закодировать числа, меньшие 28.

4 = четыре
11 = шесть плюс пять
13 = восемь плюс пять
14 = двадцать минус шесть
15 = двадцать минус пять
16 = восемнадцать минус два
17 = четырнадцать плюс три
18 = двадцать два минус четыре
20 = тридцать два минус двенадцать
21 = двадцать плюс два минус один
22 = двадцать плюс четыре минус два
23 = тридцать минус восемь плюс один
24 = двадцать плюс восемь минус четыре
25 = двадцать плюс восемь минус три
27 = двадцать восемь минус шесть плюс пять

Мы можем написать каждое число> 27 как x * 15 + одно из чисел выше.

Golfed

#define P" plus "
#define M" minus "
#define U"four"
#define F"five"
#define E"eight"
#define W"twenty"
#define A"ten"P F P
*e[]={0,0,0,0,U,0,0,0,0,0,0,F P"six",0,E P F,W M"six",W M F,E"een"M"two",U"teen"P"three",W" two"M U,A U,"thirty two"M"twelve",W P"two"M"one",W M"two"P U,"thirty"P"one"M E,W P E M U,W M"three"P E,A F P"six",W" "E M"six"P F};main(n){n=atoi(1[(int*)1[&n]]);for(printf("%d: ",n);n>27;n-=15)printf(A);puts(e[n]?e[n]:"impossible");}

Читаемый код

#include <stdio.h>
#include <stdlib.h>

// add fifteen to string, both as value and as character count (without spaces)
const char *add_fifteen = "plus ten plus five";

// table with hardcoded expressions
// NOTE: we could calculate 19, 26, 28 and 29 from 4, 11, 13 and 14
// but we would need more logic, so we hardcode those 4 numbers too.
const char *expressions[30]={"impossible", "impossible", "impossible", "impossible",
    "four", "impossible", "impossible", "impossible", "impossible",
    "impossible", "impossible", "five plus six", "impossible",
    "eight plus five", "twenty minus six",
    "fourteen plus one", "eighteen minus two", "fourteen plus three",
    "twenty two minus four", "four plus ten plus five",
    "thirty two minus twelve", "nine plus seven plus five",
    "twenty plus four minus two", "twelve plus seven plus four",
    "twenty plus eight minus four", "twenty plus eight minus three",
    "five plus six plus ten plus five", "twenty eight minus six plus five",
    "eight plus five plus ten plus five", "seven plus seven plus ten plus five"};

int main(int argc,char *argv[])
{
    int n = strtol(argv[1], NULL, 0);
    int fifteens = 0;

    printf("%d: ", n);

    // how many times do we need to add fifteen?
    if(n>29){
        fifteens=(n/15) - 1;
        n -= fifteens*15; // ensure 30 > n >= 15, so we don't get "impossible"
    }

    // look up the expression for n
    printf("%s", expressions[n]);

    // add fifteens till we are done
    while(fifteens-- > 0) {
        printf(" %s", add_fifteen);
    }

    printf("\n");
    return 0;
}

2
Не совсем уверен, как работает ваш код, но поскольку вопрос гласит, что all numbers used in the output must be positive integersвы могли бы удалить его #define Z "zero"из кода вместе с экземплярами Z, так как вам никогда не следует его использовать?
Qwix

«плюс двенадцать» - 12 букв. Это поможет сократить ваш код?
Исаак

Я бы сделал его короче, увы пробелы не в счет, plus twelveвсего 10 букв
Optokopper

ОК, я неправильно понял правила.
Исаак
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.