]]> ]]>
Править | Обсудить | История

Brainfuck

Дата создания:
1993
Создан под влиянием:
Повлиял на:
Парадигма:
Типизация:
Принятые расширения файлов:
.bf
Диалекты:
Реализации и версии (свернуть все | развернуть все):
Язык программирования

Brainfuck — один из известнейших эзотерических языков программирования, отличающийся особым минимализмом. Состоит из восьми команд, каждая из которых записывается одним символом.

Brainfuck был создан в 1993 году Урбаном Мюллером (Urban Müller), и авторская реализация остается фактическим стандартом языка. Его базовая спецификация достаточно проста, и он не был стандартизирован. Существует ряд любительских реализаций, ни одна из которых не представляет коммерческой ценности.

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

Brainfuck был изобретен при попытке создать Тьюринг-полный язык программирования с наименьшим возможным компилятором. Авторский компилятор имел размер 240 байт, а более поздние реализации достигают менее 200 байт.

Теоретически Brainfuck действительно обладает свойством Тьюринг-полноты и следовательно, может выполнить любую задачу. На практике, впрочем, этот язык совершенно непригоден для решения задач из реальной жизни; выполнение даже простейших заданий становится вызовом для разработчика. Поэтому Brainfuck используется исключительно как математическая модель или для развлечения.

Создателя Brainfuck вдохновил язык FALSE, а его 6 команд (за исключением команд ввода-вывода) в точности совпадают с командами языка P”, но остается неизвестным, влиял ли последний на разработку Brainfuck.

Brainfuck использует модель машины, напоминающую машину Тьюринга и состоящую из следующих элементов:

  • программа — последовательность односимвольных команд языка и, возможно, других символов (при обработке игнорируются);
  • указатель инструкций — указывает на команду, которая будет исполнена на следующем шагу, после ее исполнения передвигается на другую (обычно следующую справа) команду;
  • память — моделируется одномерным массивом ячеек, в каждой ячейке хранится один байт; начальное значение ячейки — ноль;
  • указатель данных — указывает на текущую ячейку памяти; начальное значение — самая левая ячейка массива; по команде двигается либо изменяет значение, хранящееся в текущей ячейке;
  • потоки ввода и вывода — последовательности байтов в кодировке ASCII.

