From e3bba69e229bb1139efcb89d661dcfaadd81d4be Mon Sep 17 00:00:00 2001 From: RasButAss Date: Sun, 29 Oct 2023 13:06:46 +0530 Subject: [PATCH 1/6] Added BFCipher interpreter with testcases --- ciphers/brainfuck.py | 190 ++++++++++++++++++++++++++++ ciphers/tests_BFCipher/testcode1.bf | 20 +++ ciphers/tests_BFCipher/testcode2.bf | 43 +++++++ 3 files changed, 253 insertions(+) create mode 100755 ciphers/brainfuck.py create mode 100644 ciphers/tests_BFCipher/testcode1.bf create mode 100644 ciphers/tests_BFCipher/testcode2.bf diff --git a/ciphers/brainfuck.py b/ciphers/brainfuck.py new file mode 100755 index 000000000000..b09f852f67a5 --- /dev/null +++ b/ciphers/brainfuck.py @@ -0,0 +1,190 @@ +import traceback + +""" + author: Samarth Tankasali + date: 29.10.2023 + class: Brainfuck Cipher + + This class implements the BF-cipher algorithm and provides + some useful methods for interpreting instructions + + Description: + Brainfuck is an esoteric programming language created in 1993 by Urban Müller. + + Notable for its extreme minimalism, the language consists of only eight simple commands, a data pointer and an instruction pointer. While it is fully Turing complete, it is not intended for practical use, but to challenge and amuse programmers. Brainfuck requires one to break commands into microscopic steps. + + The language's name is a reference to the slang term brainfuck, which refers to things so complicated or unusual that they exceed the limits of one's understanding, as it was not meant or made for designing actual software but to challenge the boundaries of computer programming. +""" + + +class BFCipher: + """ + Brainfuck Interpreter. + + BFCipher class processes the brainfuck instruction and returns the output after compilation. + + Args: + instruction (str): A string of the BFCipher code. + + Examples: + >>> # Code to add 5 + 2 + >>> instruction = "++>+++++[<+>-]++++++++[<++++++>-]<." + >>> print(BFCipher(instruction).compile()) + 7 + >>> # Code to print "Hello World!" + >>> instruction = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++." + >>> print(BFCipher(instruction).compile(), end = "") + Hello World! + """ + + def __init__(self, instruction: str) -> None: + """ + BFCipher constructor + + Args: + instruction (str): A string of the BFCipher code. + """ + self.main_arr: list = [0]*30000 + self.instruction_ptr: int = 0 + self.data_ptr: int = 0 + self.user_input: list = [] + self.loop_table: dict = {} + self.output: str = "" + if not isinstance(instruction, str): + raise TypeError("Instruction must be a string") + else: + self.instruction: str = instruction + + def __syntax_check(self): + """ + Performs a syntax check of the instruction and generates the `loop_table`. + """ + checker_ptr: int = self.instruction_ptr + bracket_stack = [] + while checker_ptr < len(self.instruction): + if self.instruction[checker_ptr] == '[': + bracket_stack.append(checker_ptr) + elif self.instruction[checker_ptr] == ']': + if len(bracket_stack) == 0: + raise SyntaxError( + f"Incomplete closure of bracket for instruction {checker_ptr}") + loop_beginning_index = bracket_stack.pop() + self.loop_table[loop_beginning_index] = checker_ptr + self.loop_table[checker_ptr] = loop_beginning_index + checker_ptr += 1 + if len(bracket_stack) > 0: + raise SyntaxError( + f"Incomplete closure of bracket for instruction {checker_ptr}") + + def __increment_data_ptr(self): + """ + Increment the data pointer by one (to point to the next cell to the right). + """ + self.data_ptr += 1 + if self.data_ptr > 30000: + raise ValueError( + "NullValue Reference: Data pointer referencing null.") + + def __decrement_data_ptr(self): + """ + Decrement the data pointer by one (to point to the next cell to the left). + """ + self.data_ptr -= 1 + if self.data_ptr < 0: + raise ValueError( + "NullValue Reference: Data pointer referencing null.") + + def __increment_data_value(self): + """ + Increment the byte at the data pointer by one. + """ + self.main_arr[self.data_ptr] += 1 + self.main_arr[self.data_ptr] = self.main_arr[self.data_ptr] & 0xFF + + def __decrement_data_value(self): + """ + Decrement the byte at the data pointer by one. + """ + self.main_arr[self.data_ptr] -= 1 + self.main_arr[self.data_ptr] = self.main_arr[self.data_ptr] & 0xFF + + def __append_bracket(self): + """ + If the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching `]` command. + """ + if self.main_arr[self.data_ptr] == 0: + self.instruction_ptr = self.loop_table[self.instruction_ptr] + + def __pop_bracket(self): + """ + If the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching `[` command. + """ + if self.main_arr[self.data_ptr] != 0: + self.instruction_ptr = self.loop_table[self.instruction_ptr] + + def __print_output(self): + """ + Output the byte at the data pointer. + """ + self.output += chr(self.main_arr[self.data_ptr]) + + def __take_input(self): + """ + Accept one byte of input, storing its value in the byte at the data pointer. + """ + if self.user_input == []: + user_input = list(input() + "\n") + self.main_arr[self.data_ptr] = ord(user_input.pop(0)) + + def compile(self) -> str: + """ + Executes the brainfuck instructions and returns appropriate output after compilation. + + Returns: + `str`: A string representing the output of the BF instructions. + """ + try: + self.__syntax_check() + while self.instruction_ptr < len(self.instruction): + if self.instruction[self.instruction_ptr] == '>': + self.__increment_data_ptr() + elif self.instruction[self.instruction_ptr] == '<': + self.__decrement_data_ptr() + elif self.instruction[self.instruction_ptr] == '+': + self.__increment_data_value() + elif self.instruction[self.instruction_ptr] == '-': + self.__decrement_data_value() + elif self.instruction[self.instruction_ptr] == '[': + self.__append_bracket() + elif self.instruction[self.instruction_ptr] == ']': + self.__pop_bracket() + elif self.instruction[self.instruction_ptr] == '.': + self.__print_output() + elif self.instruction[self.instruction_ptr] == ',': + self.__take_input() + self.instruction_ptr += 1 + return self.output + except ValueError: + print(traceback.format_exc(), end="") + except SyntaxError: + print(traceback.format_exc(), end="") + + +if __name__ == "__main__": + inputs = ["testcode1.bf", "testcode2.bf"] # Add path of testcodes here + outputs = ["7", "Hello World!\n"] # Add expected outputs here + passed = failed = 0 + for input, expected_ouput in zip(inputs, outputs): + file = open(f"tests_BFCipher/{input}", "r") + instruction = file.read() + output = BFCipher(instruction).compile() + if output == expected_ouput: + passed+=1 + else: + failed+=1 + file.close() + print(f"Passed : {passed}\nFailed : {failed}") + if failed == 0: + print("All testcases passed :)") + else: + print(f"{failed} testcases failed :(") diff --git a/ciphers/tests_BFCipher/testcode1.bf b/ciphers/tests_BFCipher/testcode1.bf new file mode 100644 index 000000000000..3f5f2eeea2d1 --- /dev/null +++ b/ciphers/tests_BFCipher/testcode1.bf @@ -0,0 +1,20 @@ +++ Cell c0 = 2 +> +++++ Cell c1 = 5 + +[ Start your loops with your cell pointer on the loop counter (c1 in our case) +< + Add 1 to c0 +> - Subtract 1 from c1 +] End your loops with the cell pointer on the loop counter + +At this point our program has added 5 to 2 leaving 7 in c0 and 0 in c1 +but we cannot output this value to the terminal since it is not ASCII encoded + +To display the ASCII character "7" we must add 48 to the value 7 +We use a loop to compute 48 = 6 * 8 + +++++ ++++ c1 = 8 and this will be our loop counter again +[ +< +++ +++ Add 6 to c0 +> - Subtract 1 from c1 +] +< . Print out c0 which has the value 55 which translates to "7"! \ No newline at end of file diff --git a/ciphers/tests_BFCipher/testcode2.bf b/ciphers/tests_BFCipher/testcode2.bf new file mode 100644 index 000000000000..1b8ceb343252 --- /dev/null +++ b/ciphers/tests_BFCipher/testcode2.bf @@ -0,0 +1,43 @@ +[ This program prints "Hello World!" and a newline to the screen, its + length is 106 active command characters. [It is not the shortest.] + + This loop is an "initial comment loop", a simple way of adding a comment + to a BF program such that you don't have to worry about any command + characters. Any ".", ",", "+", "-", "<" and ">" characters are simply + ignored, the "[" and "]" characters just have to be balanced. This + loop and the commands it contains are ignored because the current cell + defaults to a value of 0; the 0 value causes this loop to be skipped. +] +++++++++ Set Cell #0 to 8 +[ + >++++ Add 4 to Cell #1; this will always set Cell #1 to 4 + [ as the cell will be cleared by the loop + >++ Add 2 to Cell #2 + >+++ Add 3 to Cell #3 + >+++ Add 3 to Cell #4 + >+ Add 1 to Cell #5 + <<<<- Decrement the loop counter in Cell #1 + ] Loop until Cell #1 is zero; number of iterations is 4 + >+ Add 1 to Cell #2 + >+ Add 1 to Cell #3 + >- Subtract 1 from Cell #4 + >>+ Add 1 to Cell #6 + [<] Move back to the first zero cell you find; this will + be Cell #1 which was cleared by the previous loop + <- Decrement the loop Counter in Cell #0 +] Loop until Cell #0 is zero; number of iterations is 8 + +The result of this is: +Cell no : 0 1 2 3 4 5 6 +Contents: 0 0 72 104 88 32 8 +Pointer : ^ + +>>. Cell #2 has value 72 which is 'H' +>---. Subtract 3 from Cell #3 to get 101 which is 'e' ++++++++..+++. Likewise for 'llo' from Cell #3 +>>. Cell #5 is 32 for the space +<-. Subtract 1 from Cell #4 for 87 to give a 'W' +<. Cell #3 was set to 'o' from the end of 'Hello' ++++.------.--------. Cell #3 for 'rl' and 'd' +>>+. Add 1 to Cell #5 gives us an exclamation point +>++. And finally a newline from Cell #6 \ No newline at end of file From 41c94b23b4099da874eec3741843a70d62df7322 Mon Sep 17 00:00:00 2001 From: RasButAss Date: Sun, 29 Oct 2023 13:16:23 +0530 Subject: [PATCH 2/6] Added wikipedia link to description --- ciphers/brainfuck.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ciphers/brainfuck.py b/ciphers/brainfuck.py index b09f852f67a5..f2a8b4e87b64 100755 --- a/ciphers/brainfuck.py +++ b/ciphers/brainfuck.py @@ -14,6 +14,7 @@ Notable for its extreme minimalism, the language consists of only eight simple commands, a data pointer and an instruction pointer. While it is fully Turing complete, it is not intended for practical use, but to challenge and amuse programmers. Brainfuck requires one to break commands into microscopic steps. The language's name is a reference to the slang term brainfuck, which refers to things so complicated or unusual that they exceed the limits of one's understanding, as it was not meant or made for designing actual software but to challenge the boundaries of computer programming. + (https://en.wikipedia.org/wiki/Brainfuck) """ From efc9d68f918150ba4d25406c2b4a1b2ad786c216 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 29 Oct 2023 08:11:40 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ciphers/brainfuck.py | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/ciphers/brainfuck.py b/ciphers/brainfuck.py index f2a8b4e87b64..1d39874ec255 100755 --- a/ciphers/brainfuck.py +++ b/ciphers/brainfuck.py @@ -45,7 +45,7 @@ def __init__(self, instruction: str) -> None: Args: instruction (str): A string of the BFCipher code. """ - self.main_arr: list = [0]*30000 + self.main_arr: list = [0] * 30000 self.instruction_ptr: int = 0 self.data_ptr: int = 0 self.user_input: list = [] @@ -63,19 +63,21 @@ def __syntax_check(self): checker_ptr: int = self.instruction_ptr bracket_stack = [] while checker_ptr < len(self.instruction): - if self.instruction[checker_ptr] == '[': + if self.instruction[checker_ptr] == "[": bracket_stack.append(checker_ptr) - elif self.instruction[checker_ptr] == ']': + elif self.instruction[checker_ptr] == "]": if len(bracket_stack) == 0: raise SyntaxError( - f"Incomplete closure of bracket for instruction {checker_ptr}") + f"Incomplete closure of bracket for instruction {checker_ptr}" + ) loop_beginning_index = bracket_stack.pop() self.loop_table[loop_beginning_index] = checker_ptr self.loop_table[checker_ptr] = loop_beginning_index checker_ptr += 1 if len(bracket_stack) > 0: raise SyntaxError( - f"Incomplete closure of bracket for instruction {checker_ptr}") + f"Incomplete closure of bracket for instruction {checker_ptr}" + ) def __increment_data_ptr(self): """ @@ -83,8 +85,7 @@ def __increment_data_ptr(self): """ self.data_ptr += 1 if self.data_ptr > 30000: - raise ValueError( - "NullValue Reference: Data pointer referencing null.") + raise ValueError("NullValue Reference: Data pointer referencing null.") def __decrement_data_ptr(self): """ @@ -92,8 +93,7 @@ def __decrement_data_ptr(self): """ self.data_ptr -= 1 if self.data_ptr < 0: - raise ValueError( - "NullValue Reference: Data pointer referencing null.") + raise ValueError("NullValue Reference: Data pointer referencing null.") def __increment_data_value(self): """ @@ -147,21 +147,21 @@ def compile(self) -> str: try: self.__syntax_check() while self.instruction_ptr < len(self.instruction): - if self.instruction[self.instruction_ptr] == '>': + if self.instruction[self.instruction_ptr] == ">": self.__increment_data_ptr() - elif self.instruction[self.instruction_ptr] == '<': + elif self.instruction[self.instruction_ptr] == "<": self.__decrement_data_ptr() - elif self.instruction[self.instruction_ptr] == '+': + elif self.instruction[self.instruction_ptr] == "+": self.__increment_data_value() - elif self.instruction[self.instruction_ptr] == '-': + elif self.instruction[self.instruction_ptr] == "-": self.__decrement_data_value() - elif self.instruction[self.instruction_ptr] == '[': + elif self.instruction[self.instruction_ptr] == "[": self.__append_bracket() - elif self.instruction[self.instruction_ptr] == ']': + elif self.instruction[self.instruction_ptr] == "]": self.__pop_bracket() - elif self.instruction[self.instruction_ptr] == '.': + elif self.instruction[self.instruction_ptr] == ".": self.__print_output() - elif self.instruction[self.instruction_ptr] == ',': + elif self.instruction[self.instruction_ptr] == ",": self.__take_input() self.instruction_ptr += 1 return self.output @@ -172,17 +172,17 @@ def compile(self) -> str: if __name__ == "__main__": - inputs = ["testcode1.bf", "testcode2.bf"] # Add path of testcodes here - outputs = ["7", "Hello World!\n"] # Add expected outputs here + inputs = ["testcode1.bf", "testcode2.bf"] # Add path of testcodes here + outputs = ["7", "Hello World!\n"] # Add expected outputs here passed = failed = 0 for input, expected_ouput in zip(inputs, outputs): file = open(f"tests_BFCipher/{input}", "r") instruction = file.read() output = BFCipher(instruction).compile() if output == expected_ouput: - passed+=1 + passed += 1 else: - failed+=1 + failed += 1 file.close() print(f"Passed : {passed}\nFailed : {failed}") if failed == 0: From 4de5cad7e01657706a7cc599f2700a3b843f1dd1 Mon Sep 17 00:00:00 2001 From: RasButAss Date: Sun, 29 Oct 2023 14:45:06 +0530 Subject: [PATCH 4/6] Removed tests folder and linted python code --- ciphers/brainfuck.py | 78 ++++++++++++++++------------- ciphers/tests_BFCipher/testcode1.bf | 20 -------- ciphers/tests_BFCipher/testcode2.bf | 43 ---------------- 3 files changed, 42 insertions(+), 99 deletions(-) delete mode 100644 ciphers/tests_BFCipher/testcode1.bf delete mode 100644 ciphers/tests_BFCipher/testcode2.bf diff --git a/ciphers/brainfuck.py b/ciphers/brainfuck.py index 1d39874ec255..1fef30cb7061 100755 --- a/ciphers/brainfuck.py +++ b/ciphers/brainfuck.py @@ -9,11 +9,19 @@ some useful methods for interpreting instructions Description: - Brainfuck is an esoteric programming language created in 1993 by Urban Müller. - - Notable for its extreme minimalism, the language consists of only eight simple commands, a data pointer and an instruction pointer. While it is fully Turing complete, it is not intended for practical use, but to challenge and amuse programmers. Brainfuck requires one to break commands into microscopic steps. - - The language's name is a reference to the slang term brainfuck, which refers to things so complicated or unusual that they exceed the limits of one's understanding, as it was not meant or made for designing actual software but to challenge the boundaries of computer programming. + Brainfuck is an esoteric programming language created in 1993 by Urban + Müller. + + Notable for its extreme minimalism, the language consists of only eight + simple commands, a data pointer and an instruction pointer. While it is + fully Turing complete, it is not intended for practical use, but to + challenge and amuse programmers. Brainfuck requires one to break commands + into microscopic steps. + + The language's name is a reference to the slang term brainfuck, which refers + to things so complicated or unusual that they exceed the limits of one's + understanding, as it was not meant or made for designing actual software but + to challenge the boundaries of computer programming. (https://en.wikipedia.org/wiki/Brainfuck) """ @@ -22,7 +30,8 @@ class BFCipher: """ Brainfuck Interpreter. - BFCipher class processes the brainfuck instruction and returns the output after compilation. + BFCipher class processes the brainfuck instruction and returns the output + after compilation. Args: instruction (str): A string of the BFCipher code. @@ -30,11 +39,13 @@ class BFCipher: Examples: >>> # Code to add 5 + 2 >>> instruction = "++>+++++[<+>-]++++++++[<++++++>-]<." - >>> print(BFCipher(instruction).compile()) + >>> print(BFCipher(instruction).bf_compiler()) 7 >>> # Code to print "Hello World!" - >>> instruction = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++." - >>> print(BFCipher(instruction).compile(), end = "") + >>> instruction = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>" + >>> instruction += ".>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+" + >>> instruction += ".>++." + >>> print(BFCipher(instruction).bf_compiler(), end = "") Hello World! """ @@ -58,7 +69,8 @@ def __init__(self, instruction: str) -> None: def __syntax_check(self): """ - Performs a syntax check of the instruction and generates the `loop_table`. + Performs a syntax check of the instruction and generates the + `loop_table`. """ checker_ptr: int = self.instruction_ptr bracket_stack = [] @@ -68,7 +80,7 @@ def __syntax_check(self): elif self.instruction[checker_ptr] == "]": if len(bracket_stack) == 0: raise SyntaxError( - f"Incomplete closure of bracket for instruction {checker_ptr}" + "Incomplete closure of bracket for instruction" ) loop_beginning_index = bracket_stack.pop() self.loop_table[loop_beginning_index] = checker_ptr @@ -76,12 +88,13 @@ def __syntax_check(self): checker_ptr += 1 if len(bracket_stack) > 0: raise SyntaxError( - f"Incomplete closure of bracket for instruction {checker_ptr}" + "Incomplete closure of bracket for instruction" ) def __increment_data_ptr(self): """ - Increment the data pointer by one (to point to the next cell to the right). + Increment the data pointer by one (to point to the next cell to the + right). """ self.data_ptr += 1 if self.data_ptr > 30000: @@ -89,7 +102,8 @@ def __increment_data_ptr(self): def __decrement_data_ptr(self): """ - Decrement the data pointer by one (to point to the next cell to the left). + Decrement the data pointer by one (to point to the next cell to the + left). """ self.data_ptr -= 1 if self.data_ptr < 0: @@ -111,14 +125,18 @@ def __decrement_data_value(self): def __append_bracket(self): """ - If the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching `]` command. + If the byte at the data pointer is zero, then instead of moving the + instruction pointer forward to the next command, jump it forward to + the command after the matching `]` command. """ if self.main_arr[self.data_ptr] == 0: self.instruction_ptr = self.loop_table[self.instruction_ptr] def __pop_bracket(self): """ - If the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching `[` command. + If the byte at the data pointer is nonzero, then instead of moving the + instruction pointer forward to the next command, jump it back to the + command after the matching `[` command. """ if self.main_arr[self.data_ptr] != 0: self.instruction_ptr = self.loop_table[self.instruction_ptr] @@ -131,15 +149,17 @@ def __print_output(self): def __take_input(self): """ - Accept one byte of input, storing its value in the byte at the data pointer. + Accept one byte of input, storing its value in the byte at the data + pointer. """ if self.user_input == []: user_input = list(input() + "\n") self.main_arr[self.data_ptr] = ord(user_input.pop(0)) - def compile(self) -> str: + def bf_compiler(self) -> str: """ - Executes the brainfuck instructions and returns appropriate output after compilation. + Executes the brainfuck instructions and returns appropriate output after + compilation. Returns: `str`: A string representing the output of the BF instructions. @@ -172,20 +192,6 @@ def compile(self) -> str: if __name__ == "__main__": - inputs = ["testcode1.bf", "testcode2.bf"] # Add path of testcodes here - outputs = ["7", "Hello World!\n"] # Add expected outputs here - passed = failed = 0 - for input, expected_ouput in zip(inputs, outputs): - file = open(f"tests_BFCipher/{input}", "r") - instruction = file.read() - output = BFCipher(instruction).compile() - if output == expected_ouput: - passed += 1 - else: - failed += 1 - file.close() - print(f"Passed : {passed}\nFailed : {failed}") - if failed == 0: - print("All testcases passed :)") - else: - print(f"{failed} testcases failed :(") + instruction = "++>+++++[<+>-]++++++++[<++++++>-]<." + generated_output = BFCipher(instruction).bf_compiler() + print(generated_output) diff --git a/ciphers/tests_BFCipher/testcode1.bf b/ciphers/tests_BFCipher/testcode1.bf deleted file mode 100644 index 3f5f2eeea2d1..000000000000 --- a/ciphers/tests_BFCipher/testcode1.bf +++ /dev/null @@ -1,20 +0,0 @@ -++ Cell c0 = 2 -> +++++ Cell c1 = 5 - -[ Start your loops with your cell pointer on the loop counter (c1 in our case) -< + Add 1 to c0 -> - Subtract 1 from c1 -] End your loops with the cell pointer on the loop counter - -At this point our program has added 5 to 2 leaving 7 in c0 and 0 in c1 -but we cannot output this value to the terminal since it is not ASCII encoded - -To display the ASCII character "7" we must add 48 to the value 7 -We use a loop to compute 48 = 6 * 8 - -++++ ++++ c1 = 8 and this will be our loop counter again -[ -< +++ +++ Add 6 to c0 -> - Subtract 1 from c1 -] -< . Print out c0 which has the value 55 which translates to "7"! \ No newline at end of file diff --git a/ciphers/tests_BFCipher/testcode2.bf b/ciphers/tests_BFCipher/testcode2.bf deleted file mode 100644 index 1b8ceb343252..000000000000 --- a/ciphers/tests_BFCipher/testcode2.bf +++ /dev/null @@ -1,43 +0,0 @@ -[ This program prints "Hello World!" and a newline to the screen, its - length is 106 active command characters. [It is not the shortest.] - - This loop is an "initial comment loop", a simple way of adding a comment - to a BF program such that you don't have to worry about any command - characters. Any ".", ",", "+", "-", "<" and ">" characters are simply - ignored, the "[" and "]" characters just have to be balanced. This - loop and the commands it contains are ignored because the current cell - defaults to a value of 0; the 0 value causes this loop to be skipped. -] -++++++++ Set Cell #0 to 8 -[ - >++++ Add 4 to Cell #1; this will always set Cell #1 to 4 - [ as the cell will be cleared by the loop - >++ Add 2 to Cell #2 - >+++ Add 3 to Cell #3 - >+++ Add 3 to Cell #4 - >+ Add 1 to Cell #5 - <<<<- Decrement the loop counter in Cell #1 - ] Loop until Cell #1 is zero; number of iterations is 4 - >+ Add 1 to Cell #2 - >+ Add 1 to Cell #3 - >- Subtract 1 from Cell #4 - >>+ Add 1 to Cell #6 - [<] Move back to the first zero cell you find; this will - be Cell #1 which was cleared by the previous loop - <- Decrement the loop Counter in Cell #0 -] Loop until Cell #0 is zero; number of iterations is 8 - -The result of this is: -Cell no : 0 1 2 3 4 5 6 -Contents: 0 0 72 104 88 32 8 -Pointer : ^ - ->>. Cell #2 has value 72 which is 'H' ->---. Subtract 3 from Cell #3 to get 101 which is 'e' -+++++++..+++. Likewise for 'llo' from Cell #3 ->>. Cell #5 is 32 for the space -<-. Subtract 1 from Cell #4 for 87 to give a 'W' -<. Cell #3 was set to 'o' from the end of 'Hello' -+++.------.--------. Cell #3 for 'rl' and 'd' ->>+. Add 1 to Cell #5 gives us an exclamation point ->++. And finally a newline from Cell #6 \ No newline at end of file From a003bfb7704e86df31ece3ac8041ff7bdea5751c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 29 Oct 2023 09:55:04 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ciphers/brainfuck.py | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/ciphers/brainfuck.py b/ciphers/brainfuck.py index 1fef30cb7061..b17e4356b05e 100755 --- a/ciphers/brainfuck.py +++ b/ciphers/brainfuck.py @@ -9,18 +9,18 @@ some useful methods for interpreting instructions Description: - Brainfuck is an esoteric programming language created in 1993 by Urban + Brainfuck is an esoteric programming language created in 1993 by Urban Müller. - Notable for its extreme minimalism, the language consists of only eight - simple commands, a data pointer and an instruction pointer. While it is - fully Turing complete, it is not intended for practical use, but to - challenge and amuse programmers. Brainfuck requires one to break commands + Notable for its extreme minimalism, the language consists of only eight + simple commands, a data pointer and an instruction pointer. While it is + fully Turing complete, it is not intended for practical use, but to + challenge and amuse programmers. Brainfuck requires one to break commands into microscopic steps. - The language's name is a reference to the slang term brainfuck, which refers - to things so complicated or unusual that they exceed the limits of one's - understanding, as it was not meant or made for designing actual software but + The language's name is a reference to the slang term brainfuck, which refers + to things so complicated or unusual that they exceed the limits of one's + understanding, as it was not meant or made for designing actual software but to challenge the boundaries of computer programming. (https://en.wikipedia.org/wiki/Brainfuck) """ @@ -30,7 +30,7 @@ class BFCipher: """ Brainfuck Interpreter. - BFCipher class processes the brainfuck instruction and returns the output + BFCipher class processes the brainfuck instruction and returns the output after compilation. Args: @@ -69,7 +69,7 @@ def __init__(self, instruction: str) -> None: def __syntax_check(self): """ - Performs a syntax check of the instruction and generates the + Performs a syntax check of the instruction and generates the `loop_table`. """ checker_ptr: int = self.instruction_ptr @@ -79,21 +79,17 @@ def __syntax_check(self): bracket_stack.append(checker_ptr) elif self.instruction[checker_ptr] == "]": if len(bracket_stack) == 0: - raise SyntaxError( - "Incomplete closure of bracket for instruction" - ) + raise SyntaxError("Incomplete closure of bracket for instruction") loop_beginning_index = bracket_stack.pop() self.loop_table[loop_beginning_index] = checker_ptr self.loop_table[checker_ptr] = loop_beginning_index checker_ptr += 1 if len(bracket_stack) > 0: - raise SyntaxError( - "Incomplete closure of bracket for instruction" - ) + raise SyntaxError("Incomplete closure of bracket for instruction") def __increment_data_ptr(self): """ - Increment the data pointer by one (to point to the next cell to the + Increment the data pointer by one (to point to the next cell to the right). """ self.data_ptr += 1 @@ -102,7 +98,7 @@ def __increment_data_ptr(self): def __decrement_data_ptr(self): """ - Decrement the data pointer by one (to point to the next cell to the + Decrement the data pointer by one (to point to the next cell to the left). """ self.data_ptr -= 1 @@ -125,8 +121,8 @@ def __decrement_data_value(self): def __append_bracket(self): """ - If the byte at the data pointer is zero, then instead of moving the - instruction pointer forward to the next command, jump it forward to + If the byte at the data pointer is zero, then instead of moving the + instruction pointer forward to the next command, jump it forward to the command after the matching `]` command. """ if self.main_arr[self.data_ptr] == 0: @@ -134,8 +130,8 @@ def __append_bracket(self): def __pop_bracket(self): """ - If the byte at the data pointer is nonzero, then instead of moving the - instruction pointer forward to the next command, jump it back to the + If the byte at the data pointer is nonzero, then instead of moving the + instruction pointer forward to the next command, jump it back to the command after the matching `[` command. """ if self.main_arr[self.data_ptr] != 0: @@ -149,7 +145,7 @@ def __print_output(self): def __take_input(self): """ - Accept one byte of input, storing its value in the byte at the data + Accept one byte of input, storing its value in the byte at the data pointer. """ if self.user_input == []: @@ -158,7 +154,7 @@ def __take_input(self): def bf_compiler(self) -> str: """ - Executes the brainfuck instructions and returns appropriate output after + Executes the brainfuck instructions and returns appropriate output after compilation. Returns: From db6bf021d711a3a5dd453ee40a5d1bb38c0430e6 Mon Sep 17 00:00:00 2001 From: RasButAss Date: Sun, 29 Oct 2023 15:15:52 +0530 Subject: [PATCH 6/6] Minor Bug Fixes --- ciphers/brainfuck.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) mode change 100755 => 100644 ciphers/brainfuck.py diff --git a/ciphers/brainfuck.py b/ciphers/brainfuck.py old mode 100755 new mode 100644 index b17e4356b05e..563f4728cbf6 --- a/ciphers/brainfuck.py +++ b/ciphers/brainfuck.py @@ -67,7 +67,7 @@ def __init__(self, instruction: str) -> None: else: self.instruction: str = instruction - def __syntax_check(self): + def __syntax_check(self) -> None: """ Performs a syntax check of the instruction and generates the `loop_table`. @@ -87,7 +87,7 @@ def __syntax_check(self): if len(bracket_stack) > 0: raise SyntaxError("Incomplete closure of bracket for instruction") - def __increment_data_ptr(self): + def __increment_data_ptr(self) -> None: """ Increment the data pointer by one (to point to the next cell to the right). @@ -96,7 +96,7 @@ def __increment_data_ptr(self): if self.data_ptr > 30000: raise ValueError("NullValue Reference: Data pointer referencing null.") - def __decrement_data_ptr(self): + def __decrement_data_ptr(self) -> None: """ Decrement the data pointer by one (to point to the next cell to the left). @@ -105,21 +105,21 @@ def __decrement_data_ptr(self): if self.data_ptr < 0: raise ValueError("NullValue Reference: Data pointer referencing null.") - def __increment_data_value(self): + def __increment_data_value(self) -> None: """ Increment the byte at the data pointer by one. """ self.main_arr[self.data_ptr] += 1 self.main_arr[self.data_ptr] = self.main_arr[self.data_ptr] & 0xFF - def __decrement_data_value(self): + def __decrement_data_value(self) -> None: """ Decrement the byte at the data pointer by one. """ self.main_arr[self.data_ptr] -= 1 self.main_arr[self.data_ptr] = self.main_arr[self.data_ptr] & 0xFF - def __append_bracket(self): + def __append_bracket(self) -> None: """ If the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to @@ -128,7 +128,7 @@ def __append_bracket(self): if self.main_arr[self.data_ptr] == 0: self.instruction_ptr = self.loop_table[self.instruction_ptr] - def __pop_bracket(self): + def __pop_bracket(self) -> None: """ If the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the @@ -137,13 +137,13 @@ def __pop_bracket(self): if self.main_arr[self.data_ptr] != 0: self.instruction_ptr = self.loop_table[self.instruction_ptr] - def __print_output(self): + def __print_output(self) -> None: """ Output the byte at the data pointer. """ self.output += chr(self.main_arr[self.data_ptr]) - def __take_input(self): + def __take_input(self) -> None: """ Accept one byte of input, storing its value in the byte at the data pointer.