Clicky

🐪 Reformed JAPHs: Transpiler

Note: This post was edited for clarity. For the final JAPH in this series, I implemented a simple transpiler that converts a small subset of Scheme programs to equivalent Python programs. It starts with a Scheme program that prints 'just another scheme hacker'. (define (output x) (if (null? x) "" (begin (display (car x)) (if (null? (cdr x)) (display "\n") (begin (display " ") (output (cdr x))))))) (output (list "just" "another" "scheme" "hacker")) The program then tokenizes that Scheme source, parses the token stream, and converts that into Python 3. ...

April 20, 2011 · Ryan O'Neil

🐪 Reformed JAPHs: Turing Machine

Note: This post was edited for clarity. This JAPH uses a Turing machine. The machine accepts any string that ends in '\n' and allows side effects. This lets us print the value of the tape as it encounters each character. While the idea of using lambda functions as side effects in a Turing machine is a little bizarre on many levels, we work with what we have. And Python is multi-paradigmatic, so what the heck. ...

April 18, 2011 · Ryan O'Neil

🐪 Reformed JAPHs: Huffman Coding

Note: This post was edited for clarity. At this point, tricking python into printing strings via indirect means got a little boring. So I switched to obfuscating fundamental computer science algorithms. Here’s a JAPH that takes in a Huffman coded version of 'just another python hacker', decodes, and prints it. # Build coding tree def build_tree(scheme): if scheme.startswith('*'): left, scheme = build_tree(scheme[1:]) right, scheme = build_tree(scheme) return (left, right), scheme else: return scheme[0], scheme[1:] def decode(tree, encoded): ret = '' node = tree for direction in encoded: if direction == '0': node = node[0] else: node = node[1] if isinstance(node, str): ret += node node = tree return ret tree = build_tree('*****ju*sp*er***yct* h**ka*no')[0] print( decode(tree, bin(10627344201836243859174935587).lstrip('0b').zfill(103)) ) The decoding tree is like a LISP-style sequence of pairs. '*' represents a branch in the tree while other characters are leaf nodes. This looks like the following. ...

April 14, 2011 · Ryan O'Neil

🐪 Reformed JAPHs: Rolling Effect

Note: This post was updated to work with Python 3.12. It may not work with different versions. Here’s a JAPH composed solely for effect. For each letter in 'just another python hacker' it loops over each the characters ' abcdefghijklmnopqrstuvwxyz', printing each. Between characters it pauses for 0.05 seconds, backing up and moving on to the next if it hasn’t reached the desired one yet. This achieves a sort of rolling effect by which the final string appears on our screen over time. ...

April 11, 2011 · Ryan O'Neil

🐪 Reformed JAPHs: ROT13

Note: This post was updated to work with Python 3.12. It may not work with different versions. No series of JAPHs would be complete without ROT13. This is the example through which aspiring Perl programmers learn to use tr and its synonym y. In Perl the basic ROT13 JAPH starts as: $foo = 'whfg nabgure crey unpxre'; $foo =~ y/a-z/n-za-m/; print $foo; Python has nothing quite so elegant in its default namespace. However, this does give us the opportunity to explore a little used aspect of strings: the translate method. If we construct a dictionary of ordinals we can accomplish the same thing with a touch more effort. ...

April 6, 2011 · Ryan O'Neil

🐪 Reformed JAPHs: Ridiculous Anagram

Here’s the second in my reformed JAPH series. It takes an anagram of 'just another python hacker' and converts it prior to printing. It sorts the anagram by the indices of another string, in order of their associated characters. This is sort of like a pre-digested Schwartzian transform. x = 'upjohn tehran hectors katy' y = '1D0HG6JFO9P5ICKAM87B24NL3E' print(''.join(x[i] for i in sorted(range(len(x)), key=lambda p: y[p]))) Obfuscation consists mostly of using silly machinations to construct the string we use to sort the anagram. ...

April 3, 2011 · Ryan O'Neil

🐪 Reformed JAPHs: Alphabetic Indexing

Note: This post was edited for clarity. Many years ago, I was a Perl programmer. Then one day I became disillusioned at the progress of Perl 6 and decided to import this. This seems to be a fairly common story for Perl to Python converts. While I haven’t looked back much, there are a number of things I really miss about perl (lower case intentional). I miss having value types in a dynamic language, magical and ill-advised use of cryptocontext, and sometimes even pseudohashes because they were inexcusably weird. A language that supports so many ideas out of the box enables an extended learning curve that lasts for many years. “Perl itself is the game.” ...

April 1, 2011 · Ryan O'Neil