Напишите программу, которая принимает строку нечетной длины, содержащую только символы .
и :
. С помощью изначально пустого стека сгенерируйте число из этой строки следующим образом:
Для каждого символа c в строке (идущего слева направо) ...
- Если c есть,
.
а в стеке менее 2 элементов, нажмите 1 в стеке. - Если с есть
.
и стек имеет 2 или более элементов, поп два значения из стека и подтолкнуть их сумму на стек. - Если c есть,
:
а в стеке менее 2 элементов, нажмите 2 в стеке. - Если с это
:
и стек имеет 2 или более элементов, поп два значения из стека и толкать их продукт в стек.
Полученное число является значением в верхней части стека. Ваша программа должна напечатать этот номер на стандартный вывод (с дополнительным завершающим переводом строки).
(Небольшой анализ показывает, что остается только одно число, если строка не имеет четной длины, поэтому мы игнорируем их. На самом деле в стеке никогда не бывает более 2 элементов.)
Например, число для ::...:.:.
9:
2 1 2 2 /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9 \
: : . . . : . : . <-- string, one character at a time
В качестве проверки работоспособности, вот числа для всех строк длины 1, 3 и 5:
. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8
Самая короткая программа в байтах побеждает. Tiebreaker - более ранний пост.
- Вы можете предполагать, что ввод всегда действителен, то есть строка, содержащая только
.
и:
длина которой нечетна. - Вместо написания программы вы можете написать функцию, которая принимает допустимую строку и печатает или возвращает сгенерированное число.
Ответы:
CJam,
27 24 2322 байтаДовольно прямо вперед. Я использую стек CJam в качестве стека, упомянутого в вопросе;)
Алгоритм
Сначала давайте посмотрим на код ASCII для
.
и:
.Поскольку в CJam индекс оборачивается, давайте посмотрим, сможем ли мы использовать эти значения напрямую, чтобы получить желаемую операцию.
Поэтому я не могу просто использовать коды ASCII в строке операции длиной 4. Давайте попробуем некоторые другие значения
который на 4-х струнной длине сводится к
Я могу использовать эту операцию мода 10, но это будет стоить 2 байта. Давайте попробуем что-нибудь еще
Хорошо, теперь мы просто вычитаем 1 для условия размера стека, чтобы получить индексы,
0, 1, 2 and 3
и используем5
массив length ("1+2* "
) в качестве регистра переключателя. Последний пробел - это просто заполнитель для длины 5. Это всего лишь 1 дополнительный байт по сравнению с операцией моддинга.Попробуйте онлайн здесь
1 байт сохранен благодаря cosechy
источник
> <> (Рыба) , 33 байта
Довольно просто с небольшими хитростями / оптимизациями.
Объяснение:
i
= кодовая точка следующего входного символа,-1
если достигнут конец ввода;a
= 10;b
= 11;)
знак равно>
i
кодовая точка первого входного символа,b%1-
top_of_stack mod 11 - 1
маски48 ('.') , 56 (':')
для1 , 2
i:1+?\~n;
если достигнут конец ввода, выведите последний результат и завершитеb%1-
маска ввода для1 , 2
0@
нажмите0
под два числаi5a*)
прочитайте следующий ввод и замаскируйте его для0 , 1
сравнения с50
1
(':'
) умножить верхние два элемента, создавая стек [0 product][0 sum]
или[0+product=product]
40.
прыжок (цикл) обратно в положение(4,0)
, наша точка4
,i:1+?\~n;
источник
Haskell,
7365 байтПростое решение, использующее тот факт, что стек никогда не имеет более 2 элементов.
источник
C 104 байта
Ну, это слишком долго.
источник
Pyth,
2524 байтаПолучил идею, изучив решение @ isaacg. Но я использую стек.
Онлайн-демонстрация или тестовый набор
объяснение
Первое, что я делаю, это преобразовываю входную строку в 0 и 1. А
"."
превращается в0
,":"
в в1
.Тогда я уменьшу этот список чисел:
источник
JavaScript (ES6), 65
Мы используем только 2 ячейки нашего стека.
Начните помещать значение в s [0].
Затем в каждой нечетной позиции (считая от 0) во входной строке поместите значение в s [1].
В каждой четной позиции выполните calc (сложение или умножение) и сохраните результат в s [0].
Так что забудьте о стеке и используйте только 2 переменные, a и b.
Быстрый тест
Выход
источник
f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
Pyth, 27 байт
Стек? Кому нужен стек
Демонстрация.
источник
Retina ,
1057573 байтаМоя первая программа Retina! (Спасибо Мартину Бюттнеру за то, что он сэкономил 2 байта, не говоря уже о изобретении языка в первую очередь.)
Каждая строка должна идти в отдельном файле; или вы можете поместить их все в один файл и использовать
-s
флаг.<empty>
Обозначение представляет собой пустой файл / строку.Вдохновлен ответом mbomb007 , но я использую несколько иной подход. Одно из основных отличий состоит в том, что я строю стек перед точечной строкой (вершина стека обращена вправо). Это позволяет легко конвертировать символы в соответствующие номера на месте. Я также использую
a
вместо того1
, чтобы заменить его только в конце, чтобы избежать разбора неоднозначности в таких последовательностях, как$1a
. Если подобный ответaaaaaa
приемлем в качестве унарного числа, последние две строки / файлы можно исключить, чтобы сэкономить 4 байта.Объяснение:
Соответствует, если в стеке 0 или 1 элементов,
(a+;)?
за которыми следует точка (\.
); если это так, он заменяет период наa;
(т.е. помещает 1).Соответствует, если в стеке 0 или 1 элементов, за которыми следует двоеточие. Если это так, он заменяет двоеточие на
aa;
(то есть толкает 2).Соответствует, если в стеке есть два элемента, за которыми следует точка. Удаляет точку и точку с запятой между элементами, тем самым добавляя их.
Соответствует, если в стеке есть два элемента, верхний из которых - 2, за которым следует двоеточие. Удаляет двоеточие и 2 и повторяет другое число дважды, умножая его на 2.
Регулярное выражение совпадает, если в стеке есть два элемента, верхняя часть которых - 1, за которым следует двоеточие. Удаляет двоеточие и 1, оставляя другое число без изменений (т. Е. Умножается на 1).
)`
указывает на конец цикла. Если в строку были внесены какие-либо изменения, элемент управления возвращается в начало программы и снова выполняет подстановки. Если строка перестала меняться, мы заменили все точки и двоеточия, и все, что осталось, это очистить ...Удаляет оставшуюся точку с запятой.
Превращает все а в 1. Опять же, если для одинарных чисел разрешено использовать любой символ, этот шаг не требуется.
источник
Ржавчина, 170 символов
Еще одно доказательство того, что Руст абсолютно ужасен в игре в гольф. Полный негольфированный код:
Вот интересный трюк, который я использовал в этом. Вы можете сбрить символ в операторе if / else, заставив его вернуть значение, которое немедленно отбрасывается, что означает, что вам нужно только одну точку с запятой вместо двух.
Например,
может быть изменен на
который сохраняет характер, сбривая точку с запятой.
источник
Haskell,
888179 байтКажется, что кто-то превзошел меня до уровня решения Haskell, и не только это, их решение короче моего. Это плохо, но я не вижу причин, чтобы не публиковать то, что я придумал.
источник
APL (50)
Я нахожусь в невыгодном положении, потому что APL не является языком, основанным на стеке. Я, наконец, начал сокращать злоупотребления, чтобы сократить программу.
Внутренняя функция берет «команду» слева и стек справа и применяет ее, возвращая стек. Внешняя функция уменьшает его над строкой, начиная с пустого стека.
Объяснение:
(⌽⍵),⊂⍬
: начальный список, чтобы уменьшить более.⊂⍬
является пустым списком в штучной упаковке, который представляет стек,(⌽⍵)
является обратной стороной ввода. (Сокращение применяется справа налево над списком, поэтому строка будет обрабатываться справа налево. Реверсирование ввода заранее позволяет применять символы в правильном порядке.){
...}
: внутренняя функция. Он берет стек справа, символ слева и возвращает модифицированный стек.F←'.:'⍳⍺
: индекс символа в строке.:
, это будет 1 или 2 в зависимости от значения.2>⍴⍵:F,⍵
: Если 2 больше текущего размера стека, просто добавьте текущее значение в стек.⋄
: иначе,2↓⍵
: удалить два верхних элемента из стека(
...)/2↑⍵
: уменьшить заданную функцию над ними и добавить ее в стек.⍎F⌷'+×'
: функция либо+
(сложение), либо×
(умножение), выбрана с помощьюF
.⊃
: наконец, вернуть самый верхний элемент в стекеисточник
Рубин - 96 символов
Сорта интересный кусок здесь
eval
.Кроме того, я делаю предположение, что после первого символа в стеке всегда будет 2, math, 2, math, .... Это позволяет мне использовать меньше кода, получая два символа одновременно - мне никогда не придется вычислять вне зависимости от того, является ли символ математикой или числом. Это позиционно.
Ungolfed:
источник
TI-BASIC,
7873706966 байтовTI-BASIC хорош в однострочниках, потому что закрывающие скобки не обязательны; и наоборот, это плохой язык, в котором требуется сохранение нескольких значений, поскольку хранение в переменной занимает от двух до четырех байтов. Поэтому цель состоит в том, чтобы написать как можно больше в каждой строке. TI-BASIC также ужасен (для языка токенов) при любых манипуляциях со строками; даже чтение подстроки занимает много времени.
Трюки включают в себя:
int(e^([boolean]
вместо того1+(boolean
; сохраняет один байтисточник
".:.":prgmDOTTY
, сохраняя 4 байта.1+(":"=sub(Ans,1,1
Идти,
129115112 байт(отчасти) разгневанный
Попробуйте онлайн здесь: http://play.golang.org/p/B3GZonaG-y
источник
Python 3, 74
Сначала преобразует входной список в последовательность из 1 и 2, принимая первое значение в качестве начального значения
x
. Затем снимает два элемента одновременно с передней частиs
, беря первое число и добавляя или умножая его на текущее число, основываясь на том, равен ли второй 1 или 2.источник
ну это так просто операция, сложная опера (намеренно)
просто ...
Код: C (80 байт)
вход
длина = 2n + 1 вектор V типа char '.' или ':'
Выход
целое число k
функция
Моделирование:
попробуйте здесь
источник
*(V-1)
) равен нулю?Сетчатка,
181135129 байтКаждая строка должна быть в отдельном файле.
<empty>
представляет пустой файл. Выход в Унарном.Когда${0}1
используется, фигурные скобки отделяются$0
от1
, в противном случае это была бы$01
1-я подходящая группа. Я пытался использовать$001
, но это, похоже, не работает в. NET вкус регулярных выражений.Изменить: Найдено, что так
$&
же, как$0
.В псевдокоде это, по сути, будет цикл do-while, как показано ниже. Я нажимаю первый номер, затем зацикливаю: нажимаю второй номер, убираю операцию (инструкцию), делаю математику, убираю оп. Продолжайте цикл. Обратите внимание, что когда операция прерывается, это также удалит пробел после выполнения всех инструкций.
комментарии:
источник
(:)(.*)
->$1$2
, что, я уверен, может быть просто(:.*)
->$1
(поскольку вы держите две группы в одном порядке и больше ничего с ними не делаете ).Python 3, 122 байта
Ungolfed:
В python вы ссылаетесь на индекс списка следующим образом:
Вы можете поместить логическое значение в это,
True
есть1
иFalse
есть0
.Попробуйте онлайн здесь
источник
Perl, 77 байт
расширен:
@o
Массив отображает цифры для операторов. Затем мы заменяем пары цифр соответствующим оператором, переставленным в infix. Регулярное выражение начинается с\B
того, что мы не сопоставляем самого первого символа. Результатs///g
говорит нам, сколько открытых паренов нам нужно в начале. Затем, когда мы собрали полное инфиксное выражение, мы можем его оценить. (Удалите,eval
если хотите вместо этого увидеть выражение).Вот тестовый жгут, который я использовал для проверки результатов:
Входные данные представляют собой список выражений точек и их значений (приведены в вопросе), а выходные данные представляют собой пары {фактические, ожидаемые}.
источник