Brainfuck Printer

Description

For each line of input of printable ASCII (0x20-0x7e), output a brainfuck program which produces that string. Your score is the sum of the length of your program and the length of the code it would output for β€œHello World!”

For example, if one line of the input is ABC you could output +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+.+.

For reference, Brainfuck is played on an infinite tape of 8-bit values extending in both sides with all values starting at 0. The commands are as follows:

  • + increment the current value in the tape, wrapping back to 0 after 255. (*ptr++)
  • - decrement the current value in the tape, wrappeing back to 255 after 0 (*ptr–)
  • > move to the next value on the tape (ptr–)
  • < move to the previous value on the tape (ptr++)
  • [ Jump to past the matching ] if the current value on the tape is 0 (while(*ptr) {)
  • ] Jump to before the matching [ (})
  • . Output the current value on the tape (putchar(*ptr))

Any other characters are ignored.

Judge

(async function*(context: Context): Challenge {
	const evalBF = (bfCode:string):string => {
		const tape = new Array(0x8000).fill(0);
		let ptr = 0;
		let output = ``;
		for(let codeIdx = 0; codeIdx < bfCode.length; codeIdx++)
		{
			let command = bfCode.charAt(codeIdx);
			let jumpDirection = 0;
			if(command==`+`) tape[ptr]=(tape[ptr]+1)&255;
			if(command==`-`) tape[ptr]=(tape[ptr]-1)&255;
			if(command==`>`) ptr = ptr+1 & 0x7fff;
			if(command==`<`) ptr = ptr-1 & 0x7fff;
			if(command==`.`) output += String.fromCharCode(tape[ptr] & 0xff);
			if(command==`[` && !(tape[ptr]&0xff)) jumpDirection = 1;
			if(command==`]` &&  (tape[ptr]&0xff)) jumpDirection = -1;
			for(let balance = jumpDirection;balance;)
			{
			command = bfCode.charAt(codeIdx += jumpDirection);
			balance +=
				command==`[` ? 1 :
				command==`]` ? -1 : 0;
			}
		}
		return output;
	}

	let scores = [];

	const scoringTestCases = [
		"Hello, World!", 
		"Byte Heist is a site where you can test your coding skills by solving challenges in as few bytes as possible.",
		"The 8 valid brainfuck commands are: `+`,`-`,`>`,`<`,`[`,`]`,`.`, and `,`.",
		"How much wood would a wood chuck chuck is a wood chuck could chuck wood?",
		"Leentje leerde lotje lopen langs de lange linde laan, maar toen leentje niet wouw lopen leerde leentje lotje staan",
		"Ik ben ik. En dit is mijn vel. Past het wel? Het past. Wat zal ik er mee doen? Ik geef mijn vel een zoen",
		"Er was eens een bij uit 's-Gravenhage, die antwoord wist op alle vragen. Toen men hem moeiljk genoeg vroeg: \"Wat was was, eer was was was?\", werd hij de winnaar van de quiz, met \"Eer was was was, was was is\"",
		"Wij snachten naar achtentachtig prachtige nachten bij achtentachtig prachtige grachten",
		"Chandu ke chacha ne Chandu ki chachi ko Chandni Chowk mein chandi ke chammach se chatni chatai",
		"Kacha papita pital ki patili may pila pila"
	];

	const nonScoringTestCases = [
		"a",
		" !\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",
		"[>q1h`2@Xv 95Be:-Fsj73py(P!T Bayk{{Wpy|L|$ 7*kLwE|",
		"eL34NfeOL454KdeJ44JOdefePK55gQ67ShfTL787KegJ77JTeghfUK88iV9:XjgYL:;:KfiJ::JYfij",
		"J,xU #={lM#+[`iwt9cRxdz[ACiNRok~H\\6I[|72KHo]k IN9jsB:WtoUq3%c|r>:QAb\":>-hYH\" k",
		"i0sAVNQ Ik!EV5/E&^Ym_DJfyD<$/JkG,-kN,AQ=CT[K+L\"n^^z=",
		"&^5B5BF&6b%^7B&*N7H76n876 n907HM*M9[.)>][)>.0O[{>]>{I9.0,u-m8"
	];

	yield *context.runTestCases([
		...scoringTestCases,
		...nonScoringTestCases
	].map(s=>[s,s] as [string,string]), {
		  compareFunction: (output, expected) => {
			  let index;
			  if ((index = scoringTestCases.indexOf(expected))!=-1) {
				  delete scoringTestCases[index];
				  scores.push(output.length);
			  }
			  return evalBF(output) === expected
		  }
	});

	const textEncoder = new TextEncoder('utf-8');
	const lengthInBytes = (s: string): number => textEncoder.encode(s).length;


	// Finally, the challenge is passed if no test cases failed
	return context.noFailures(
		lengthInBytes(context.code) + Math.round(scores.reduce((a,b)=>a+b)/scores.length)
	);
})

