Text to Brain-Flak



Your challenge is to turn input text to brain-flak code that will output the text.

Tutorial taken from here with permission here

Brain-Flak has two stacks, known as 'left' and 'right'. The active stack starts at left. If an empty stack is popped, it will return 0. That's it. No other variables. When the program starts, each command line argument is pushed on to the active stack.

The only valid characters in a Brain-Flak program are ()[]{}<>, and they must always be balanced. There are two types of functions: Nilads and Monads. A nilad is a function that takes 0 arguments. Here are all of the nilads:

  • () Evaluates to one.
  • [] Evaluates to the height of the current stack.
  • {} Pop the active stack. Evaluates to the popped value.
  • <> Toggle the active stack. Evaluates to zero.

These are concatenated together when they are evaluated. So if we had a '3' on top of the active stack, this snippet:


would evaluate to 1 + 1 + active.pop() which would evaluate to 5.

The monads take one argument, a chunk of Brain-Flak code. Here are all of the monads:

  • (n) Push 'n' on the active stack.
  • [n] Evaluates to negative 'n'
  • {foo} While zero is not on the top of the stack, do foo.
  • <foo> Execute foo, but evaluate it as 0.

These functions will also return the value inside of them, so


Will push 3 but


Will push 3 twice.

The {} will evaluate to the sum of all runs. So if we had '3' and '4' on the top of the stack:


would evaluate as 7.

When the program is done executing, each value left on the active stack is printed, with a newline between. Values on the other stack are ignored.


  • You may assume that the Brain-Flak is being run with ascii out. (-A)
  • The brain-flak code must NOT require input
  • All standard rules apply
  • The code must run within 1 minute for any input up to 1024 bytes on TIO. (If no TIO output is available supply an interpreter and I will run it on my machine (my machine should be able to come close to TIO)).
  • You must support arbitrary length input.
  • You may take input from a file.
  • Optimization for test cases is not allowed
  • Deterministic output is required
  • Programs don't need to be stack clean

Test cases (try your code on these, actual scoring texts will be released in 1-2 weeks after challenge is posted)


The meaning of brain-flak is to flak your brain with pain.


To be, or not to be, that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles
And by opposing end them. To die-to sleep,
No more; and by a sleep to say we die

<your brain-flak code here>

The fitness pacer test is a multi stage test. Avacado Avacado Avacadad Avacadad carrot.bat carrot.jar carrot.carrot Quack Quack Quack Quack Quack Quack Quack Quack Quack downgoat doawngoat down down gaot

This challenge came from a online program that turned text into brain-fuck. However brain-fuck has limitations and it is not nearly as cool as brain-flak. I really am looking forward to cool programs :) I am glad you took the time to read this and look forward to seeing your answer.


To win you must give the total length of the brain-flak code given by each of the test cases which will be released 1-2 weeks after the post date. The shortest total length wins.


This is not , length of your code will not effect your final score in any way. Making clean readable code is appreciated. Thanks!

Test cases



Posted 2018-03-07T18:48:00.800

Reputation: 3 428

Boxofsand – Christopher – 2018-03-07T18:48:44.760

Is gaot a typo? – Weijun Zhou – 2018-03-07T19:35:38.607

@WeijunZhou no meme from TNB – Christopher – 2018-03-07T19:38:27.257

I see, thank you for clarification. – Weijun Zhou – 2018-03-07T19:38:56.470

4TNB memes are the dankest of memes. – Magic Octopus Urn – 2018-03-07T19:45:55.427

@MagicOctopusUrn as always – Christopher – 2018-03-07T19:49:42.273

1Wish I could double +1 this, instead I'll offer a bounty because I wanna know how this was supposed to be done. First answer that gets <your brain-flak code here> under 1000 is awarded the bounty. Which I cannot post for another day, whoops; didn't notice how new this was. – Magic Octopus Urn – 2018-03-08T20:59:35.817

@magic sweet! That will bring fun answer's – Christopher – 2018-03-08T23:42:13.127

@MagicOctopusUrn status-complete

– HyperNeutrino – 2018-03-09T01:47:00.457

@MagicOctopusUrn I think you've underestimated just how short that text could be golfed – Jo King – 2018-03-09T09:40:11.953

What is the range of characters that can be inputted? Printable ASCII? – Jo King – 2018-03-10T03:23:23.393

@JoKing anything that fits in 8 bits – Christopher – 2018-03-11T01:07:23.420

@JoKing copy error – Christopher – 2018-03-12T15:56:50.577

