snippetcppMinor
How to speak Brainfuck: for beginners
Viewed 0 times
speakbeginnersforhowbrainfuck
Problem
The following code transforms multi-line input into the the Brainfuck equivalent. One line turns into one program. The resulting programs are split by newlines for readability.
Brainf.cpp
Brainf.hpp
Explanation:
The print statement in Brainfuck is
The Brainfuck doesn't think. It increments, decrements or prints.
Example usage:
Input:
Output:
```
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++
++++++++++++++++++++++.++++++
Brainf.cpp
#include "Brainf.hpp"
int main()
{
std::vector userInput;
std::string currentLine = " "; // do not start empty
while (currentLine.length() != 0) // escape input by an empty line
{
std::getline(std::cin, currentLine);
userInput.push_back(currentLine);
}
std::vector::size_type userInputSize = userInput.size();
for (unsigned i = 0; i < userInputSize; i++)
{
std::cout << modifyString(userInput[i]) << std::endl << std::endl;
}
}Brainf.hpp
#ifndef BRAINF_HPP
#define BRAINF_HPP
#include
#include
#include
#include
std::string modifyChar(char input, int carry)
{
std::string output;
int next = input - carry;
if (next > 0)
{
for (unsigned i = 0; i < next; ++i)
{
output += "+";
}
}
if (next < 0)
{
for (unsigned i = 0; i < abs(next); ++i)
{
output += "-";
}
}
output += ".";
return output;
}
std::string modifyString(std::string input)
{
std::string output;
int traveller = 0;
for (unsigned i = 0; i < input.length(); ++i)
{
output += modifyChar(input[i], traveller);
traveller = (int)input[i];
}
return output;
}
#endifExplanation:
The print statement in Brainfuck is
.. The resulting Brainfuck prints the original string character-by-character, so there will be as much . as there are characters to print. Between those . there will be either + if the ASCII is higher than the previous character and - if it's lower.The Brainfuck doesn't think. It increments, decrements or prints.
Example usage:
Input:
Hello World!Output:
```
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++
++++++++++++++++++++++.++++++
Solution
First of all, let's not beat around the bush. Clearly your filenames should be Brainfuck.hpp and Brainfuck.cpp. Let's not be shy. Now for the real reviews:
Input
This is bad.
This ensures that you get the correct strings in your
Looping
Since this is tagged C++11, you definitely want to use a range-for expression to do your loop. It's less code and clearer:
Know what's in the standard
Your
Thus:
And same comment about looping again for
Input
std::string currentLine = " "; // do not start empty
while (currentLine.length() != 0) // escape input by an empty line
{
std::getline(std::cin, currentLine);
userInput.push_back(currentLine);
}This is bad.
getline() could fail - and you'd expect it to fail when the input runs out. But you're not checking the result of getline(), so you end up writing an extra string onto your vector. The correct approach would be:for (std::string currentLine; std::getline(std::cin, currentLine); ) {
userInput.push_back(currentLine);
}This ensures that you get the correct strings in your
userInput.Looping
Since this is tagged C++11, you definitely want to use a range-for expression to do your loop. It's less code and clearer:
for (const std::string& str : userInput) {
std::cout << modifyString(str) << std::endl << std::endl;
}Know what's in the standard
Your
modifyChar() function's job is to pick some character (either + or -) and return a string with that character next times, followed by a period. You do not need a loop for this. There is a constructor for std::string that takes a count and a character and constructs a string with that character that many times.Thus:
std::string modifyChar(char input, int carry)
{
int next = input - carry;
std::string output = (next > 0) ? std::string(next, '+')
: std::string(-next, '-');
return output + '.';
}And same comment about looping again for
modifyString. Though additionally you should take input by reference-to-const, to avoid a completely unnecessary copy:std::string modifyString(std::string const& input)
{
std::string output;
int traveller = 0;
for (char c : input)
{
output += modifyChar(c, traveller);
traveller = c;
}
return output;
}Code Snippets
std::string currentLine = " "; // do not start empty
while (currentLine.length() != 0) // escape input by an empty line
{
std::getline(std::cin, currentLine);
userInput.push_back(currentLine);
}for (std::string currentLine; std::getline(std::cin, currentLine); ) {
userInput.push_back(currentLine);
}for (const std::string& str : userInput) {
std::cout << modifyString(str) << std::endl << std::endl;
}std::string modifyChar(char input, int carry)
{
int next = input - carry;
std::string output = (next > 0) ? std::string(next, '+')
: std::string(-next, '-');
return output + '.';
}std::string modifyString(std::string const& input)
{
std::string output;
int traveller = 0;
for (char c : input)
{
output += modifyChar(c, traveller);
traveller = c;
}
return output;
}Context
StackExchange Code Review Q#97628, answer score: 8
Revisions (0)
No revisions yet.