Команды языка:

  • + : увеличить на 1 значение в текущей ячейке;
  • - : уменьшить на 1 значение в текущей ячейке;
  • > : сдвинуть указатель данных на одну ячейку вправо;
  • < : сдвинуть указатель данных на одну ячейку влево;
  • [ : “начало цикла”: если значение в текущей ячейке положительно, сдвинуть указатель инструкций на одну команду вправо, иначе сдвинуть его на команду, следующую за парной командой ];
  • ] : “конец цикла”: если значение в текущей ячейке нулевое, сдвинуть указатель инструкций на одну команду вправо, иначе иначе сдвинуть его на команду, следующую за парной командой [. Может также быть представлен как безусловный переход указателя инструкций на парную команду [, т.к. [ выполняет отдельную проверку на вход в тело цикла;
  • . : вывести значение в текущей ячейке в поток вывода как символ с соответствующим ASCII-кодом;
  • , : прочитать символ из потока ввода и сохранить его ASCII-код в текущую ячейку.

Следует отметить, что из-за специфики языка команды условного перехода [ и ] используются при реализации практически всех операций, являющихся элементарными в других языках (присвоение значения, математические и логические операции и т.д.).

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

Элементы синтаксиса:

Бесконечный цикл [-]+[]
Цикл с предусловием condition[...]
Цикл с постусловием [...condition]
Цикл for - next для диапазона целых чисел с инкрементом на 1 [-][...+]
Цикл for - next для диапазона целых чисел с декрементом на 1 [-]-[...-]

Примеры:

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck), Müller's Brainfuck 2.0, weave.rb

Существует много способов сказать “Hello, World!” на Brainfuck. Ниже приведен самый простой из них: использовать только одну ячейку памяти и последовательно изменять ее значение на ASCII-код каждой буквы сообщения. Каждая строка примера выводит один символ.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
+++++++++++++++++++++++++++++.
+++++++.
.
+++.
-------------------------------------------------------------------.
------------.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++.
++++++++++++++++++++++++.
+++.
------.
--------.
-------------------------------------------------------------------.

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck), Müller's Brainfuck 2.0, weave.rb

В этом примере используется три основные ячейки памяти — первая для прописных букв ‘H’ и ‘W’, вторая для строчных букв и третья для знаков препинания ‘,’, ‘ ‘ и ‘!’ — и три дополнительные индексные ячейки для сокращения записи изменений ASCII-кодов. Использованная память выглядит следующим образом:

(индексная ячейка 1) (ячейка прописных букв) (индексная ячейка 2) (ячейка строчных букв) (индексная ячейка 3) (ячейка знаков препинания)

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

Числа Фибоначчи:

Пример для версий EsCo 0.511 (Brainfuck), Müller's Brainfuck 2.0, weave.rb

В примере используется итеративное определение чисел Фибоначчи: два последних числа хранятся в ячейках-переменных c4 и c5 (в начале c4=0, c5=1), число c5 посимвольно выводится на печать (это действие занимает большую часть кода), затем вычисляется следующее число (c6 = c5+c4), и числовая пследовательность сдвигается на одно число вперед (c4 = c5, c5 = c6). Низкоуровневое описание приведено в комментариях к коду, запись “cXvY” означает, что после выволнения команд в строке указатель данных находится в ячейке X, и значение в этой ячейке равно Y.

Классический интерпретатор Brainfuck использует переменные типа byte для хранения значений в ячейках памяти, и 14-16 числа Фибоначчи вызовут ошибку переполнения. Написание длинной арифметики на Brainfuck — задача достаточно трудоемкая, поэтому в примере предполагается, что в ячейках памяти могут храниться числа типа integer.

++++++++++++++++++++++++++++++++++++++++++++		c1v44 : ASCII code of comma
>++++++++++++++++++++++++++++++++			c2v32 : ASCII code of space
>++++++++++++++++					c3v11 : quantity of numbers to be calculated
>							c4v0  : zeroth Fibonacci number (will not be printed)
>+							c5v1  : first Fibonacci number
<<							c3    : loop counter
[							block : loop to print (i)th number and calculate next one
>>							c5    : the number to be printed

							block : divide c5 by 10 (preserve c5)
>							c6v0  : service zero
>++++++++++						c7v10 : divisor
<<							c5    : back to dividend
[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]			c5v0  : divmod algo; results in 0 n d_n%d n%d n/d
>[<+>-]							c5    : move dividend back to c5 and clear c6
>[-]							c7v0  : clear c7

>>							block : c9 can have two digits; divide it by ten again
>++++++++++						c10v10: divisor
<							c9    : back to dividend
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]				c9v0  : another divmod algo; results in 0 d_n%d n%d n/d
>[-]							c10v0 : clear c10
>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]c12v0 : print nonzero n/d (first digit) and clear c12
<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]] c11v0 : print nonzero n%d (second digit) and clear c11

<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]	c8v0  : print any n%d (last digit) and clear c8
<<<<<<<.>.                                              c1c2  : print comma and space
							block : actually calculate next Fibonacci in c6
>>[>>+<<-]						c4v0  : move c4 to c6 (don't need to preserve it)
>[>+<<+>-]						c5v0  : move c5 to c6 and c4 (need to preserve it)
>[<+>-]							c6v0  : move c6 with sum to c5
<<<-							c3    : decrement loop counter
]
<<++...							c1    : output three dots

Факториал:

Пример для версий EsCo 0.511 (Brainfuck), Müller's Brainfuck 2.0, weave.rb

