Генерация программы Brainf_ck, которая выводит строку заданной длины

11

Ваш друг пытается взломать хранилище, которое имеет своеобразную систему блокировки: для этого требуется определенное количество мягких ударов в определенном месте. Ваш друг обнаружил номер (который находится в диапазоне 1 ... 99999) и обладает гаджетом, который производит необходимые удары. Тем не менее, гаджет является интерпретатором Brainfuck! Таким образом, ваш друг должен кормить его программой Brainfuck, которая, очевидно, должна быть максимально короткой (ввод-вывод гаджета медленный).

Твоя задача - помочь ему! Напишите программу или подпрограмму на любом языке, которая принимает в качестве входных данных число Nи выводит программу Brainfuck, которая не принимает и выводит строку печатных символов ASCII (исключая пробельные символы - коды в диапазоне 33 ... 126) длины N.

Пример: для ввода 10вывод может быть

+++++++++++++++++++++++++++++++++..........

(но я уверен, что это может быть сокращено!)

Ваша оценка будет суммой длин ваших выходных данных для следующих значений N(это случайные числа):

55
68
15
28
841
838
522
846
4898
9004
9363
3810
13230
67175
37231
44701

О, и вы будете передавать свой код (программу-генератор) своему другу через Twitter. Поэтому убедитесь, что это 140 символов или меньше!


PS Язык Brainfuck имеет много вариантов. Давайте предположим, что лента бесконечна в обоих направлениях (или «круглая и достаточно большая»), а ячейки имеют 32-битную емкость int (конечную и способны хранить числа до 99999). Кроме того, без упаковки: когда ячейка переполняется, машина самоуничтожается!

anatolyg
источник
2
«следующие значения N (это случайные числа)» напомнили мне о xkcd.com/221
Cirpis
Просто для справки, пробел (код символа 32) обычно включается в диапазон ASCII для печати. Это не имеет большого значения для задачи, так как вы определили диапазон явно.
Мартин Эндер
3
Можем ли мы предположить, что клетки в brainfuck являются целыми числами произвольной ширины? Если нет, как и когда они обертывают?
orlp
1
Было бы неплохо предположить, по крайней мере, возможность содержать 67175 + несколько.
orlp
@anatolyg Я понял это позже. Сожалею.
Esolanging Fruit

Ответы:

3

Python 2, оценка: 1021

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

Вот скрипт Python размером 102 байта, который делает эту работу:

n=input()
s='>'
while n:
    s+='>'+'+'*(n%5+1);n/=5
print s+'[->[-<+++++>]<<]<+++++++[>+++++<-]>>[-<.>]'

Идея состоит в том, чтобы использовать кодирование базы 5 для N (наилучшая база, по крайней мере, для текущих входов, которые, кстати, не кажутся очень «случайными», похоже, что они были произвольно выбраны OP), и написать общий алгоритм Брейнфука для декодировать число произвольной длины (число кодируется с каждой цифрой, увеличенной на единицу для определения конца преобразования). Я решил напечатать символ 35 #, символ 36 $эквивалентен.

Вы можете запустить следующий скрипт bash, чтобы получить результат:

i=0
while read p; do
  i=$((i+`echo $p | python convert.py | wc -m`))
done
echo $i

С более продвинутой программой, которая заменяет кодирование умножением для небольших чисел и выбирает лучшую базу для кодирования каждого числа, я могу достичь 958 символов Brainfuck, но Python слишком многословен (и я довольно плохой / ленивый игрок в гольф) по порядку получить конвертер в 144 байта!

rixm
источник
Эта великолепная идея! Возможно, я воспользуюсь им один раз, чтобы улучшить этот ответ (написал скрипт на Python, чтобы получить оценку менее 950, но я не знаю ни одного языка для игры в гольф, чтобы сделать его достаточно коротким).
Анатолий
8

BrainF ***, оценка: 193 313

Это не менее 140 символов (это 147, так близко !!), так что это не может победить, но я подумал, что это круто.

Печатает 43 знака плюс, затем Nпериоды. Не очень оптимальный.

>++++++[>+++++++<-]>+[->+>+<<]>[->.<]<<+[[-]>[-],[+[-----------[>[-]++++++[<------>-]<--<<[->>++++++++++<<]>>[-<<+>>]<+>]]]<]>>>+++<<<<[>>>>.<<<<-]

Если кто-то может помочь сократить это, я буду рад.

mdc32
источник
Я предполагаю, что с Brainfuck было бы достаточно создать «подпрограмму», которая получает входные данные на ленте - не нужно читать со «стандартного устройства ввода».
anatolyg
@anatolyg Это делает это намного проще - вероятно, около 80 или 90 символов. Должен ли я изменить это?
mdc32
5

J, Общая оценка = 1481

(Для моей предыдущей записи и объяснения проверьте историю изменений.)

