Ваша задача - если вы решите принять ее - состоит в том, чтобы создать программу, которая анализирует и оценивает строку (слева направо и произвольной длины) токенов, которые дают указания - влево или вправо. Вот четыре возможных токена и их значения:
> go right one single step
< go left one single step
-> go right the total amount of single steps that you've gone right, plus one,
before you previously encountered this token and reset this counter to zero
<- go left the total amount of single steps that you've gone left, plus one,
before you previously encountered this token and reset this counter to zero
Однако есть одна загвоздка - токены направлений, которые ваша программа должна уметь анализировать, будут представлены в следующем виде:
<<->-><<->->>->>->
... другими словами, они объединены, и ваша программа должна определить правильный приоритет направлений и количество шагов, которые нужно предпринять (заглядывая в будущее). Порядок приоритета выглядит следующим образом (от высшего к низшему приоритету):
->
<-
>
<
Если вы столкнулись <-
с тем, что с момента запуска или с момента последнего сброса ранее не было сделано никаких шагов влево, сделайте один единственный шаг влево. То же правило применяется к ->
, но затем для перехода вправо.
Ваша программа должна начинаться с 0, а ее результатом должно быть целое число со знаком, представляющее конечную конечную позицию.
Вы можете ожидать, что ввод всегда будет действительным (например, ничего подобного <--->>--<
).
Пример ввода:
><->><-<-><-<>>->
Шаги в этом примере:
step | token | amount | end position
------+-------+--------+--------------
1. | > | +1 | 1
2. | < | -1 | 0
3. | -> | +2 | 2
4. | > | +1 | 3
5. | <- | -2 | 1
6. | < | -1 | 0
7. | -> | +2 | 2
8. | <- | -2 | 0
9. | < | -1 | -1
10. | > | +1 | 0
11. | > | +1 | 1
12. | -> | +3 | 4
Для пояснения: выходные данные программы должны быть только конечной конечной позицией в виде целого числа со знаком. Приведенная выше таблица как раз иллюстрирует шаги, которые предпринял мой пример. Нет необходимости выводить такую таблицу, строку таблицы или даже просто конечные позиции шагов. Требуется только конечная конечная позиция в виде целого числа со знаком.
Самый короткий код, через неделю, выигрывает.
<-
него, - это сразу после него<
или a или a->
. Там нет никакого способа на этом языке , чтобы представить последовательность ,<-
то>
- что будетgo left the total amount of single steps that you've gone left, plus one, then go right one single step
. Это правильно и по замыслу?Ответы:
GolfScript, 46 символов
Это одна из самых линейных программ на GolfScript, которую я когда-либо писал - в ней нет ни одного цикла, условного или переменного присваивания. Все делается с помощью манипуляции со строками:
Во-первых, я заменяю каждое вхождение
->
на)
. Поскольку входные данные гарантированно действительны, это гарантирует, что любое оставшееся вхождение-
должно быть частью<-
.Затем я делаю две копии строки. Из первого экземпляра я удаляю символы
<
и-
, оставляя только>
и)
. Затем я дублирую результат, удаляю все)
s и каждый>
следующий за последним)
из второй копии, объединяю их и подсчитываю символы. Таким образом, по сути, я считаю:)
,>
после последнего)
и>
перед последним)
.Далее я делаю то же самое для другой копии, за исключением этого времени, считая
<
и<-
вместо>
и)
, и удаляя-
s до окончательного подсчета символов. Таким образом, я считаю:<-
,<
после последнего<-
и<
перед последним<-
.Наконец, я вычитаю второй отсчет из первого и вывожу результат.
источник
Python 2,7 -
154147134128 байтСерьезные изменения были внесены в работу этой программы. Я удалил старое объяснение, которое все еще можно найти в истории редактирования этого ответа.
Это грубо.
Он работает почти так же, как и другие ответы на этот вопрос, заменяя символы на входе действительными утверждениями на этом языке и выполняя их. Однако есть одно существенное отличие:
replace
это длинное слово. Да пошло оно.В чате @ProgrammerDan возникла идея использовать кортеж со строкой
;').replace('
в нем 4 раза, чтобы использовать предварительныйstr.format()
метод форматирования текста. Четыре экземпляра%s
находятся в строке во второй строке, каждый из которых берет свое значение из связанного элемента кортежа в конце. Поскольку они все одинаковые, каждый%s
заменяется на;').replace('
. Когда вы выполняете операции, вы получаете эту строку:Теперь это действительный код Python, который можно выполнить с помощью
exec
. Правильно, детка: вложенныеexec
s позволяют мне использовать строковые операции над кодом, которые должны выполнять строковые операции над кодом . Кто-нибудь, пожалуйста, убейте меня.Все остальное довольно просто: каждая команда заменяется кодом, который отслеживает три переменные: текущую позицию, количество прав с момента последней
->
и то же для левых и<-
. Все это выполняется, и позиция печатается.Вы заметите, что я делаю
raw_input(';')
, используя ';' скорее, чемraw_input()
как подсказка. Это сохраняет символы не интуитивно понятным способом: если бы я это сделалraw_input()
, мне пришлось бы заполнить кортеж).replace('
, и каждый экземпляр%s
имел бы «; \» перед ним, кроме первого . Наличие подсказки создает больше избыточности, поэтому я могу сохранить больше символов в целом.источник
list.index()
msgstr " возвращается,-1
когда не удается найти символ" .. нет. Это поднимаетIndexError
. Вы, возможно, перепутали это сstr.find
. На самом деле вы могли бы заменить[list('><rl').index(c)]
на['><rl'.find(c)]
.Perl
134131...9995 байтПринимает ввод в виде одной строки в stdin, например:
или:
Я разделил инструкции на «правые» операторы («>» и «->») и «левые» операторы («<» и «<-»). Преимущества этого состоят в том, что проще использовать параллелизм между левым и правым операторами, и нам не нужно делать ничего необычного для токенизации строки. Каждое «направление» рассматривается как операция замещения, в которой мы корректируем промежуточную сумму на количество шагов, предпринятых в этом направлении, игнорируя обратное направление, о котором заботится другая операция замещения. Вот менее преданный этому кодексу предок этого рода документации:
В предыдущей итерации этого кода все замены выполнялись за один проход. Преимуществом этого было сохранение прямого отображения между $ p / $ pos и позицией, которая будет возвращена в любой данный момент времени, но занимала больше байтов кода.
Если вы хотите использовать () 5.10.0, вы можете s / print / say / убрать еще 2 символа, но это не совсем мой стиль.
источник
Perl,
8877 байтВвод ожидается через STDIN, например:
Обновить
Нет необходимости преобразовывать строку в сумму, потому что
s//
она уже считается. :-)Первая версия
Ввод ожидается через STDIN, пример:
Объяснение:
Идея состоит в том, чтобы преобразовать строку направления в сумму, чтобы результат выводился простым
print eval
.>
прежде чем любой->
делает два шага, один за раз, а другой за другим->
. Неважно, какой из->
них следует за хотя бы одним из них. Внутренний счетчик сбрасывается после следующего->
, поэтому>
не вызывает дальнейших шагов, максимум составляет два шага. Затем->
добавьте один шаг для себя и сделайте все остальное>
после последнего->
.То же самое относится к обратному направлению с отрицательным, а не положительным количеством шагов.
Например:
><->><-<-><-<>>->
s/->/+1/
: Начните с направления вперед, потому что->
имеет наивысший приоритет.Например:
><+1><-<+1<-<>>+1
s/>(?=.*1)/+2/g
: Шаблон прогнозирования гарантирует, что преобразуются только те, которые>
прежде->
.Например:
+2<+1+2<-<+1<-<+2+2+1
s/>/+1/g
: Теперь остальные>
покрыты.Например:
+2<+1+2<-<+1<-<+2+2+1
s/<-/-1/g
: Аналог в обратном направлении.Например:
+2<+1+2-1<+1-1<+2+2+1
s/<(?=.*-)/-2/g
: В прогнозной схеме полное-1
из первых<-
не требуется, поскольку не осталось-
символов направления.Например:
+2-2+1+2-1-2+1-1<+2+2+1
s/</-1/g
: Оставшиеся<
после последнего<-
конвертируются.Например:
+2-2+1+2-1-2+1-1-1+2+2+1
print eval
: Рассчитать и вывести результат.Например:
4
источник
-p
: 74 байт Я изменил ваш ,s/>//g
чтобыy/>//
сохранить байты в каждом случае , который также позволил для удаления из скобок в выражении.Рубин, 141 байт
Ungolfed:
источник
l=1;r=1
может бытьl=r=1
и$><<o
может бытьp o
. Я думаю, что вы могли бы сильно побриться, заменив это заявление случая чем-то менее громоздким, возможно, чем-то вродеeval %w(o-=1;l+=1 o+=1;r+=1 o-=l;l=1 o+=r;r=1)['<>LR'.index c]
l=r=1;o=0;gets.gsub('->',??).scan(/<-|./){eval"o+=#{%w[-1;l+ -l;l 1;r+ r;r][$&[-1].ord%4]}=1"};p o
вы можете перейти к 94, используяruby -p
Д - 243
Гольф :
Без гольфа :
источник
С
148141140140:
141:
148:
С пробелами:
Наверное, гораздо больше возможностей для игры в гольф. Я в основном отказался от попыток манипулировать 4 переменными в троицах, которые захватывали lvalues (он продолжал появляться дольше и становился позже), но неплохой первый проход. Довольно простой проход массива. Принимает ввод в качестве аргумента командной строки, выводит через возвращаемое значение.
Вам понадобится
-std=c99
флаг, чтобы скомпилировать его с помощью gcc.РЕДАКТИРОВАТЬ: Да, уже поздно - пропустил некоторые очевидные вещи.
источник
main
:main(char*x,char**v)
. Тогда у вас есть 138 вместо 140.>><-
дает 0 вместо 1 или><->
0 вместо 2.char
и*
и заменить(*(x+1)==45)?(x++,o-=l+2,l=0):(o--,l++)
на(*++x==45)?(o-=l+2,l=0):(x--,o--,l++)
.JavaScript, 136
Unminified:
Как это устроено
Приведенный строковый ввод выглядит
s
примерно так:Он использует регулярное выражение для замены каждой команды набором команд, которые изменяют
z
(конечную позицию),l
(сохраненные движения влево) иr
сохраненные движения вправо. Каждое регулярное выражение выполняется в порядке приоритета.Для ввода выше это преобразуется
s
в:Довольно, не правда ли?
Наконец, мы
eval(s)
должны выполнить инструкции и предупреждения,z
которые содержат конечную позицию.источник
Javascript (116,
122,130)116:
122:
130:
источник
JavaScript [217 байт]
Вероятно, это может быть сокращено немного больше ...
источник
PHP,
284282Нет регулярных выражений
Ungolfed:
источник
str_split($i)
(1
по умолчанию для второго аргумента.) И$i
вероятно, должно быть$c
, правильно?$i
): P Исправлено!Другое решение Perl, 113 символов
Уже есть два ответа, которые побеждают это, это только для хихиканья. Он использует подход, основанный на наблюдениях Ильмари о значении токенов:
Немного взорвался:
источник