How can I check if user input is equal to a value in brainfuck?

196 Views Asked by At

I am trying to write a program (which I'm sure has been done before, just trying to challenge myself) that takes two user inputs per loop, one for the letter/number, and one to check if the user is done inputting (y/n), and then print the whole string. I know what I have so far isn't fantastic, but basically I start the loop, move the pointer up two (so there's a findable 0 value at the beginning), ask for the first and second inputs, set the next value to lowercase n, and am currently trying to figure out how to compare the values. I have tried to print values, which only appear to print after two inputs and then the program breaks.

Here is what I have so far:

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

If it makes a difference, I am using a homemade brainfuck interpreter, which may have some imperfections:

def brainfuck(code):
    array = [0]
    pointer = 0
    i = 0
    while(i < len(code)):
        if(code[i] == '<'):
            if(i != 0):
                if(pointer != 0):
                    pointer -= 1
        elif(code[i] == '>'):
            pointer += 1
            if(len(array) <= pointer):
                array.append(0)
        elif(code[i] == '+'):
            array[pointer] += 1
        elif(code[i] == '-'):
            if(array[pointer] > 0):
                array[pointer] -= 1
        elif(code[i] == '.'):
            print(pointer,chr(array[pointer]))
        elif(code[i] == ','):
            x = input('Input:')
            try:
                array[pointer] = int(x)
            except ValueError:
                array[pointer] = ord(x)
        elif(code[i] == '['):
            if(array[pointer] == 0):
                openBraces = 1
                while(openBraces > 0):
                    i += 1
                    if(code[i] == '['):
                        openBraces += 1
                    elif(code[i] == ']'):
                        openBraces -= 1
        elif(code[i] == ']'):
            openBraces = 1
            while(openBraces > 0):
                i -= 1
                if(code[i] == '['):
                    openBraces -= 1
                elif(code[i] == ']'):
                    openBraces += 1
            i -= 1
        i += 1
2

There are 2 best solutions below

0
user17301834 On

I made something like this a long time ago, should do the trick (if I remember right)

// if x == y: {if_code}; else: {else_code}

,

(x)'y
[->-<]>

0'(y minus x)
[>+>]<

{if} (0)'0; {else} 0'y minus x'(1)
-[
  {if_code}
  +>>
]<

0'(y minus x)
[
  <
  {else_code}
  >[-]
]<

empty memory

The comments show what memory looks like before each line and they may be structured a bit weirdly in order to avoid using symbols which would be considered as brainfuck by the interpreter. Values in the memory are separated by apostrophes and brackets are used to show which position in the memory the pointer is at.

Make sure to have the value you want to compare the input to in the second position in the memory and to move the pointer back to the first position before implementing this code.

I'm sorry that I didn't read through your interpreter, but I assume that it works.

Hope this helps!

0
Daniel Cristofani On

Your interpreter is certainly contributing, at least because decrementing a 0 in it produces a 0 rather than a -1. I haven't checked it for other bugs, but I would suggest using another interpreter. And the main thing I'd suggest is to actually step through your code by hand with pen and paper, command by command, keeping a series of maps of the state of the array. That should show what's happening and where things went off the rails.

(So far, you're outputting a NUL from the third cell, getting input into the third and fourth, putting 110='n' in the 5th, outputting that 'n', moving/negating it in a convoluted way to end up with 0 in the fifth cell and -110 in the sixth, outputting another NUL from the fifth cell, scanning back past your input to the first cell and zeroing it to exit the loop after the first iteration.)

I should note, maybe the simplest way to do what you're trying to do is something like:

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

We read the two bytes and subtract 'y' (121) from the second, then use that to check for loop termination. If the input character was a 'y' the subtraction gives a 0 and we stop the loop; otherwise it gives a positive or negative number and we do the loop again, reading the next character over the residue.

Note, though, that in brainfuck the ',' command reads one character, without prompting. So you'll have to give input like

Hnenlnlnon!y

To get output like

Hello!