@Christopher If you aren't releasing the test cases yet, then you need to release their hashes, so you cannot change them. Otherwise, there's no way to know whether you design test cases after the fact to bias towards a certain answer. Though I don't think you would do that, I'm pretty sure it's policy that test cases should be fixed ahead of time if the score depends on them, and the proof of that is the hashes. – mbomb007 – 2018-03-14T13:29:13.650

1Also, if the range of input is not limited to printable ASCII, then you should include test cases that have every byte value, including NUL bytes. – mbomb007 – 2018-03-14T13:33:23.193

@mbomb I will give the hash soon (mobile) but I wouldn't bias them :P – Christopher – 2018-03-14T15:09:54.030

Just a reminder to release the test cases eventually – Jo King – 2018-03-26T06:35:54.123

Also, is the NUL byte a possible input? Because that will invalidate most solutions – Jo King – 2018-03-26T09:46:12.377

@joking I can't until Sunday because I ended up In Florida for a week – Christopher – 2018-03-27T18:31:21.623

2"Making clean, readable code is appreciated" hastily does challenge in 05AB1E – Magic Octopus Urn – 2018-04-02T18:09:26.513



Brain-Flak, 130 bytes


Try it online!

Output for <your brain-flak code here>: 5045 bytes


Try it online!


Posted 2018-03-07T18:48:00.800

Reputation: 26 575

1Brain-flakking *intensifies* – Magic Octopus Urn – 2018-03-15T11:40:56.273

1@MagicOctopusUrn metaflakking :D – HyperNeutrino – 2018-03-15T15:31:16.610

Test cases are out – Christopher – 2018-04-02T17:05:43.857


Python 3, 17744 bytes

Edit: I've added a couple of options to help golf in stack safe situations.

import sys
import time

