Условия if...else

image
Доброго времени суток Хабралюди!

Сегодня для меня великий день.
В вопросах я писал о краткой справке для новичков и профессионалов, думалось мне что я сейчас быстро окунусь в язык, сделаю всем добро и пойду дальше изучать свой Perl.
Но как всегда всё пошло не так...

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

Иногда запускал на компьютере BrainfuckIDE и экспериментировал. Эксперименты были достаточно плодотворные, и уже через 5-6 часов я изучил его досконально. Помнил все алгоритмы сложения, вычитания, перемещения, копирования, деления и умножения. Элементарные сложение, вычитание и перемещение я подсмотрел на каком то из сайтов, остальное додумал сам.

Потом посерфил поискал в интернете и увидел что на нём оказывается можно делать условия(то было для меня удивлением). Главный вопрос: Как?

Не став изучать и принтскрить алгоритм себе в мозг, сел с тетрадочкой в угол и начал думать.
Думал я до эффекта полной абстракции от мира сего. Ушло две тетрадки, в которых я пробовал кучу разных вариантов, перемещал, копировал, пытался как то сравнивать, расплывчатые идеи при их реализации на листке, к концу приводили к очередному хаосу в моей голове.

Поставив перед собой цель написать программу, которая будет сравнивать введённое число с заведомо известным, и выводить результат(равно или не равно), я два дня практически без отдыха(только сон, еда, туалет и dota) сидел и воображал как это реализовать, на столь запутанном прекрасном языке.

Лёг спать достаточно поздно(10 утра), не мог заснуть когда в моей голове вертелось такое.

Проснувшись ближе к вечеру, взял недописанную вторую тетрадь и начал писать, честно говоря, я сам не понимаю как к такому алгоритму я пришёл, но на листочке через 2 часа он казался рабочим. Сел за нэтбук, на стационарном в это время ставилась новая ось.
Начал переписывать с листочка, оказалось я не учёл очень много вопросов и подводных камней, но алгоритм всё ещё казался верным.
За компьютером его отладка заняла не больше часа, как вдруг, перед моими глазами программа очнулась, работая именно так, как я того хотел.
Ощущение непередаваемое, такое чувство что ты планету открыл. Первые мои слова были: "Б*ля Ну вот, наконец то!". Немного отладив, убрал кучу + и -, заменив их на циклы всё работало как в сказке.

Не сильно закидывайте помидорами и тухлыми яйцами, но я попробую рискнуть и привести код, который написал. Смотрите:
,[>+>+<<-]>>[<<+>>-]                   # Копируем введённое значение в 1 ячейку
+++++ +++++[<----->-]<---              # Уменьшаем её на ascii код числа с которым сравниваем
>>+>>+<<<<                             # Счётчики для циклов
[                                      # Цикл Если n != 5
    [-]+++++ +++++[>+++++<-]>+++.      # Выводим 5
    [-]<++++++++[>++++<-]>.            # Выводим пробел
    [-]<++++++++[>++++<-]>+.           # Выводим восклицательный знак
    [-]<++++++++++[>++++++<-]>+.       # Выводим знак равенства
    [-]<++++++++[>++++<-]>.<<.         # Выводим пробел и число n
>>>>>-<<-]                             # Обнуляем счётчики, что бы второй цикл не выполнился
>>[                                    # Цикл иначе, практически всё тоже самое
    [-]+++++ +++++[>+++++<-]>+++.
    [-]<++++++++[>++++<-]>.
    [-]<++++++++++[>++++++<-]>+.
    [-]<++++++++[>++++<-]>.<<<<.
>>>>>-]


Как видите, основная идея в том, что бы цикл выполнялся тогда и только тогда, когда остаток от разности чисел n и ascii кода числа с которым сравнивают != 0.

Думаю это будет достаточно наглядный пример для начинающих, а от Вас Уважаемые гуру и ниндзя этого языка, прошу совета и возможно критики.

Ещё интересуют вопросы:
  • Как остальные решили бы данный вопрос?
  • Правильно ли я выбрал алгоритм, или можно обойтись более простым?
  • Что здесь можно ещё оптимизировать, и можно ли вообще?
