Производная Brainfuck
Давайте определим простой Brainfuck- подобный язык программирования. Он имеет двунаправленную ленту ячеек, и каждая ячейка содержит один бит. Все биты изначально равны 0. На ленте имеется движущаяся головка, первоначально в позиции 0. Программа - это строка над символами <>01!
, выполняемая слева направо, со следующей семантикой:
<
перемещает голову на один шаг влево.>
перемещает голову на один шаг вправо.0
ставит 0 в текущей ячейке.1
ставит 1 в текущей ячейке.!
переворачивает текущую ячейку.
Циклов нет, поэтому программа из n символов завершается ровно после n шагов. Программа скучна, если все ячейки содержат 0 в конце выполнения, и захватывающая, если есть хотя бы один 1. Обратите внимание, что размер ленты не указан, поэтому в зависимости от реализации он может быть двусторонним бесконечным или круговой.
Пример программы
Рассмотрим программу 1>>>!<<<<0>!>>>!
. На бесконечной ленте выполнение выполняется следующим образом:
v
00000000000000 Put 1
v
00000100000000 Move by >>>
v
00000100000000 Flip
v
00000100100000 Move by <<<<
v
00000100100000 Put 0
v
00000100100000 Move by >
v
00000100100000 Flip
v
00000000100000 Move by >>>
v
00000000100000 Flip
v
00000000000000
В конце все ячейки равны 0, так что эта программа скучная. Теперь давайте запустим ту же программу на круговой ленте длиной 4.
v
0000 Put 1
v
1000 Move by >>>
v
1000 Flip
v
1001 Move by <<<< (wrapping around at the edge)
v
1001 Put 0
v
1000 Move by > (wrapping back)
v
1000 Flip
v
0000 Move by >>>
v
0000 Flip
v
0001
На этот раз есть ячейка со значением 1, поэтому программа захватывающая! Мы видим, что скучная или захватывающая программа зависит от размера ленты.
Задание
Ваш ввод представляет собой непустую строку, <>01!
которая представляет программу на вышеуказанном языке программирования. Массив символов также является приемлемым форматом ввода. Программа гарантированно будет скучной при запуске на бесконечной ленте. Ваш вывод должен быть списком длин ленты, на которых программа является захватывающей. Обратите внимание, что вам нужно тестировать программу только на лентах, которые короче длины программы.
Решение с наименьшим количеством байтов на каждом языке является победителем. Применяются стандартные правила игры в гольф .
Контрольные примеры
> : []
110 : []
1>0<! : [1]
0>>1>0<<>! : [1]
1>>>!<<<<0>!>>>! : [2, 4]
!<!<><<0>!>!<><1!>>0 : [2]
>>!>><>001>0<1!<<!>< : [1, 2, 3]
1!><<!<<<!!100><>>>! : [1, 3]
!!1>!>11!1>>0<1!0<!<1><!0<!<0> : [3, 4]
<><<>>!<!!<<<!0!!!><<>0>>>>!>> : [1, 2, 4]
0>>><!<1><<<0>!>>!<<!!00>!<>!0 : [3]
0000!!!!><1<><>>0<1><<><<>>!<< : []
!>!>!>!>!>1>!>0<!<!<!<0<!<0<!<!<!<1>!>0<<! : [1, 2, 5, 7]
<!!>!!><<1<>>>!0>>>0!<!>1!<1!!><<>><0<<!>><<!<<!>< : [1, 2, 4, 5]
!>1<<11<1>!>!1!>>>0!!>!><!!00<><<<0<<>0<<!<<<>>!!> : [1, 2, 3, 5, 6]
<>01!
?Ответы:
Haskell, 119 байт
Попробуйте онлайн!
Функция
#
является интерпретатором для одной командыc
. Вся программаp
управляетfold
ING#
со стартовой лентой вp
.f
выполняетсяp
для каждой ленты и сохраняет те, где сумма ячеек составляет не менее 1.источник
n<-[1..length p] ... 0<$[1..n]
кажется довольно длинным, должен быть более короткий путь.n
как результата, поэтому, если вы построили0<$[1..n]
другой путь (скажем, с помощьюscanr(:)
), вам нужно будет принятьlength
его. (Я также попытался использовать1
(для заменыlength
наsum
) илиFalse
(чтобы использоватьor
для теста) вместо0
, но это не получилось короче.)n<-init$scanr(:)[]$0<$p ... n
что на 2 байта короче, но он возвращает список начальных лент вместо их длины, например[[0],[0,0,0]]
. С небольшим изгибом правила можно было видеть ленты как одинарные числа, так что, возможно, все в порядке.init$
можно заменить, добавив в[0]
качестве начального списка, но он все еще не стал достаточно коротким. Я думаю, что унарный допускается только для языков без более естественного представления чисел .Stax ,
5654433835 байт CP43742 байта в распакованном виде,
Запускать и отлаживать онлайн!
-2 байта за комментарий @recursive
объяснение
Я буду использовать версию с префиксом
i
(то естьi%fz(y{{|(}{|)}{B!s+}{0_]e&}4ls"><! "I@!F|a
), чтобы объяснить, и я объясню, почемуi
можно удалитьКод для запуска программы:
источник
i
чека.0]*
can be replaced withz(
. Also, if you change the string to "<>!", then0
and1
will give index -1, so that way your block list only needs 4 blocks, instead of 5. This will work since the0
and1
handlers are identical anyway.CJam,
57564946 bytes-7 thanks to @MartinEnder
Try it online!
источник
Perl 5,
83827977 bytesIncludes
+3
for-F
Give instructions as one line on STDIN
Try it online!
источник
Perl 5 (
-F
), 101 bytesTry it online!
источник
Red, 243 bytes
Try it online!
Prety verbose and straightforward implementation. Red's 1-indexing doesn't allow me to reduce the byte count by using modular arithmetic for looping through the circular tapes.
Ungolfed
источник
Python 2,
139135133132131 bytes-3 bytes thanks to Mr. Xcoder
Try it online!
источник
Retina, 121 bytes
Try it online! Explanation:
Create an array of tapes of each length up to the length of the input program.
Loop until the program is consumed.
If the next character in the program is a 0 or 1, change the first character on each line to that character.
If it is a
!
then toggle the first character on each line.If it is a
>
or<
then rotate the line. (Easier than moving the head.)Delete the instruction and end the loop.
Keep only the exciting lines.
Count the length of each line.
источник
JavaScript (ES6),
126118 bytesSaved 3 bytes thanks to @user71546
Takes input as an array of 1-character strings.
Try it online!
источник
t.some(x=>x)?
by+t.join``?
instead check the array as digits (and 0 indicates an all-zero tape), but 3 bytes less.APL (Dyalog Unicode),
796454 bytes (Adám's SBCS)Try it online!
-15 thanks to Adám (forgot about monadic
⍸
).-10 thanks to ngn.
источник
↓
). I'll look into it and update. :)↓
you'll need a;
, no?MATL,
4639 bytesTry it online! Or verify all test cases.
How it works
источник
APL (Dyalog Unicode),
19278 bytesTry it online! (non-flattened result)
Try it online! (flattened)
After some time spent banging my head against the wall, I decided to make a Tradfn instead of a Dfn. This is the result. Smarter people than me may be able to golf the heck out of this.Surprise, surprise, someone smarter than me did golf the heck out of this. Thank you Adám for 114 bytes.
He said:
The function assumes
⎕IO←0
.How?
(This explanation uses an "ungolfed" version to facilitate reading)
источник
t←l⍴0
bet←l⍴i←0
, and removing the line above it. You can also save another by changingt[i|⍨≢t]←1-t[i|⍨≢t]
tot[i|⍨≢t]←~t[i|⍨≢t]
.∇
s?∇
s? It is a tacit function.Jelly, 41 bytes
Try it online!
источник
C (clang), 171 bytes
Try it online!
Had to use clang, since using
char*p,t[l=strlen(S)]
as the initialisation expression for some reason makes GCC think I want to declarestrlen
instead of calling it.Pretty straight-forward: Runs the program on circular tapes of decreasing length, outputting any length that resulted in a 1 somewhere on the tape.
Tried shortening the tangle of the ternary operators, but ended up needing more parenthesis than was healthy.
источник
i=0,bzero(t,l)
instead ofmemset(t,i=0,l)
and*p-62?t[i]=*p^33?*p-48:t[i]^1:(i=~i+l?i+1:0)
instead of*p==62?i=i^l-1?i+1:0:*p^33?t[i]=*p-48:(t[i]^=1)