В примере используется итеративное определение факториала: последний вычисленный факториал хранится в ячейке-переменной c6 и на каждом шагу умножается на очередное число, хранящееся в c5. Низкоуровневое описание приведено в комментариях к коду, запись “cXvY” означает, что после выволнения команд в строке указатель данных находится в ячейке X, и значение в этой ячейке равно Y.

Классический интерпретатор Brainfuck использует переменные типа byte для хранения значений в ячейках памяти, и уже 6! вызовет ошибку переполнения. Написание длинной арифметики на Brainfuck — задача достаточно трудоемкая, поэтому в примере предполагается, что в ячейках памяти могут храниться числа типа integer.

+++++++++++++++++++++++++++++++++			c1v33 : ASCII code of !
>++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++				c2v61 : ASCII code of =
>++++++++++						c3v10 : ASCII code of EOL
>+++++++						c4v7  : quantity of numbers to be calculated
>							c5v0  : current number (one digit)
>+							c6v1  : current value of factorial (up to three digits)
<<							c4    : loop counter
[							block : loop to print one line and calculate next
>++++++++++++++++++++++++++++++++++++++++++++++++.	c5    : print current number
------------------------------------------------	c5    : back from ASCII to number
<<<<.-.>.<.+						c1    : print !_=_

>>>>>							block : print c6 (preserve it)
>							c7v0  : service zero
>++++++++++						c8v10 : divizor
<<							c6    : back to dividend
[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]			c6v0  : divmod algo borrowed from esolangs; results in 0 n d_n%d n%d n/d
>[<+>-]							c6    : move dividend back to c6 and clear c7
>[-]							c8v0  : clear c8

>>							block : c10 can have two digits; divide it by ten again
>++++++++++						c11v10: divizor
<							c10   : back to dividend
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]				c10v0 : another divmod algo borrowed from esolangs; results in 0 d_n%d n%d n/d
>[-]							c11v0 : clear c11
>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]c13v0 : print nonzero n/d (first digit) and clear c13
<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]] c12v0 : print nonzero n%d (second digit) and clear c12
<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]	c9v0  : print any n%d (last digit) and clear c9

<<<<<<.							c3    : EOL
>>+							c5    : increment current number
							block : multiply c6 by c5 (don't preserve c6)
>[>>+<<-]						c6v0  : move c6 to c8
>>							c8v0  : repeat c8 times
[
<<<[>+>+<<-]						c5v0  : move c5 to c6 and c7
>>[<<+>>-]						c7v0  : move c7 back to c5
>-
]
<<<<-							c4    : decrement loop counter
]

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck)

Этот пример является переводом на Ook! этого примера на Brainfuck.

Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? 
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. 
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook? 
Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. 
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? Ook. Ook. Ook. Ook. 
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. 
Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. 
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook. Ook. 
Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. 
Ook! Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. 
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook! Ook! Ook? Ook! 
Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? 
Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook? 
Ook! Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. 
Ook. Ook. Ook! Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. 
Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook? Ook! Ook. Ook. Ook? Ook. Ook? Ook! Ook. 
Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! 
Ook! Ook! Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! 
Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook. Ook! Ook. 

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck)

Этот пример является переводом на Spoon этого примера. Отметим, что Spoon позволяет не разделять отдельные команды пробелами, но текущая версия EsCo требует, чтобы команды разделялись пробелами.

1111110010001011111111111101100000110100010100101111111111001000101111111111011000001101
0100101011111110010100010101110010100101111001000101111111111101100000110100010100111110
0100010000000000000011000001101000101001101101101101111100100010111110110000011010001010
0100100010101110010100000000000000000000010100000000000000000000000000010100100101001010

Hello, World!:

Пример для версий Müller's Brainfuck 2.0

Этот пример является переводом на Brainloller этого примера. Поскольку Brainloller — язык чисто графический, в роли исходного кода выступают изображения.

"Hello, World!" на Brainloller
"Hello, World!" на Brainloller

"Hello, World!" на Brainloller (увеличение 10x)
"Hello, World!" на Brainloller (увеличение 10x)

Hello, World!:

Пример для версий Müller's Brainfuck 2.0