17 марта 2012, 03:29
34
systemiv 79,1

комментарии (19)

+3
DjPhoeniX #
!™
+12
ffriend #
Эх, было бы у меня столько свободного времени…
+2
systemiv #
Сам в поисках работы. Пока время есть, буду вытворять разные крутые штуки, которые возможно кому то помогут
+4
facha #
Когда-то писал сравнение 2-х чисел на brainfuck-e. Есть конструкция if-then-else. Не уверен, насколько там все корректно, но работало.

,>,< # вводим 2 числа
[->-<] # if a=b (вычитаем из обоих 1 пока первое не обнулится)
>[.>>-<] # else (выводим разницу если числа различаются)
>+[-.....] # then (выводим разницу (0) 5 раз если числа одинаковы)
+1
systemiv #
По моему достаточно красиво. А как Вы писали алгоритм? Мне пришлось с этим столкнуться в первые 10-15 минут работы с этим языком. Я пробовал стандартную блочную схему алгоритма, но от неё мало толку, если только в уме переводить всё на Си, и писать алгоритм на нём. Так же пробовал просто писать несколько байт, и на каждой новой строчке, их преобразования. В этом случае я запутался в итерациях. Есть ли универсальный метод алгоритмизации?
0
Mrrl #
Метод хороший. Но интереснее, когда этот прием приходится использовать не в конце, а в середине программы — тогда после условного сдвига надо как-то вернуться на то же место ленты.
0
Nicolette #
+11
systemiv #
Это слишком простой выход, смотреть на чужие решения
+2
Mrrl #
Я бы написал как-нибудь так:
,[->+>+<<]  # вводим число и дублируем его. На ленте _0 n n
++++++[->>--------->+++++>+++++++++<<<<]  # вычитаем из второй копии 54, а дальше создаем 30 и 54
>>+>++>- # подправляем сдвиги, чтобы получилось 0 n n-53 32 53
.<. # печатаем '5 '
<[>+.-<[-]] # если n-'5'!=0, печатаем '!', переделав его из пробела, и обнуляем счетчик
>>++++++++.<.<<. # печатаем "= n".

Интереснее было бы в случае равенства печатать 5 == n. Тогда так:
,[->+>+<<] 
++++++[->>--------->+++++>+++++++++<<<<]  
>>+>++>->+ 
.++++++++<. # сразу после вывода 5 переделываем его в =
<[>+.->>-<<<[-]] # если n-'5'!=0, печатаем '!', переделав его из пробела, и обнуляем счетчики
>>>[<.>-] # если надо, печатаем =
<.<.<<. # печатаем "= n".

Коды не проверялись.
0
Disasm #
Теперь для вас задача — сделать обращение к массиву по переменному индексу.
0
AbnormalHead #
Это тоже решено. Можете посмотреть как делали морской бой на brianfuck. Там же есть описание как сделать более универсальное if-then-else.
0
Disasm #
Да оно-то решено, но автору наверняка понравится повторить это самостоятельно.
0
Mrrl #
Есть задача проще — ввести два символа m,n и если m<n, напечатать «m<n» а иначе — «m>=n».
0
systemiv #
Я щас хочу выполнить сравнение двух введённых чисел и результат выводить >, < или ==. Но всё равно за задачку спасибо.
+4
ilyaplot #
Мне, как незнакомому с этим языком, свернуло мозг напрочь.
Это потрясающе :)
+2
Aga #
,>, //считываем
[< (0) [->>+>+<<<] >>>[-<<<+>>>] < (2) >>+<< [[-]>>-<<] <-<->] //делаем магию
после магии:
если числа равны то в 0ой ячейке 0 в 4ой 0
если первое число больше то в 4ой 1
если первое меньше то в 4ой 0
+ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ // для вывода
<[ >+< [-]] // числа не равны
>>>>[ <<<-->>> [-]] // первое число меньше
<<<. //вывод

может кому будет интересно
вводятся два символа, и программа выводит >, < или =
0
Mrrl #
Интересный способ
0
Mrrl #
А еще можно так:

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

Без комментариев :)
+3
Keyten #
Стоило бы в заголовке написать, что это Brainfuck — а то с приходом хабов это плохо видно

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.