Example Code

input = require("fs").readFileSync(0) + "";
for (const line of input.split("\n")) {
  console.log(
    [...line].map(char => "[-]" + "+".repeat(char.charCodeAt(0)) + ".").join("")
  );
}

Comments

mousetail
mousetail
This suggestion will automatically be accepted if it gets enough πŸ‘
accepted

Suggestion to edit judge

Output
Expected
9 identical lines skipped if(command==`+`) tape[ptr]=(tape[ptr]+1)&255; if(command==`+`) tape[ptr]=(tape[ptr]+1)&255; if(command==`-`) tape[ptr]=(tape[ptr]-1)%255; if(command==`-`) tape[ptr]=(tape[ptr]-1)&255; if(command==`>`) ptr = ptr+1 & 0x7fff; if(command==`>`) ptr = ptr+1 & 0x7fff;
mousetail
mousetail

The wrapping behavior was incorrect, it should have been either:

%256

or

&255
mousetail
mousetail
This suggestion will automatically be accepted if it gets enough πŸ‘
accepted

Suggestion to edit description

Output
Expected
2 identical lines skipped For example, if one line of the input is `A` you would output `+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.` For example, if one line of the input is `A` you would output `+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.` For reference, Brainfuck is played on an infinite tape of 8-bit values extending in both sides with all values starting at 0. The commands are as follows: - `+` increment the current value in the tape, wrapping back to 0 after 255. (`*ptr++`) - `-` decrement the current value in the tape, wrappeing back to 255 after 0 (`*ptr--`) - `>` move to the next value on the tape (`ptr--`) - `<` move to the previous value on the tape (`ptr++`) - `[` Jump to past the matching `]` if the current value on the tape is 0 (`while(*ptr) {`) - `]` Jump to before the matching `[` (`}`) - `.` Output the current value on the tape (`putchar(*ptr)`) Any other characters are ignored.
mousetail
mousetail
This suggestion will automatically be accepted if it gets enough πŸ‘
accepted

Suggestion to edit judge