Этот пример является переводом на Unary этого примера. Сам код слишком обширен, чтобы приводить его полностью, поэтому указана только его длина.

A string of 
708184005756841022918598670049178934705323143517361395031673227349803938380
119378597780037353721967636097362645175347036417214959141923667629285233360
306016978751166690464736541968556 zeroes (approximately 7*10^182).

Числа Фибоначчи:

Пример для версий Müller's Brainfuck 2.0

Этот пример является переводом на Unary этого примера. Сам код слишком обширен, чтобы приводить его полностью, поэтому указана только его длина.

A string of 
146778148267671308907956810331954494567788969820594569869966345643952713144
716974835554679004232198811425384864927587749892052914319949694507679080918
662111668706252645905597146857061868763596677983948203224834326028677131466
814323099384842068831692029352209655371798175735992788874417787727414767365
600708388513171998134124513036377960362194431944262896105838957344640161915
106378867996851411865254464299481964724009334722033995112813417289458551426
925973669722270280516592327343992579166227546099835941334220 zeros (approximately 1.5*10^509)

Hello, World!:

Пример для версий Müller's Brainfuck 2.0

Этот пример является переводом на Pi этого примера.

3.141592653589793238462623382272502824197169299275107820904924592337816406386238
99262833482534311206728234808621328230264709314460935058223872535941812844111745
00841022019385311055296426229289549302819244388109726652334471204756422337867231
65221231909345628566933460342610454226248213391607264249148273720587036656315582
17288153092396282225439171532436789559536003133023024882044652108412695192151163
94330573703656595909530921261173839326137921051125420742623799227495273538857227
24892227938133011749109833675362442656243086321294946795024737130702479860343702
77453921711629317375838467480846766440513202056822724526351082178577132275778260
91736271767204684409312229532301462492853110307922896892089235450199501120290219
65862034218129813624774731309964518707241349993993372978039951049734732816036348
59504445345544690330263252250825304468003522193158817101

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck)

Пример для Boolfuck.

H ;;;+;+;;+;+;
e +;+;+;+;;+;;+;
l ;;+;;+;+;;+;
l ;;+;;+;+;;+;
o +;;;;+;+;;+;
comma ;;+;;+;+;+;;
space ;;;;;+;+;;
W +;;;+;+;+;+;+;
o +;;;;+;+;;+;
r ;+;+;;+;;;+;
l ;;+;;+;+;;+;
d ;;+;+;;+;;+;
! +;+;;;;+;+;;
\n ;+;+;+; 

Hello, World!:

Пример для версий weave.rb

Пример использования диалекта pbrain. Первая строка определяет процедуру номер 0, которая, будучи вызвана в некоторой ячейке, копирует в нее содержимое соседней слева ячейки и прибавляет к нему 10. Вторая строка заполняет первые 14 ячеек значениями от 0 до 130 с шагом 10. Затем значения в нужных ячейках изменяются на ASCII-коды нужных символов.

(++++++++++<[>+>+<<-]>>[<<+>>-])
>::::::::::::::
<<<<<<<--------.>>>---------.+++++++..>---------.<<<<<<
<------.<--------.>>>>>---.>>>.+++.<.--------.<<<<<<<+.

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck)

Пример на COW.

MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MOO moO MoO moO MoO MoO moO MoO MoO MoO 
moO MoO MoO MoO MoO moO MoO MoO MoO MoO MoO moO MoO MoO MoO MoO MoO MoO moO MoO 
MoO MoO MoO MoO MoO MoO moO MoO MoO MoO MoO MoO MoO MoO MoO moO MoO MoO MoO MoO 
MoO MoO MoO MoO MoO moO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO moO MoO MoO MoO 
MoO MoO MoO MoO MoO MoO MoO MoO moO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO 
MoO moO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO mOo mOo mOo mOo mOo
mOo mOo mOo mOo mOo mOo mOo mOo MOo moo moO moO moO moO moO moO moO moO MOo MOo 
MOo MOo MOo MOo MOo MOo Moo moO moO moO MOo MOo MOo MOo MOo MOo MOo MOo MOo Moo 
MoO MoO MoO MoO MoO MoO MoO Moo Moo moO MOo MOo MOo MOo MOo MOo MOo MOo MOo Moo 
mOo mOo mOo mOo mOo mOo mOo MOo MOo MOo MOo MOo MOo Moo mOo MOo MOo MOo MOo MOo 
MOo MOo MOo Moo moO moO moO moO moO MOo MOo MOo Moo moO moO moO Moo MoO MoO MoO 
Moo mOo Moo MOo MOo MOo MOo MOo MOo MOo MOo Moo mOo mOo mOo mOo mOo mOo mOo MoO 
Moo 

