Detail změny č. 507

Jazyk Brainfuck

Jazyk Brainfuck
###############

Programovací jazyk Brainfuck patří mezi ezoterické jazyky, určené k pobavení a zamyšlení programátorů. Navrhl jej v roce 1993 švýcarský programátor **Urban Müller** a obsahuje pouze 8 příkazů, kde každý z nich je reprezentován právě jedním ASCII znakem. Neznámé znaky jsou ignorovány. Brainfuck je však i přesto Turingovsky úplný a má tedy formálně stejné schopnosti jako ostatní "programovací jazyky":[programovaci-jazyky], například "**C++**":[jazyk-cpp] nebo "**Java**":[jazyk-java].

Seznam příkazů
**************

Programovací jazyk Brainfuck obsahuje celkem 8 příkazů. Má k dispozici pole buněk o zadané velikosti (obvykle 30000), které je na počátku vynulováno. Každá buňka může nabývat hodnot 0-255 (rozsah je tedy jeden bajt). Aktuální buňku určuje tzv. **datový ukazatel**.

|---
| Příkaz | Význam
|---
| *<* | Přesune datový ukazatel o jednu buňku vlevo
| *>* | Přesune datový ukazatel o jednu buňku vpravo
| *+* | Inkrementuje hodnotu v aktuální buňce
| *-* | Dekrementuje hodnotu v aktuální buňce
| *.* | Vypíše hodnotu v aktuální buňce (obvykle jako odpovídající znak ASCII)
| *,* | Načte hodnotu na vstupu do aktuální buňky (obvykle ASCII hodnotu zadaného znaku)
| *[* | Je-li hodnota v aktuální buňce rovna 0, přesune instrukční ukazatel za odpovídající *]*
| *[* | Je-li hodnota v aktuální buňce různá od 0, přesune instrukční ukazatel na odpovídající *[*

Program "Hello World!"
**********************

$$bf:
+++++ +++++ inicializace pocitadla (bunka #0) na 10
[ pomoci cyklu nastavit bunky na hodnoty 70, 100, 30, 10
> +++++ ++ pricist 7 k bunce #1
> +++++ +++++ pricist 10 k bunce #2
> +++ pricist 3 k bunce #3
> + pricist 1 k bunce #4
<<<< - dekrementovat pocitadlo (bunka #0)
] konec cyklu
> ++ . vypsat 'H'
> + . vypsat 'e'
+++++ ++ . vypsat 'l'
. vypsat 'l'
+++ . vypsat 'o'
>++ . vypsat ' '
<< +++++ +++++ +++++ . vypsat 'W'
> . vypsat 'o'
+++ . vypsat 'r'
----- - . vypsat 'l'
----- --- . vypsat 'd'
> + . vypsat '!'
> . vypsat znak pro novy radek
$$

$$bf:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.
>.+++.------.--------.>+.>.
$$

Interpretr (Java)
*****************

Třída v "jazyce Java":[jazyk-java], která provádí interpretaci programů v jazyce Brainfuck, vypadá následovně:

$$java5:
import java.util.Scanner;

/**
* Interpretr jazyka Brainfuck.
* @author Vojtěch Hordějčuk
*/
public class Interpreter
{
/**
* datové buňky
*/
final private byte[] data;
/**
* scanner pro zpracování standardního vstupu
*/
final Scanner scanner;

/**
* Vytvoří nový interpretr se zadaným počtem datových buněk.
* @param size počet datových buněk
*/
public Interpreter (final int size)
{
// zkontrolovat parametry

if (size < 1)
{
System.err.println ("Invalid cell count.");
System.exit (-1);
}

// vytvořit a vynulovat datové buňky

this.data = new byte[size];

for (int i = 0; i < this.data.length; i ++)
{
this.data[i] = 0;
}

// vytvořit scanner

this.scanner = new Scanner (System.in);
}

/**
* Spustit zadaný program v jazyce Brainfuck.
* @param program pole znaků, kde znaky jsou jednotlivé instrukce
* @return TRUE právě když program skončil úspěšně
*/
public boolean start (final char[] program)
{
// zkontrolovat parametry

if (program.length < 1)
{
System.out.println ("The input code is empty.");
return true;
}

// inicializovat ukazatele

int dataPointer = 0;
int instructionPointer = 0;

// inicializovat scanner

this.scanner.reset ();

// spustit provádění instrukce

while (instructionPointer < program.length)
{
switch (program[instructionPointer])
{
case '+':

// inkrementace aktuální buňky

if (this.data[dataPointer] < Byte.MAX_VALUE)
{
this.data[dataPointer] ++;
instructionPointer ++;
}
else
{
System.err.println ("Cannot increase the maximal value (" + Byte.MAX_VALUE + ").");
return false;
}

break;

case '-':

// dekrementace aktuální buňky

if (this.data[dataPointer] > Byte.MIN_VALUE)
{
this.data[dataPointer] --;
instructionPointer ++;
}
else
{
System.err.println ("Cannot decrease the minimal value (" + Byte.MIN_VALUE + ").");
return false;
}

break;

case '<':

// posun o buňku vlevo

if (dataPointer > 0)
{
dataPointer --;
instructionPointer ++;
}
else
{
System.err.println ("Low boundary broken (0).");
return false;
}

break;

case '>':

// posun o buňku vpravo

if (dataPointer < this.data.length - 1)
{
dataPointer ++;
instructionPointer ++;
}
else
{
System.err.println ("High boundary broken (" + (this.data.length - 1) + ").");
return false;
}

break;

case ',':

// načíst vstup do aktuální buňky

String input;

do
{
System.out.print ("Input: ");

input = this.scanner.nextLine ();

if (input.length () == 1)
{
break;
}

System.out.println ("Invalid input. Type one character only and press ENTER.");
}
while (true);

this.data[dataPointer] = (byte) input.charAt (0);
instructionPointer ++;
break;

case '.':

// vypsat aktuální buňku na výstup jako ASCII

System.out.print ((char) this.data[dataPointer]);
instructionPointer ++;
break;

case '[':

// je-li hodnota aktuální buňky nulová, přesunout instrukční ukazatel za odpovídající "]"

if (this.data[dataPointer] == 0)
{
int depth = 0;
int ictemp = instructionPointer + 1;

while (ictemp < program.length - 1)
{
if (program[ictemp] == '[')
{
depth ++;
}
else if (program[ictemp] == ']')
{
if (depth == 0)
{
instructionPointer = ictemp + 1;
break;
}
else
{
depth --;
}
}

ictemp ++;
}

if (depth != 0)
{
System.err.println ("Invalid parenthesis.");
return false;
}
}
else
{
instructionPointer ++;
}

break;

case ']':

// je-li hodnota aktuální buňky různá od nuly, přesunout instrukční ukazatel na odpovídající "["

if (this.data[dataPointer] != 0)
{
int depth = 0;
int ictemp = instructionPointer - 1;

while (ictemp > 0)
{
if (program[ictemp] == '[')
{
if (depth == 0)
{
instructionPointer = ictemp;
break;
}
else
{
depth --;
}
}
else if (program[ictemp] == ']')
{
depth ++;
}

ictemp --;
}

if (depth != 0)
{
System.err.println ("Invalid parenthesis.");
return false;
}
}
else
{
instructionPointer ++;
}

break;

default:

// neznámé znaky budou přeskočeny

instructionPointer ++;
break;
}
}

return true;
}
}
$$

Reference
#########

- http://en.wikipedia.org/wiki/Brainfuck
Jazyk Brainfuck
###############

Programovací jazyk Brainfuck patří mezi ezoterické jazyky, určené k pobavení a zamyšlení programátorů. Navrhl jej v roce 1993 švýcarský programátor **Urban Müller** a obsahuje pouze 8 příkazů, kde každý z nich je reprezentován právě jedním ASCII znakem. Neznámé znaky jsou ignorovány. Brainfuck je však i přesto Turingovsky úplný a má tedy formálně stejné schopnosti jako ostatní "programovací jazyky":[programovaci-jazyky], například "**C++**":[jazyk-cpp] nebo "**Java**":[jazyk-java].

Seznam příkazů
**************

Programovací jazyk Brainfuck obsahuje celkem 8 příkazů. Má k dispozici pole buněk o zadané velikosti (obvykle 30000), které je na počátku vynulováno. Každá buňka může nabývat hodnot 0-255 (rozsah je tedy jeden bajt). Aktuální buňku určuje tzv. **datový ukazatel**.

|---
| Příkaz | Význam
|---
| *<* | Přesune datový ukazatel o jednu buňku vlevo
| *>* | Přesune datový ukazatel o jednu buňku vpravo
| *+* | Inkrementuje hodnotu v aktuální buňce
| *-* | Dekrementuje hodnotu v aktuální buňce
| *.* | Vypíše hodnotu v aktuální buňce (obvykle jako odpovídající znak ASCII)
| *,* | Načte hodnotu na vstupu do aktuální buňky (obvykle ASCII hodnotu zadaného znaku)
| *[* | Je-li hodnota v aktuální buňce rovna 0, přesune instrukční ukazatel za odpovídající *]*
| *[* | Je-li hodnota v aktuální buňce různá od 0, přesune instrukční ukazatel na odpovídající *[*

Program "Hello World!"
**********************

$$bf:
+++++ +++++ inicializace pocitadla (bunka #0) na 10
[ pomoci cyklu nastavit bunky na hodnoty 70, 100, 30, 10
> +++++ ++ pricist 7 k bunce #1
> +++++ +++++ pricist 10 k bunce #2
> +++ pricist 3 k bunce #3
> + pricist 1 k bunce #4
<<<< - dekrementovat pocitadlo (bunka #0)
] konec cyklu
> ++ . vypsat 'H'
> + . vypsat 'e'
+++++ ++ . vypsat 'l'
. vypsat 'l'
+++ . vypsat 'o'
>++ . vypsat ' '
<< +++++ +++++ +++++ . vypsat 'W'
> . vypsat 'o'
+++ . vypsat 'r'
----- - . vypsat 'l'
----- --- . vypsat 'd'
> + . vypsat '!'
> . vypsat znak pro novy radek
$$

Bez komentářů a nových řádků vypadá kód následovně:

$$bf:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
$$

Jednoduché programy
*******************

Nulování aktuální buňky
=======================

$$bf:
[-]
$$

Vyhledání první nenulové buňky
==============================

Dopředné:

$$bf:
[>]<
$$

Zpětné:

$$bf:
[<]>
$$

Sčítání
=======

Nechť buňka *#0* obsahuje první sčítanec a buňka *#1* druhý. Po skončení následující cyklu bude v buňce *#0* nula a v buňce *#1* součet.

$$bf:
[->+<]
$$

Interpretr (Java)
*****************

Třída v "jazyce Java":[jazyk-java], která provádí interpretaci programů v jazyce Brainfuck, vypadá následovně:

$$java5:
import java.util.Scanner;

/**
* Interpretr jazyka Brainfuck.
* @author Vojtěch Hordějčuk
*/
public class Interpreter
{
/**
* datové buňky
*/
final private byte[] data;
/**
* scanner pro zpracování standardního vstupu
*/
final Scanner scanner;

/**
* Vytvoří nový interpretr se zadaným počtem datových buněk.
* @param size počet datových buněk
*/
public Interpreter (final int size)
{
// zkontrolovat parametry

if (size < 1)
{
System.err.println ("Invalid cell count.");
System.exit (-1);
}

// vytvořit a vynulovat datové buňky

this.data = new byte[size];

for (int i = 0; i < this.data.length; i ++)
{
this.data[i] = 0;
}

// vytvořit scanner

this.scanner = new Scanner (System.in);
}

/**
* Spustit zadaný program v jazyce Brainfuck.
* @param program pole znaků, kde znaky jsou jednotlivé instrukce
* @return TRUE právě když program skončil úspěšně
*/
public boolean start (final char[] program)
{
// zkontrolovat parametry

if (program.length < 1)
{
System.out.println ("The input code is empty.");
return true;
}

// inicializovat ukazatele

int dataPointer = 0;
int instructionPointer = 0;

// inicializovat scanner

this.scanner.reset ();

// spustit provádění instrukce

while (instructionPointer < program.length)
{
switch (program[instructionPointer])
{
case '+':

// inkrementace aktuální buňky

if (this.data[dataPointer] < Byte.MAX_VALUE)
{
this.data[dataPointer] ++;
instructionPointer ++;
}
else
{
System.err.println ("Cannot increase the maximal value (" + Byte.MAX_VALUE + ").");
return false;
}

break;

case '-':

// dekrementace aktuální buňky

if (this.data[dataPointer] > Byte.MIN_VALUE)
{
this.data[dataPointer] --;
instructionPointer ++;
}
else
{
System.err.println ("Cannot decrease the minimal value (" + Byte.MIN_VALUE + ").");
return false;
}

break;

case '<':

// posun o buňku vlevo

if (dataPointer > 0)
{
dataPointer --;
instructionPointer ++;
}
else
{
System.err.println ("Low boundary broken (0).");
return false;
}

break;

case '>':

// posun o buňku vpravo

if (dataPointer < this.data.length - 1)
{
dataPointer ++;
instructionPointer ++;
}
else
{
System.err.println ("High boundary broken (" + (this.data.length - 1) + ").");
return false;
}

break;

case ',':

// načíst vstup do aktuální buňky

String input;

do
{
System.out.print ("Input: ");

input = this.scanner.nextLine ();

if (input.length () == 1)
{
break;
}

System.out.println ("Invalid input. Type one character only and press ENTER.");
}
while (true);

this.data[dataPointer] = (byte) input.charAt (0);
instructionPointer ++;
break;

case '.':

// vypsat aktuální buňku na výstup jako ASCII

System.out.print ((char) this.data[dataPointer]);
instructionPointer ++;
break;

case '[':

// je-li hodnota aktuální buňky nulová, přesunout instrukční ukazatel za odpovídající "]"

if (this.data[dataPointer] == 0)
{
int depth = 0;
int ictemp = instructionPointer + 1;

while (ictemp < program.length - 1)
{
if (program[ictemp] == '[')
{
depth ++;
}
else if (program[ictemp] == ']')
{
if (depth == 0)
{
instructionPointer = ictemp + 1;
break;
}
else
{
depth --;
}
}

ictemp ++;
}

if (depth != 0)
{
System.err.println ("Invalid parenthesis.");
return false;
}
}
else
{
instructionPointer ++;
}

break;

case ']':

// je-li hodnota aktuální buňky různá od nuly, přesunout instrukční ukazatel na odpovídající "["

if (this.data[dataPointer] != 0)
{
int depth = 0;
int ictemp = instructionPointer - 1;

while (ictemp > 0)
{
if (program[ictemp] == '[')
{
if (depth == 0)
{
instructionPointer = ictemp;
break;
}
else
{
depth --;
}
}
else if (program[ictemp] == ']')
{
depth ++;
}

ictemp --;
}

if (depth != 0)
{
System.err.println ("Invalid parenthesis.");
return false;
}
}
else
{
instructionPointer ++;
}

break;

default:

// neznámé znaky budou přeskočeny

instructionPointer ++;
break;
}
}

return true;
}
}
$$

Reference
#########

- http://en.wikipedia.org/wiki/Brainfuck

Hledat na Wiki

 

Wiki - aktuálně