Output
Expected
26 identical lines skipped let hello_world_score = 999; let scores = []; yield *context.runTestCases([ const scoringTestCases = [ "Hello, World!", "Hello, World!", 1 identical lines skipped "The 8 valid brainfuck commands are: `+`,`-`,`>`,`<`,`[`,`]`,`.`, and `,`.", "The 8 valid brainfuck commands are: `+`,`-`,`>`,`<`,`[`,`]`,`.`, and `,`.", "How much wood would a wood chuck chuck is a wood chuck could chuck wood?", "Leentje leerde lotje lopen langs de lange linde laan, maar toen leentje niet wouw lopen leerde leentje lotje staan", "Ik ben ik. En dit is mijn vel. Past het wel? Het past. Wat zal ik er mee doen? Ik geef mijn vel een zoen", "Er was eens een bij uit scravenhagen, die antwoord wist op alle vragen. Toen men hem moeiljk genoeg vroeg: \"Wat was was, eer was was was?\", werd hij de winnaar van de quiz, met \"Eer was was was, was was is\"", "Wij snachten naar achtentachtig prachtige nachten bij achtentachtig practhige grachten" ]; const nonScoringTestCases = [ "a", "a", 5 identical lines skipped "&^5B5BF&6b%^7B&*N7H76n876 n907HM*M9[.)>][)>.0O[{>]>{I9.0,u-m8" "&^5B5BF&6b%^7B&*N7H76n876 n907HM*M9[.)>][)>.0O[{>]>{I9.0,u-m8" ]; yield *context.runTestCases([ ...scoringTestCases, ...nonScoringTestCases ].map(s=>[s,s] as [string,string]), { ].map(s=>[s,s] as [string,string]), { compareFunction: (output, expected) => { compareFunction: (output, expected) => { if (expected === "Hello, World!") { let index; hello_world_score = output.length; if ((index = scoringTestCases.indexOf(expected))!=-1) { delete scoringTestCases[index]; scores.push(output.length); } } 9 identical lines skipped return context.noFailures( return context.noFailures( lengthInBytes(context.code) + hello_world_score lengthInBytes(context.code) + Math.round(scores.reduce((a,b)=>a+b)/scores.length) ); );
mousetail
mousetail
This suggestion will automatically be accepted if it gets enough πŸ‘
accepted

Suggestion to edit judge

Output
Expected
35 identical lines skipped "Ik ben ik. En dit is mijn vel. Past het wel? Het past. Wat zal ik er mee doen? Ik geef mijn vel een zoen", "Ik ben ik. En dit is mijn vel. Past het wel? Het past. Wat zal ik er mee doen? Ik geef mijn vel een zoen", "Er was eens een bij uit scravenhagen, die antwoord wist op alle vragen. Toen men hem moeiljk genoeg vroeg: \"Wat was was, eer was was was?\", werd hij de winnaar van de quiz, met \"Eer was was was, was was is\"", "Er was eens een bij uit 's-Gravenhage, die antwoord wist op alle vragen. Toen men hem moeiljk genoeg vroeg: \"Wat was was, eer was was was?\", werd hij de winnaar van de quiz, met \"Eer was was was, was was is\"", "Wij snachten naar achtentachtig prachtige nachten bij achtentachtig practhige grachten" "Wij snachten naar achtentachtig prachtige nachten bij achtentachtig prachtige grachten", "Chandu ke chacha ne Chandu ki chachi ko Chandni Chowk mein chandi ke chammach se chatni chatai", "Kacha papita pital ki patili may pila pila" ]; ];
mousetail
mousetail
This suggestion will automatically be accepted if it gets enough πŸ‘
rejected

Suggestion to edit description

Output
Expected
For each line of input of printable ASCII (0x20-0x7e), output a brainfuck program which produces that string. Your score is the sum of the length of your program and the length of the code it would output for "Hello World!" For each line of input of printable ASCII (0x20-0x7e), output a brainfuck program which produces that string. Your score is the sum of the length of your program and the mean length of the output for varoius tounge twisters in different languages.
Mukundan314
Mukundan314

spelling for various is incorrect

mousetail
mousetail
This suggestion will automatically be accepted if it gets enough πŸ‘
rejected

Suggestion to edit description

Output
Expected
For each line of input of printable ASCII (0x20-0x7e), output a brainfuck program which produces that string. Your score is the sum of the length of your program and the length of the code it would output for "Hello World!" For each line of input of printable ASCII (0x20-0x7e), output a brainfuck program which produces that string. Your score is the lenght of your code + the average size of the output for various tongue twisters in different languages.
MeWhenI
MeWhenI

β€œvarious” spelling is fixed from last suggestion but now β€œlength” is misspelled

mousetail
mousetail

Damn it

lynn
lynn
This suggestion will automatically be accepted if it gets enough πŸ‘
accepted

Suggestion to edit description

Output
Expected
1 identical lines skipped For example, if one line of the input is `A` you would output `+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.` For example, if one line of the input is `ABC` you could output `+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+.+.`
lynn
lynn

show a more typical input and β€œcould” instead of β€œwould”