Re this: https://www.theverge.com/2018/4/4/17199818/google-pentagon-project-maven-pull-out-letter-ceo-sundar-pichai
I’m of two minds on this story. On one hand, I get the that the programmers are unhappy about it, but on the other that algorithm will get written no matter what, so people who are good at implementation may have some sort of obligation to minimize civilian casualties by making sure it does its job well.
That and they’re working for Google. It’s not like they really have some sort of moral high ground just because what they do is starting to feel viscerally wrong as opposed to just wrong in the abstract.
Yeah ok, I’m not really in two minds about it as you might tell, I just said that to try and be less antagonistic about stuff. People just blanche when they can see the results of their actions clearly enough to make it impossible to deny them away. Shut up and write the war machine, Googlers, it’s probably the least damage you’ll do humanity all day.
I just ‘finished’ the puzzle game TIS-100, meaning I wrote a code that solves the final task of the game and saw all of the plot (other than the hidden puzzle. I’m not ready to tackle that mentally), so please listen to me rant why this is probably my favorite puzzle game of the 2010s, if not of all time.
First of all: what is it? It’s a game that tells you that you inherited a weird old time-y computer from your missing uncle and are trying to run some debuggers on it to figure out what it is. It comes with an ancient looking manual and very little else. If it sounds like a mystery game, it’s cause it is.
(Throughout this post, feel free to click to embiggen the images)
The game is really about designing algorithms in the mathematical sense: converting inputs into outputs. To do so you’re given a pretty simple assembly language architecture with one feature, and one huge caveat. The feature is that you have access to multiple chips that all run in parallel and can talk to each other. The caveat is that each only has a single register that can do storage, math, and logic, and a second register that can only be used as long term storage.
Got it? Ok, so let’s go over a solution to a puzzle, or more precisely my thought process of solving one. Spoiler warning obviously, if you want to solve each one yourself, don’t read this.
The TIS-100 in later levels includes a ‘graphics’ module that allows you to display pixel data that is being sent to the output. The format is a string of integers formed as
( Starting X coordinate, Starting Y coordinate, <series of integers representing colors to draw 1 square of>, -1 )
In this task we are given a length of a line, then a color to use for it. We have to figure out how to wrap at the edge of the screen if the line is longer than the screen width. Here’s what the tasks look like, along with my initial solution:
So how does a guy who loves nothing more than clean logical order and Object Orientation handle this? Simple, by creating treating each node as a make-shift object. Let me walk you through the code above.
First, we got to keep track of where we are on the screen:
The upper circled node iterates from 0 to 30 (screen width), then sends that data to the right. It also sends either 0 or -1 down to the node that keeps track of rows. The row tracking node (circled below) returns it’s stored value, and whenever it receives a -1 it increments the stored value. So now we got a steady generator that spits out
Now we have to keep track of what color we’re on. We got a third node for that:
This one stores the length of a color and the value of the color, then by swapping those in and out of the long term register it decrements the length and constructs a little quad packet like (0, 0, 2, -1). That particular packet would draw a grey square in top left for instance. The node then passes this packet down into the chain of helper passing nodes and off they go to the output off the bottom row.
I make this sound trivial, but in reality it took the better part of an hour to come up with this solution, and then a better part of a second hour debugging a bunch of silly deadlocks and memory corruption mistakes (having two nodes get out of sync and wait for input from each other so that they hang indefinitely, forgetting to swap memory contents before displaying, stuff like that).
So what kind of performance do we get on that? Well, this:
Not great compared to the average other user. So now we get to the second part of TIS-100. Optimizing to compete with the ‘others’ of the internet. So how can we optimize this?
Well, first thing that jumps out at me is that the bottom right node seems to be sending stuff pointlessly far. Look:
It really doesn’t have to go that far. What if instead of going all the way around, it just goes right? Now the top right packet constructor will only do 3 of the numbers, and the node below him will just plug in the row number from the left as we go. That should skim off a cycle or two, no? And skim them off the innermost loops too. Always good.
So now we’re just going straight right, though we needed to add a tiny bit of logic to the right to build the packet. 3 cycles less per each loop. Nice.
We can do better though, can’t we. I mean, what if we reärrange the nodes so that instead of the top right node acting as a packet constructor the packet gets constructed “as needed” and only in the last moment. A Just-In-Time packet, if you forgive the borderline archaic term. It would require moving the two “storage” nodes to below the input and then setting up an assembly line to the right of them. And oh look, the output is already set up exactly in the perfect spot for it. Hm. It’s like the designers knew this.
So at time A the packet is (?, ?, Color, ?).
At B we get (X, ?, Color, ?)
And only at C do we get (X, Y, Color, -1)
Now, how much of an improvement do we get?
Down from 7684 to 4898, so 36%. Not too shabby considering all we did was move some nodes around. Now, if we really wanted to make this mother fly, we would use that feature that lets us create longer packets. I mean, why send
A kickstarter micro from Joe (thank you Joe), and another fun travel game.
Roll dice to kill dragons. Blue is easy to kill, green is hard to kill, red is hard to kill. Very push your luck with one minor complication of “challenging” where you can force someone to fight 1 more dragon. I think this is one of those games that I’ve never won against anyone, cause for a mathematician I am surprisingly bad at anything push-your-luck.
No fear though. I am also a problem solver. I wrote a perl script to try every possible strategy of this game to find the ultimate path: http://www.codesend.com/view/27b4c6737ffb0f258d21f0870ef40f39/ (note, that page apparently stripped the slash from \n turning them into n, putting the slashes back in is left as an ‘exercise to the reader’)
Ran the above a million times as it plays the game against itself, and dumped out the results split first into 3 bravery strategies, then per line as to what dragons to fight first and when to stop: G is green, B is blue, R is red:
Requiem 32 is a series of virus genotypes, starting with a simple repeated ‘c’ which then in 31 iterations becomes the HIV genotype. Each of these iterations is then analyzed using a process based on biological DNA parsing which change the music created into a different piece, slowly more and more different from the original, until the original state is completely unrecognizable. I hope the piece gives helps create emotional understanding of the idea of a virus and how something that is so simple can have such an incredible impact, hopefully bridging the very real mental chasm between the biology of infection, and it’s effect on the infected.
For best experience, please make your browser window as large as possible and use headphones. To interact with the piece click the circles at the top. The RNA sequence clicked on and matching sheet music will be loaded and the piano performance encoded by that RNA string will start. 1 represents a starting state, and encodes the 4 E chords with a repeated E note 4 times. Each of the other states adds a tiny bit more complexity to the virus, creating progressively more and more changes to the music piece.
A visual guide for the RNA parsing is provided at left. The darker color is the header for a particular function, while the lighter color is the actual data processed by it. Each of the biological parsers, each represented by one color, begins at the top of the genotype, reads until it finds its starting trigger, and then starts reading while getting ready to apply a modification. Upon hitting the terminator (always “cc”), it applies the change to the music. It then keeps reading looking for a new starting condition.
The piece involves intrinsic looping in the structure of the music, similarly to how the biological processes do not function in a vacuum, but rely on a host organism to provide context to the RNA intrusion.
Technical notes: the majority of the code is written in python, with the exception of the text parser which creates the 30 intermediate states which is written in perl. When ran using the ./go shell command, the python code will open all rna files, processes them, then output both a color coded html file and the midi file represented. The file ‘models.py’ contains the actual structure of the music: repeated sequences that contain a chordal structure, and a melody played on top; while the file ‘driver.py’ contains the actual mechanism of parsing of the text into midi. The final mp3s and pngs of the sheet music were both created by hand and are currently not automated.
Finally, I genuinely apologize for any possible layout issues with your particular hardware/software setup. This was designed under time constraints as a standing installation using Safari in full-screen mode, and unfortunately cross-platform compatibility was not a priority. I welcome any pull requests with improvements.
If I start coding before I sit down and make one of these, I’ll never get anywhere. I need to have a mental visual relationship between everything, before I can start.
Visual memory is very important in programming for me. I really value IDEs that have one of those sublime-style “code maps” on the side, and ones that let me skip to bookmarks and function definitions easily, preferably with a single click. Not having to think about where I am in the file lets me concentrate on more useful things.
Another weird thing is that sketching process is so far it only works for me with pen and paper. I’d love to have an iPad with enough input resolution to properly let me sketch but so far none of the tools are good enough at it.