tiny turing machine in C v2

Here is the second version of my DTM in C. I used a linked list so the tape can be much larger.

// could probably be much smaller given some work.
// compressed version
 
#include <stdio.h>
#define w while
#define b break
int i,j;char s='S',d[]="S0a0>S1a0>a0a0>a1a0>a-H--";struct t{t*l;t*r;char v;};
int main(int c, char**v){t*h=0;w(v[1][j]){t*n=new t;n->v=v[1][j];n->l=h;n->r=0;if(h)h->r=n;
h=n;++j;}w(1){if(!h->l)b;h=h->l;}w(1){if(s=='H')b;i=0;w(d[i]){if(s==d[i]&&h->v==d[i+1]){
s=d[i+2];h->v=d[i+3];t*m=new t;m->v='-';if(d[i+4]=='<'){if(!h->l){m->l=0;m->r=h;h->l=m;}
h=h->l;}if(d[i+4]=='>'){if(!h->r){m->l=h;m->r=0;h->r=m;}h=h->r;}b;}i+=5;}}printf("%c:",s);
w(1){if(!h->l)b;h=h->l;}w(h){putchar(h->v);h=h->r;};return 0;}
 
// readable version
 
#include <stdio.h>
 
int i,j;
 
char state = 'S';
char delta[] = "S0a0>S1a0>a0a0>a1a0>a-H--";
 
// node for linked list
struct cell
{
	cell		*left;
	cell		*right;
	char	        value;
};
 
int main(int argc, char **argv)
{
	// create the head
	cell*		head = 0;
 
	// write input to tape
	while ( argv[1][j] ) {
		// make a new cell for each input character
		cell* newCell = new cell;
		newCell->value = argv[1][j];
 
		// add it to the right of head
		newCell->left = head;
		newCell->right = 0;
 
		// if head is a node, add newCell to the left
		if (head) 
			head->right = newCell;
 
		// move head to the newCell
		head = newCell;
 
		++j;
	}
 
	// move head to leftmost character
	while (1) {
		// stop if the next cell is empty
		if(!head->left) 
			break;
 
		head = head->left;
	}
 
	while (1) {
		// exit if we reach the halting state
		if ( state == 'H') break;
 
		i = 0;
		// check the delta function
		while (delta[i]) {
			// does current state and head value match?
			if(state == delta[i] && head->value == delta[i+1]){
				// switch to new state
				state = delta[i+2];
				// write new value
				head->value = delta[i+3];
 
				// create a new cell (might need this, might not)
				cell* blankCell = new cell;
				blankCell->value = '-';
 
				// are we moving to the left?
				if (delta[i+4] == '<') {
					// add blankCell if there is no cell here
					if (!head->left) {
						blankCell->left = 0;
						blankCell->right = head;
						head->left = blankCell;
					}
 
					// set head to left cell
					head = head->left;
				}
 
				// are we moving to the right?
				if (delta[i+4] == '>') {
					// add blankCell if there is no cell here
					if (!head->right) {
						blankCell->left = head;
						blankCell->right = 0;
						head->right = blankCell;
					}
 
					// set head to right cell
					head = head->right;
				}
 
				break;
			}
			i+=5;
		}
	}
 
	// print the state
	printf("%c:",state);
 
	// move head to far left
	while (1) {
		if ( !head->left )
			break;
 
		head = head->left;
	}
 
	// move from left to right, printing cell value as we go.
	while (head) {
		putchar( head->value );
		head = head->right;
	};
 
	// note, we should delete the tape here but we're trying to be small so... ;)
 
	return 0;
}

tiny turing machine in C

I while ago I had a little contest with a friend to write a C/C++ Deterministic Turing Machine (DTM) in as little bytes of code as possible. We drew up a simple specification and set to work! Here’s mine (uncompressed):

#include <stdio.h>
#define w while
 
int i,j,k,h=1024;
char s='S',t[2049],d[]="S0a0>S1a0>a0a0>a1a0>a-H--";
 
int main(int c, char**v)
{
    w(i<h*2){t[i]='-';++i;}t[i]='\n';
    w(v[1][j]){t[j+h]=v[1][j];++j;};
    w(1){
        if(s=='H')break;i=0;
        w(d[i]){
            if (s==d[i]&&t[h]==d[i+1]){
                s=d[i+2];t[h]=d[i+3];
                h-=d[i+4]=='<';
                h+=d[i+4]=='>';
                break;
            }
            i+=5;
        }
    }
    printf("%c:",s);
    w(k<2049){if(t[k]!='-')putchar(t[k]);++k;};
    return 0;
}

The delta function is encoded in a char array. The DTM checks every fifth index i for a matching state and i+1 for a matching character on the tape. When it finds a match it changes to state i+2, writes i+3 and moves i+4. This way I can encode the delta function in as little space as possible. I used a fair amount of while loops and it worked out cheaper to add a #define. One neat trick I used was adding/subtracting the result of a boolean operation to change the h value.

h-=d[i+4]=='<';

This will subtract 1 if the head should move left, otherwise it will subtract 0 (do nothing). This removed the need for an if statement and got the code down by a couple of bytes.

Overall I am pretty happy. A limitation would be that the tape has a finite number of cells, but we agreed to this in our specification. I plan to write a Non-deterministic Turing Machine (NTM) next time I have a slow-day. This time I will use a linked list so the tape length is limited only by the size of the systems RAM.

a big list of tlds

I needed a big list of Top Level Domains (TLDs) for a small project I’ve been working on. It’s a pretty easy job with vim, some regex and a copy of this – but I’ve included it here for anyone that might be Googling for it.

You can get the full list here, but I’ve also included a handy selection of arrays.

The complete list was build with this vim command

:%s/^\.\([a-z]*\)\(.*\)$/.\1/

and one line of manual pruning.

tmux with irssi – ncurses redraw bug

I recently noticed that in large terminals (over 40 rows) irssi won’t draw properly with tmux. Apparently this is a bug with tmux. It’s easy to fix, just add the following line to your ~/.tmux.conf and the problem should go away!

# set correct term
set -g default-terminal screen-256color

Google Talk chatback badge – auto open chat

Just recently I needed to make a Google Talk chatback session start automatically, that a website could offer assistance after x amount of idletime and start the chat upon request. Far cleaner than asking them to click a link, I wanted the session to initiate once a user click “Yes, start live chat!” (or something to that effect).

The problem, was the Google Talk chatback badge uses an iFrame. I wanted to use jQuery to click the “open” link, but because of cross-domain scripting security within browsers this wasn’t possible.

My solution was quite simple. First of all I realised that I could easily grab the source to my chatback badge.

$ wget "http://www.google.com/talk/service/badge/Show?tk=...&amp;w=200&amp;h=60" -O talkBadge.html

Then I modified the talkBadge.html file to fix the broken resources. I did this with vim, since I already had it open, but you can do it with any tool using a simple search and replace.

:%s/"\/talk\//"http:\/\/www.google.com\/talk\//g

This replaces “/talk/ with “http://www.google.com/talk/. Finally I modified line 56 to give the a tag id=”talkLink”.

Now it was as easy as including the iFrame to my page as usual, but with the new talkBadge.html.

<iframe id="talkBadge" src="talkBadge.html" frameborder="0" allowtransparency="true" width="200" height="60"></iframe>

And then you can open the chatbox with the following line of Javascript (using jQuery).

$('#talkBox').contents().find('#talkLink').click();

I used the setTimeout function and a jQuery UI Dialog box to build a quick “Do you require assistance?” alert. Works a treat.