Числа Фибоначчи:

Пример для версий EsCo 0.511 (Brainfuck)

Пример на COW. Аналогичен этому примеру, но вывод чисел на печать существенно упрощается за счет команды OOM; фактически, даже с более длинными командами пример лаконичнее исходного.

MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO 
MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO 
                                            c1v44 : ASCII code of comma
moO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO 
MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO
                                            c2v32 : ASCII code of space
moO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO
                                            c3v11 : quantity of numbers to be calculated
moO                                         c4v0  : zeroth Fibonacci number (will not be printed)
moO MoO                                     c5v1  : first Fibonacci number
mOo mOo                                     c3    : loop counter
MOO                                         block : loop to print (i)th number and calculate next one
moO moO OOM                                 c5    : the number to be printed
mOo mOo mOo mOo Moo moO Moo                 c1c2  : print comma and space
                                            block : actually calculate next Fibonacci in c6
moO moO MOO moO moO MoO mOo mOo MOo moo     c4v0  : move c4 to c6 (don't need to preserve it)
moO MOO moO MoO mOo mOo MoO moO MOo moo     c5v0  : move c5 to c6 and c4 (need to preserve it)
moO MOO mOo MoO moO MOo moo                 c6v0  : move c6 with sum to c5
mOo mOo mOo MOo                             c3    : decrement loop counter
moo 
mOo mOo MoO MoO Moo Moo Moo                 c1    : output three dots

Hello, World!:

Пример для версий EsCo 0.511 (Brainfuck)

Этот пример является переводом на Blub этого примера на Brainfuck.

Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub! Blub? Blub. Blub? 
Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. 
Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub? Blub. Blub! Blub! Blub? Blub! Blub. Blub? 
Blub! Blub. Blub. Blub? Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. 
Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub! Blub? Blub. Blub? Blub. Blub. Blub. Blub. 
Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. 
Blub? Blub. Blub! Blub! Blub? Blub! Blub. Blub? Blub. Blub. Blub! Blub. Blub. Blub. Blub. Blub. 
Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub! Blub. Blub! Blub. Blub. Blub. 
Blub. Blub. Blub. Blub. Blub! Blub. Blub. Blub? Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. 
Blub! Blub? Blub. Blub? Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. 
Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub? Blub. Blub! Blub! Blub? Blub! 
Blub. Blub? Blub! Blub. Blub? Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub! Blub? Blub. Blub? 
Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub? Blub. Blub! Blub! Blub? Blub! Blub. Blub? 
Blub! Blub. Blub? Blub. Blub? Blub. Blub? Blub. Blub? Blub. Blub? Blub. Blub. Blub. Blub. Blub. 
Blub. Blub. Blub! Blub? Blub. Blub? Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. Blub. 
Blub? Blub. Blub! Blub! Blub? Blub! Blub. Blub? Blub! Blub. Blub. Blub? Blub. Blub? Blub! Blub. 
Blub. Blub. Blub. Blub. Blub. Blub. Blub! Blub. Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub! 
Blub! Blub! Blub! Blub! Blub! Blub. Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub! 
Blub! Blub! Blub! Blub! Blub! Blub! Blub! Blub. Blub. Blub? Blub. Blub? Blub. Blub. Blub! Blub. 

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам