Skip to content

Commit

Permalink
Add brainfuck minifier
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiasbynens committed Jan 15, 2012
1 parent e386dd8 commit 56b126d
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 0 deletions.
7 changes: 7 additions & 0 deletions brainfuck-minifier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# [Mothereffing brainfuck minifier](http://mothereff.in/brainfuck-minifier)

[Brainfuck](http://esolangs.org/wiki/Brainfuck) _(not capitalized except at the start of a sentence)_ is an esoteric programming language. It has eight commands — `+-<>[],.` — and ignores all other characters. As a result, no special syntax for comments is needed, as long as the comments don’t contain the command characters.

This tool will automatically remove comments from any brainfuck snippet you enter.

Made by [Mathias Bynens](http://mathiasbynens.be/).
108 changes: 108 additions & 0 deletions brainfuck-minifier/eff.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
html, textarea {
font: 1em/1.6 sans-serif;
}

body {
max-width: 40em;
padding: 0 1em;
}

h1 {
text-align: center;
font-size: 1.3em;
margin: 0 0 .5em;
padding-top: 1em;
}

h2 {
font-size: 1em;
}

a {
color: #333;
text-decoration: none;
border-bottom: 1px solid #aaa;
padding: .1em .2em;
}

a:hover, a:focus {
color: #fff;
border-color: #036;
background: #36c;
}

dt {
font-weight: bold;
font-style: italic;
}

#output a, textarea, code {
font-family: Monaco, Consolas, monospace;
}

code {
font-size: .9em;
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}

ul {
margin-bottom: 0;
}


blockquote {
margin: 0 0 1em;
border-left: .5em solid #e3e3e3;
padding-left: 10px;
}

#footer {
margin-top: 2em;
text-align: center;
}

textarea {
background: #eee;
border: 3px double grey;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
display: block;
margin: 1em 0 .5em;
padding: .7em;
resize: vertical;
min-height: 9.5em;
}

pre {
padding: .5em;
border: 3px double green;
background: #90ee90;
}

.fail {
border-color: red;
background: #ffb6c1;
}

@media (min-width: 42em) {

html {
font-size: 1.2em;
background: #c4c4c4;
height: 100%;
}

body {
margin: 0 auto;
padding: 0 2em;
min-height: 100%;
background: #fff;
border: solid #aaa;
border-width: 0 1px;
}

}
111 changes: 111 additions & 0 deletions brainfuck-minifier/eff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
(function(window, document) {

var textarea = document.getElementsByTagName('textarea')[0],
characters = document.getElementById('characters'),
pre = document.getElementsByTagName('pre')[0],
output = document.getElementById('output'),
permalink = document.getElementById('permalink'),
dds = document.getElementsByTagName('dd'),
before = dds[0],
after = dds[1],
ratio = dds[2],
regexNotBrainfuck = /[^\+\-<>\[\],\.]/g,
regexNumberGroup = /(?=(?:\d{3})+$)(?!\b)/g,
// http://mathiasbynens.be/notes/localstorage-pattern
storage = (function() {
try {
var storage = window.localStorage,
uid = new Date;
storage.setItem(uid, uid);
return storage.getItem(uid) == uid && storage;
} catch(e) {}
}()),
characterReferences;

function text(el, str) {
if (str == null) {
return el.innerText || el.textContent;
}
el.innerText != null && (el.innerText = str);
el.textContent != null && (el.textContent = str);
}

// Taken from http://mths.be/punycode
function ucs2decode(string) {
var output = [],
counter = 0,
length = string.length,
value,
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if ((value & 0xF800) == 0xD800) {
extra = string.charCodeAt(counter++);
if ((value & 0xFC00) != 0xD800 || (extra & 0xFC00) != 0xDC00) {
throw Error('Illegal UCS-2 sequence');
}
value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
}
output.push(value);
}
return output;
}

function formatNumber(number, unit) {
return (number == 0 ? '0' : String(number).replace(regexNumberGroup, ',')) + ' ' + unit + (number == 1 ? '' : 's');
}

function charCount(string) {
return ucs2decode(string).length;
}

function byteCount(string) {
return ~-encodeURI(string).split(/%..|./).length; // https://gist.github.com/1010324
}

function update() {
var value = textarea.value,
result = value.replace(regexNotBrainfuck, ''),
originalCharacterCount = charCount(value),
originalByteCount = byteCount(value),
resultingByteCount = byteCount(result); // byte and character counts are the same at this point
text(output, result || '[no output]');
pre.className = resultingByteCount ? '' : 'fail';
text(before, formatNumber(originalByteCount, 'byte') + (originalCharacterCount == originalByteCount ? '' : ' (assuming UTF-8); ' + formatNumber(originalCharacterCount, 'character')));
text(after, formatNumber(resultingByteCount, 'byte'));
text(ratio, (originalByteCount ? ((originalByteCount - resultingByteCount) / originalByteCount * 100) : 0).toFixed(2) + '%');

permalink.hash = encodeURIComponent(value);
storage && (storage.brainfuck = value);
};

textarea.onkeyup = update;
textarea.oninput = function() {
textarea.onkeyup = null;
update();
};

if (storage) {
storage.brainfuck && (textarea.value = storage.brainfuck);
update();
}

window.onhashchange = function() {
textarea.value = decodeURIComponent(location.hash.slice(1));
update();
};

if (location.hash) {
window.onhashchange();
}

}(this, document));

// Google Analytics
window._gaq = [['_setAccount', 'UA-6065217-60'], ['_trackPageview']];
(function(d, t) {
var g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
g.src = '//www.google-analytics.com/ga.js';
s.parentNode.insertBefore(g, s);
}(document, 'script'));
45 changes: 45 additions & 0 deletions brainfuck-minifier/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<title>Brainfuck minifier</title>
<meta name=viewport content="width=device-width">
<link rel=stylesheet href=eff.css>
<meta name=description content="An on-the-fly brainfuck minifier.">
<h1>Brainfuck minifier</h1>
<noscript><strong>To use this tool, please <a href=http://enable-javascript.com/>enable JavaScript</a> and reload the page.</strong></noscript>
<h2>Input</h2>
<textarea autofocus>+++++ +++++ initialize counter (cell #0) to 10
[ use loop to set the next four cells to 70/100/30/10
> +++++ ++ add 7 to cell #1
> +++++ +++++ add 10 to cell #2
> +++ add 3 to cell #3
> + add 1 to cell #4
&lt;&lt;&lt;&lt; - decrement counter (cell #0)
]
> ++ . print 'H'
> + . print 'e'
+++++ ++ . print 'l'
. print 'l'
+++ . print 'o'
> ++ . print ' '
&lt;&lt; +++++ +++++ +++++ . print 'W'
> . print 'o'
+++ . print 'r'
----- - . print 'l'
----- --- . print 'd'
> + . print '!'
> . print '\n'</textarea>
<h2>Minified result (<a href=#%E2%82%AC id=permalink>permalink</a>)</h2>
<pre><code id=output>++++++++++[>+++++++>++++++++++>+++>+&lt;&lt;&lt;&lt;-]>++.>+.+++++++..+++.>++.&lt;&lt;+++++++++++++++.>.+++.------.--------.>+.>.</code></pre>
<dl>
<dt>Before
<dd>1,082 bytes
<dt>After
<dd>111 bytes
<dt>Compression ratio
<dd>89.74%
</dl>
<h2>About brainfuck</h2>
<p><a href=http://esolangs.org/wiki/Brainfuck>Brainfuck</a> <i>(not capitalized except at the start of a sentence)</i> is an esoteric programming language. It has eight commands — <code>+-&lt;>[],.</code> — and ignores all other characters. As a result, no special syntax for comments is needed, as long as the comments don’t contain the command characters.
<p id=footer>Made by <a href=http://mathiasbynens.be/>@mathias</a><a href=https://github.com/mathiasbynens/mothereff.in/tree/master/brainfuck-minifier>fork this on GitHub!</a></p>
<script src=eff.js></script>

0 comments on commit 56b126d

Please sign in to comment.