def copy(n, code):
	if n == 1: return code
	for x in range(2, n):
		if n%x == 0: return '('*(x-1) + copy(n//x, code) + ')'*(x-1) + '{}'*(x-1)
	return '('*(n-1) + code + ')'*(n-1) + '{}'*(n-1)

letterCache = {}
def letterGen(n, stackLen, prev=0, enclosed=0):
	if (n, stackLen, prev, enclosed) in letterCache: return letterCache[(n, stackLen, prev, enclosed)]
	if n == 0: return ''
	if n == 1: return '()'
	if n == stackLen: return '[]'
	f = []
	if n < 0:
		f.append('[%s]'%letterGen(-n, stackLen, prev, enclosed))
		if prev != 0:
			diff = n-prev
			#Saves ~200 bytes but 20x longer
			#for x in range(min(diff, 0)-stackLen, max(diff, 0)+stackLen+1):
				#f.append(letterGen(x, stackLen - enclosed) + 's' + letterGen(diff - x, stackLen))

			f.append('s' + letterGen(diff, stackLen))
			f.append(letterGen(diff, stackLen - enclosed) + 's')
		x = 2
		while x*x < n:
			f.append(copy(x, letterGen(n//x, stackLen, prev, enclosed)) + letterGen(n%x, stackLen, prev, enclosed))
			x += 1
		f.append(letterGen(n-1, stackLen, prev, enclosed)+'()')
		if abs(n-stackLen) < n and stackLen > 1: f.append(letterGen(n-stackLen, stackLen, prev, enclosed) + '[]')
	letterCache[(n, stackLen, prev, enclosed)] = min(f, key=len)
	return letterCache[(n, stackLen, prev, enclosed)]

def s2BrainFlak(c, checkReverse = True):
	g = []
	c = c[::-1]
	stack = []
	out = []
	enclosed = 0

	if checkReverse:
		g.append(''.join(out) + s2BrainFlak(c, False) + '{({}<>)<>}<>')
		#for x in range(1,11): g.append(s2BrainFlak(list(c)+[chr(0)]*x, False) + '{({}<>)<>}<>')
	#if c and c[0] == chr(0):
	#	out.append('<>')
	#	while c[0] == chr(0):
	#		stack.append(0)
	#		out[0] = '(' + out[0] + ')'
	#		c = c[1:]

	for letter in range(len(c)):
		char = ord(c[letter])
		x = '(%s)'%letterGen(char, len(stack), stack[-1] if stack else 0, enclosed)

		if 's' in x:
			out[-1] = x.replace('s', out[-1])
			enclosed += 1
			enclosed = 1
		if checkReverse and c[letter+1:]:
			g.append(''.join(out) + '<>' + s2BrainFlak(c[letter+1:], False) + '{({}<>)<>}<>')
			m = min(list(map(ord, c[letter+1:])))-1
			#for i in range(1,m): g.append(''.join(out) + '<>' + s2BrainFlak(list(map(lambda x: chr(ord(x)-i), c[letter+1:])), False) + "{({}%s<>)<>}<>"%letterGen(i, 0))
			g.append(''.join(out) + '<>' + s2BrainFlak(list(map(lambda x: chr(ord(x)-m), c[letter+1:])), False) + "{({}%s<>)<>}<>"%letterGen(m, 0))
			#for x in range(1,11): g.append(''.join(out) + s2BrainFlak(list(c)+[chr(0)]*x, False) + '{({}<>)<>}<>')
	return min(g, key=len)

Try it online!

A simple recursive solution which I will continue to improve further. This does very well with smaller inputs, but loses out to MegaTom's Ruby answer for longer inputs.


  • This needs a clean stack to operate, otherwise the improvements with [] become useless (though they can be disabled by commenting out a couple of lines, and they only improve it by about 100 bytes quite a bit).
  • Since this is a recursive algorithm, it will take longer for chars with large values. For example, the character ÿ (value 255) takes 9 seconds to evaluate, where every test case at once takes 1.6 seconds. Cache implemented!
  • Idea of checking the reverse shamelessly borrowed from HyperNeutrino's answer, saving 800 bytes from the total.
  • I changed the total from all test cases at once to the total of each test case. This saves some bytes by adding more uses for the stack length operator ([])
  • ~200 bytes from choosing the minimum of prepending the difference between characters, or appending them (again, this saves bytes through the stack length operator)
  • Implemented a cache (which caches values based on stack length), which allowed me to check more possible avenues without going over the time limit. This saved 1500 bytes from the total.
    • Also, I switched the em dash in the Shakespeare test case to a normal -. This cut out a few bytes, and a lot of time given the value of that em dash was 8212 :o .
  • Cut out 1200 bytes from the longer test cases by cutting them into slices and checking whether it was shorter to switch to the other stack, construct it in reverse, and push it back to the first stack again. Next up, even more slicing, and saving time by optimising the minimum slicing range.
  • Combined the number generating function with the checking for efficiencies with the previous character part into one recursive function. There's a couple of sections in here that save some bytes, but extend the runtime of the program a bit beyond the the one minute limit.
    • Uncommenting those parts can cut it down to 11394 bytes... but takes about 16 minutes.

Example outputs:

<your brain-flak code here> (312 bytes):


Try it online!

Hello, World! (142 bytes [Note: The current previous best was 148 bytes, and is now 136 bytes]):


Try it online!

Jo King

Posted 2018-03-07T18:48:00.800

Reputation: 38 234

checking reversal saves 800 bytes? o_O – HyperNeutrino – 2018-03-10T02:23:46.813

also you should cache the results of your recursive function; would save so much time – HyperNeutrino – 2018-03-10T02:24:29.903

@HyperNeutrino Caching means I can’t use the stack length operator, which actually does save a lot, especially for shorter inputs – Jo King – 2018-03-10T02:37:56.793

oh right, I see edit that's actually a really genius idea (stack length) mind if i steal it? :P – HyperNeutrino – 2018-03-10T02:46:26.320

No worries @HyperNeutrino – Jo King – 2018-03-10T02:53:57.997

1@HyperNeutrino I just realised I can have a cache, as long as I make separate caches for each stack height – Jo King – 2018-03-12T01:06:07.540

@HyperNeutrino Actually... tips for golfing in Brain-flak. – user202729 – 2018-03-13T01:24:37.370

1Your brain-flak meta-golfer out-golfed the best answer for a brain-flak regular golf? What. – Magic Octopus Urn – 2018-03-15T11:47:44.810

Test cases are out – Christopher – 2018-04-02T17:05:13.380


Python has a built-in for an LRU cache, if you would like to use that.

– ThePlasmaRailgun – 2019-03-07T20:36:20.130


Ruby, 17398 bytes for all (new) test cases

# cache for holding shortest push results
$p_cache = {} 

# Get code to push a number "a" to the stack,
#  given top of stack "b" and stack height "h"
def push a,b=nil,h=0
  return $p_cache[[a,b,h]] if $p_cache[[a,b,h]]
  arr = []
  if b
    arr.push "(({})#{add(a-b,h)})"
  arr.push "(#{add a,h}  )"
  arr.push "([]#{add a-h,h}  )"
  while i*i<=a && i<4
    arr.push "#{'('*(i-1)}#{push a/i,b,h}#{')'*(i-2)+'{}'*(i-1)}#{add(a%i,h)})"
  $p_cache[[a,b,h]] = arr.min_by(&:length)

$cache = {}

# Get code to add a number "n" to the 3rd stack
#  given stack height "h" 

def add n,h=0
  return $cache[[n,h]] if $cache[[n,h]]
  arr = []
  if n > 0
  elsif n == 0
    return ""
    if h > 0
        arr.push "[#{'[]'*i}]#{add(h*i+n,h)}"
    arr.push "[#{add(-n,h)}]"
    return ($cache[[n,h]] = arr.min_by &:length)
  if h > 0
    if n > h
      arr.push "[]#{add n-h,h}"
      arr.push "[]#{add n-h}"
  while i*i<=n && i<4
    arr.push "#{'('*(i-1)}#{add n/i,h}#{')'*(i-1)+'{}'*(i-1)}#{add(n%i,h)}"
    if x > 0
      arr.push "#{'('*(i-1)}#{add x/i,h}#{')'*(i-1)}[]#{'{}'*(i-1)}#{add(x%i)}"
  $cache[[n,h]] = arr.min_by &:length

def push_arr(arr)
  code = push(arr[0]) + "\n" + 
    i+=1;push r[1],r[0],i
  while code =~ /^\((.*)\)\n(\(*)\{\}/
    code.gsub!(/^\((.*)\)\n(\(*)\{\}/, '\2\1')
  code.split(/\n| /).join

# push a string to the stack
def push_string(text)
  push_arr text.chars.map(&:ord)

$str_cache = {}
# Push a string in reverse order
def push_string_r(text)
  return $str_cache[text] if $str_cache[text]
  a = [push_string(text)+"{({}<>)<>}<>", push_string(text.reverse)]
  min = text.bytes.min-1
  a.push push_arr(text.bytes.map{|x|x-min}) + "{({}<>#{add min})<>}<>"

  # Try cutting it into bits
  3.upto([text.length/20, 10].min)do|x|
    spl = x*9
    a.push push_string_r(text[spl..-1]) + "<>" + 
      push_string(text[0...spl]) + "{({}<>)<>}<>"
    spl = x*10
    a.push push_string_r(text[spl..-1]) + "<>" + 
      push_string(text[0...spl]) + "{({}<>)<>}<>"

  $str_cache[text] = a.min_by &:length

Try it online!

<your brain-flak code here>, 362 358 bytes


Try it online!


Posted 2018-03-07T18:48:00.800

Reputation: 3 787

Your code takes over 1 minute for all the test cases at once (~950 bytes). It's good that it produces quite short code for the longer individual test cases though. – Jo King – 2018-03-12T09:01:18.573

@JoKing it is fine that it takes longer for every cases :P – Christopher – 2018-03-12T15:58:14.770

@Christopher I was referring to the Must run under 1 minute for inputs up to 1024 bytes rule (though it's much quicker now) – Jo King – 2018-03-13T01:55:33.693

1Although it doesn't actually matter for the code execution, an object that stores data for later use is called a cache, not cash ;p – Value Ink – 2018-03-14T04:44:59.390

Test cases are out – Christopher – 2018-04-02T17:05:28.570


Python 3, 16222 bytes

cache = {}

def generate_number(num, height, level = 0, output = False): # Idea to use Stack Height inspired by Jo King
	if output: print(" " * level + str(num) + " " + str(height))
	if (num, height) in cache: return cache[(num, height)]
	if num == 0: return ""
	if num < 0: return "[" + generate_number(-num, height, level + 1, output) + "]"
	if num == height: return "[]"
	value = min((["[]" + generate_number(num - height, height, level + 1, output)] if height > num * 2 and abs(num - height) < num else []) + ["()" + generate_number(num - 1, height, level + 1, output)] + ["(%s)%s{}" % (generate_number(num // i, height, level + 1, output), "({})" * (i - 2)) for i in range(2, num) if num % i == 0], key = len)
	cache[(num, height)] = value
	return value

generate_number(256, 0, 0, False)

def generate_string(array):
	string = ""
	last = 0
	for height, num in enumerate(array):
		string = min("(" + string + generate_number(num - last, height) + ")", "<" + string + ">" + "(" + generate_number(num, height) + ")", key = len)
		last = num
	return string

a = lambda s: generate_string(list(map(ord, s)))

i = sys.stdin.read()
j = i[::-1]

print(min(a(j), a(i) + "{({}<>)<>}<>", key = len))

Try it online!

First below 1000 for <your brain-flak code here> :D

Brain-Flak, 448 bytes


Try it online!

(originally 827 for <your brain-flak code here>)


Posted 2018-03-07T18:48:00.800

Reputation: 26 575

Bounty inc, soon. – Magic Octopus Urn – 2018-03-13T01:19:06.437

@MagicOctopusUrn cool ty :D – HyperNeutrino – 2018-03-13T02:12:39.403

You're now at 16222 bytes total – Jo King – 2018-03-13T10:16:49.993

Hope 250 was cool. – Magic Octopus Urn – 2018-03-13T13:12:37.310

@MagicOctopusUrn 250 is great :D tyvm – HyperNeutrino – 2018-03-13T13:48:29.380

@JoKing Oh really. huh that's weird, guess I was using the wrong version to get the bytecount :P – HyperNeutrino – 2018-03-13T13:48:42.713

You’re probably testing all the cases together. The stack height addition is more useful when they’re separate. – Jo King – 2018-03-13T21:08:05.613

@JoKing oh yeah that makes more sense, thanks – HyperNeutrino – 2018-03-13T22:37:29.930

Test cases are out – Christopher – 2018-04-02T17:05:34.990

Your bytecount for the new test cases is 24882 – Jo King – 2018-04-07T09:15:23.760


05AB1E, too many bytes (My first BF anything)


Try it online!

Extremely basic attempt at golfing using a the premade "multiplication" Brain-flak code. All this does is finds the smallest-sum divisor pair for each ASCII code point, then pushes both of those divisors pairs as numbers. The Brainflak code ({}<>)({<({}[()])><>({})<>}{}<><{}>) is then appended and executed in a loop until all values are on the alternate stack.

List of people I'm thanking:

  • DJMcMayhem for pointing out (()())(()()()) = ((()())()) (-252 bytes)
  • DJMcMayhem for showing me how loops should work (-927 bytes).

Example golf of <your brain-flak code here> at 3470 3218 2291 bytes:

Brain-Flak, 2291 bytes


Try it online!

Each row represents one character being golfed, this beats the basic solution I posted by 60%, and going in knowing literally nothing about Brainflak I feel this is a good baseline of what not to do. I'll score the answer in a little while, in the middle of something else and I'm sure I can improve on this. (I'm including the newlines in the byte-count because I don't expect this to win).

Magic Octopus Urn

Posted 2018-03-07T18:48:00.800

Reputation: 19 422

Here are some tips: 1) If you're pushing two numbers (say 4 and 5 to get 20), then you could push them together to save bytes. Compare (()()()())(()()()()()) and ((()()()())()) 2) Multiplication by a constant can be much shorter than push(); multiply();. For example, to double a number, you can do (({}){}) rather than (()())({}<>)({<({}[()])><>({})<>}{}<><{}>). But this isn't a terrible baseline. If you want more input, I'm always happy to chat in the third stack

– James – 2018-03-08T19:16:53.287

@DJMcMayhem I was honestly looking to use deltas between numbers, restarting after each negative delta. But I see the idea for differences as well... I'm incorporating that now... theres some other problems with this as well that I'm fixing. Also, the 05AB1E code itself is ungolfed, not that it matters, but I want to redo that too. – Magic Octopus Urn – 2018-03-08T20:15:05.103

The score cases aren't out yet. Will ping in a week or 2 when I post (avoid test case optimization solution) – Christopher – 2018-03-08T23:41:33.390

@DJMcMayhem Would divisors of deltas be good? – Magic Octopus Urn – 2018-03-13T01:20:43.777

Test cases are out – Christopher – 2018-04-02T17:06:18.360

@Christopher my score: "bad" – Magic Octopus Urn – 2018-04-02T17:34:10.333

Sounds good, :P – Christopher – 2018-04-02T17:43:16.070



For each character (main loop)

Get the difference between the top two characters

Push an open paren on the other stack

Retrieve difference

Greater than zero


While non-zero

Add value if not 1


Divmod 2

Hold the div

Push the mod part

Put div down

Open paren if div non-zero

Less than 4


Make that many 1s

End if

End loop puting number of times run on the stack

For each close push and pop

End if

Less than zero



Push open bracket


While non-zero

Add value if not 1


Divmod 2

Hold the div

Push the mod part

Put div down

Open paren if div non-zero

Less than 4


Make that many 1s

End if

End loop puting number of times run on the stack

For each close push and pop

Push close bracket


Remove top character

End of main loop

Close the open parens

Reverse code

Try it online!

Output for <your brain-flak code here>, 582 bytes:


Post Rock Garf Hunter

Posted 2018-03-07T18:48:00.800

Reputation: 55 382