f10=.('>++++++++++<';'')rplc~;@([:(<@('+++++[>+++++++<-]>>+',;@((<'[>++++++++++')#~#)),[<@(']',~'<-','<.>'#~],[,])"0 #-i.@# )10#.inv])

Эта функция генерирует вложенные петли BF на основе цифр base10 входного номера. Проверка всех разумных оснований и выбор наименьшего кода BF улучшит счет с небольшим количеством.

Программы BF для тестового набора:

   f10 every 55 68 15 28 841 838 522 846 4898 9004 9363 3810 13230 67175 37231 44701
+++++[>+++++++<-]>>+[>++++++++++[-<<.....>>]<-<.....>]                                                                                     
+++++[>+++++++<-]>>+[>++++++++++[-<<......>>]<-<........>]                                                                                 
+++++[>+++++++<-]>>+[>++++++++++[-<<.>>]<-<.....>]                                                                                         
+++++[>+++++++<-]>>+[>++++++++++[-<<..>>]<-<........>]                                                                                     
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[-<<<........>>>]<-<<....>>]<-<.>]                                                             
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[-<<<........>>>]<-<<...>>]<-<........>]                                                       
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[-<<<.....>>>]<-<<..>>]<-<..>]                                                                 
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[-<<<........>>>]<-<<....>>]<-<......>]                                                        
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[-<<<<....>>>>]<-<<<........>>>]<-<<.........>>]<-<........>]                      
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[-<<<<.........>>>>]<-<<<>>>]<-<<>>]<-<....>]                                      
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[-<<<<.........>>>>]<-<<<...>>>]<-<<......>>]<-<...>]                              
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[-<<<<...>>>>]<-<<<........>>>]<-<<.>>]<-<>]                                       
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[>++++++++++[-<<<<<.>>>>>]<-<<<<...>>>>]<-<<<..>>>]<-<<...>>]<-<>]                 
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[>++++++++++[-<<<<<......>>>>>]<-<<<<.......>>>>]<-<<<.>>>]<-<<.......>>]<-<.....>]
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[>++++++++++[-<<<<<...>>>>>]<-<<<<.......>>>>]<-<<<..>>>]<-<<...>>]<-<.>]          
+++++[>+++++++<-]>>+[>++++++++++[>++++++++++[>++++++++++[>++++++++++[-<<<<<....>>>>>]<-<<<<....>>>>]<-<<<.......>>>]<-<<>>]<-<.>]          

Вычисление баллов на тестовом наборе:

   +/#@> f10 each 55 68 15 28 841 838 522 846 4898 9004 9363 3810 13230 67175 37231 44701
1481
randomra
источник
3

Пиф, 1702

Восстановите числа, используя коэффициенты N + x.

+holN+]++">>"*"+"Q"<<"mjk(">>"j">"m*"+"kP+Qd"<[[->[->+>+<<]>>[-<<+>>]<<<]>[-]>[-<<+>>]<<<]>"*"-"d"<<")50"++++++[>++++++<-]>>[<.>-]"
orlp
источник
Для 2этого выводы ++. теперь, который ничего не печатает в BF.
Рандомра
@randomra Хороший улов, это произошло при обновлении, я исправлю это, дай мне несколько.
orlp
@randomra Должен быть исправлен, сделал счет немного выше (конечно).
orlp
3

CJam, 52 74 108 байт, всего = 1304 1244 1210

ri5b_,1>{(_3<{\(@5*+}*\+}*W%)\{T+_2>:T5*-_0>"-+"=\z*}%\T+'+*a+W%{"[->+++++<]>"\}*">x[>x<-]<[->>.<<]"'x/'+6**

Тестовый скрипт (медленный в онлайн-переводчике):

q~]
{
_[0:T;
5b_,1>{(_3<{\(@5*+}*\+}*W%)\{T+_2>:T5*-_0>"-+"=\z*}%\T+'+*a+W%{"[->+++++<]>"\}*">x[>x<-]<[->>.<<]"'x/'+6**
]s
_[L:RL@0\
"-+><.]"['('){+\_{)}0?@\}{@\+\_{)}0?}{R1$c+:R;}]:`"]a"{{_aa+1$4G#%{:~~1}{;0}?}g}`+a+er:~:~
];R,@=!"Error."N+*o
}%s,
jimmy23013
источник
Я не видел часть о самоуничтожении. Но оно никогда не переполнится.
jimmy23013
Как это работает?
Анатолий
@anatolyg Первая версия просто генерирует число в базе 5. Более поздние версии добавили специальный регистр для первых двух цифр, а также использовали декремент.
jimmy23013
@ user23013 Ой, прости, не видел изменений в спецификации. (
Обновил
2

Befunge-98, N + 41, всего = 193281

&>'+\:v
v^-1,\_
' >1-:v
>v^,+'_
,'    :
>ff3++^
>2f*+v
^>/9+:,
>'>,61v
, v*6+<
^/2,:<@
v >+2+,
>'<,']^

Я знаю, что это плохо, но я чувствовал, что хочу написать немного Befunge сегодня. Лучшая часть Befunge состоит в том, что программы даже менее понятны, чем настоящие языки гольфа, особенно когда они повторно используют код: D

Использует алгоритм, аналогичный ответу CJam Мартина Бюттнера :

(N +'s)>+++++++++++++++++++++++++++++++++<[->.<]
PurkkaKoodari
источник
1

CJam, 40 + N, всего: 193265

'+33*'>'+l~*"[<.>-]"

Просто для начала, вот базовое решение. Он генерирует следующий код:

+++++++++++++++++++++++++++++++++>_[<.>-]

где _есть Nкопии +.

Запустите генератор здесь.

Мартин Эндер
источник
1

Befunge-93 - 24 + N, всего = 193009

&>">>]-<]-<++++>[++++>[+++"v
v  ,,,,,,,,,,,,,,,,,,,,,,, <
>:v
,v_@
"1
.-
"
^<

При этом используется префикс +++[>++++[>++++<-]<-]>>для установки первого индекса ленты на «0» с 24 символами. Программа Befunge очень проста и выводит ее вместе с N '.' персонажи.

объект
источник
Теперь, когда я вижу это, я не знаю, почему я думал, что мой цикл будет лучше ...
Мартин Эндер