Feb 2 2009

Hello Gene

While on breaks at work I’ve been reading a bit about Genetic Programming. The following is a quick-and-dirty python script I threw together (mostly for myself) the other night. It evolves the target string “Hello World” over several generations, starting with random strings. After a bit of experimentation I found that a population size of 300 seems to work best for this.

import random
import string
 
class GenePool:
    def __init__(self, population_size):
        self.population_size = population_size
        self.population = [self.generate()
                           for i in range(population_size)]
 
    def run(self):
        i = 0
        while True:
            print "Generation " + str(i) + ": " + self.population[0]
            i = i + 1
            if self.step():
                return
 
 
    def step(self):
        fittest = self.get_best(self.population_size/2)
        if self.successful(fittest[0]):
            print "Success! " + fittest[0]
            return True
        else:
            self.population = self.get_new_generation(fittest)
            return False
 
    def generate(self):
        return "".join([random.choice(string.ascii_letters + " ")
                         for i in range(11)])
 
    def evaluate(self, individual):
        s = "Hello World"
        total = 0
        for idx in range(len(s)):
            if individual[idx] == s[idx]:
                total = total + 1
        return total / 11.0
 
    def get_best(self, n):
        fitness = []
        for idx, individual in enumerate(self.population):
            fitness.append((idx, self.evaluate(individual)))
        fitness.sort(cmp=lambda x,y: cmp(x[1], y[1]), reverse=True)
        best = []
        return [self.population[tup[0]] for tup in fitness[:n]]
 
    def successful(self, individual):
        return individual == "Hello World"
 
    def get_new_generation(self, individuals):
        population = []
        while len(population) < int(self.population_size * 0.75):
            population.extend(self.breed(
                                    random.choice(individuals),
                                    random.choice(individuals)))
        while len(population) < self.population_size:
            population.append(self.generate())
        return population
 
    def breed(self, mother, father):
        point1 = random.randint(0,len(mother)-2)
        point2 = random.randint(point1+1, len(mother)-1)
        new1 = mother[:point1] + father[point1:point2] + mother[point2:]
        new2 = father[:point1] + mother[point1:point2] + father[point2:]
        if random.random() < 0.05:
            new1 = self.mutate(new1)
        if random.random() < 0.05:
            new2 = self.mutate(new2)
        return (new1, new2)
 
    def mutate(self, individual):
        x = list(individual)
        x[random.randint(0, len(x)-1)] = random.choice(
                                            random.choice(
                                              string.asciiletters + " "))
        return "".join(x)
 
if __name__ == "__main__":
    G = GenePool(300)
    G.run()

Jan 14 2009

Learning Java: Monty Hall Simulation

I’ve always found the Monty Hall problem kind of interesting. So I wrote a little Java program to demonstrate it. Here’s an example of the output:

C:\Home\working\java\MontyHall>java -jar MontyHallTest.jar 10000
Sticking with the same box wins 3368 out of 10000, or 33.68%
Switching boxes wins 6682 out of 10000, or 66.82%

Downloads:
montyhall.zip – source files.
montyhalltest.jar – java archive.


Jan 13 2009

Learning Java: Guess The Number

I’ve just finished reading the section on Basic I/O on the Java essential classes trail. So I put together a little Guess-The-Number game.

import java.io.*;
import java.lang.Math.*;
 
public class NumberGame {
    private Console c;
    private int upperBound;
    private int lowerBound;
 
    public NumberGame() {
        c = System.console();
        if (c == null) {
            System.err.println("Unable to aquire console. Exiting...");
            System.exit(1);
        }
    }
 
    private void playGame() {
        c.format("Welcome to the guess-the-number game!%n");
        c.format("Think of a number between 1 and 100 and I'll try to " +
                 "guess it!%n");
        upperBound = 100;
        lowerBound = 1;
        boolean finished;
        do {
            finished = makeGuess();
        } while (finished == false);
        c.format("Thank you for playing!%n");
    }
 
    private boolean makeGuess() {
        if (upperBound == lowerBound) {
            makeAccusation(upperBound);
            return true;
        }
        else {
            int choice = ((upperBound - lowerBound) / 2) + lowerBound;
            if (Math.random() < 0.5) {
                boolean answer = askYesOrNo(String.format("%nIs your " +
                                   "number higher than %d? ", choice));
                if (answer) {
                    lowerBound = choice + 1;
                }
                else {
                    upperBound = choice;
                }
            }
            else {
                boolean answer = askYesOrNo(String.format("%nIs your " +
                                   "number lower than %d? ", choice));
                if (answer) {
                    upperBound = choice;
                }
                else {
                    lowerBound = choice - 1;
                }
            }
        }
        return false;
    }
 
    private boolean askYesOrNo(String query) {
        int answer = -1;
        String result;
        char resultChar = ' ';
        while (true) {
            result = c.readLine(query);
            if (result != "") {
                result = result.toLowerCase();
                if (result.length() > 0) {
                    resultChar = result.charAt(0);
                    if (resultChar == 'y') {
                        return true;
                    }
                    else if (resultChar == 'n') {
                        return false;
                    }
                }
            c.format("Please answer 'yes' or 'no'.%n");
            }
        }
    }
 
    private void makeAccusation(int accusation) {
        boolean result = askYesOrNo(String.format("%nIs your number %d? ",
                                                            accusation));
        if (result) {
            c.format("Awesome!%n");
        }
        else {
            c.format("One of us is obviously confused.%n");
        }
    }
 
    public static void main(String[] args) {
        NumberGame ng = new NumberGame();
        ng.playGame();
    }
}

Jan 8 2009

Learning Java – Rot13

I’m planning to do a masters degree in computing in the next year or two. Most of the courses I’ve been looking at are built around Java, so I thought it would be a good idea to learn a bit now when I can relax and take my time. So I’ve been working through the tutorial over the last few days. I’m done with the basics and will shortly be moving on to those essential java classes. So I’m at the point where I can write some little programs to test that I actually do know what’s going on. This fancy book learning is all very well, but I like to get my hands dirty with whatever I’m trying to understand, so I’ll be trying out my knowledge as I go along.

This first program is pretty damn simple. But it’s the first program I’ve ever written in Java, so I’m kind of proud of it. It’s an implementation of the rot13 cipher.:

public class Rot13 {
    static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
    private static char rotateChar(char c) {
        if (Character.isLetter(c)) {
            int idx = ALPHABET.indexOf(Character.toLowerCase(c));
            idx += 13;
            if (idx >= 26) {
                idx -= 26;
            }
            char rotatedChar = ALPHABET.charAt(idx);
            if (Character.isUpperCase(c)) {
                return Character.toUpperCase(rotatedChar);
            }
            else {
                return rotatedChar;
            }
        }
        else {
            return c;
        }
    }
 
    public static String rotate(String source) {
        char[] resultArray = new char[source.length()];
        for (int i = 0; i < source.length(); i++) {
            resultArray[i] = rotateChar(source.charAt(i));
        }
        return new String(resultArray);
    }
 
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println(rotate(args[i]));
        }
    }
}

This stuff is easier in Python, where I’d write something like:

import string, sys
transtable = string.maketrans(string.ascii_letters,
                 string.ascii_lowercase[13:] +
                 string.ascii_lowercase[:13] +
                 string.ascii_uppercase[13:] +
                 string.ascii_uppercase[:13])
for arg in sys.argv[1:]:
    print string.translate(arg, transtable)

Actually, I could write it on one line using less than 200 characters. Not that this is a good idea, but...

import string as s;import sys;a=s.ascii_lowercase;
b=s.ascii_uppercase;[sys.stdout.write(s.translate(
arg,s.maketrans(s.ascii_letters,a[13:]+a[:13]+
b[13:]+b[:13]))+"\n") for arg in sys.argv[1:]]

So yeah, Java does seems a bit verbose at the moment.


Dec 20 2008

The Positivist Calendar

In 1849 Auguste Comte (1798-1857) published his ‘Calendrier positiviste’. This is not the place to expound Comte’s positivist philosophy, save to say that it encompassed lofty sentiments for the progress and betterment of the whole of mankind along rational lines. His calendar was intended as a vehicle for the inspiration of the people and to be transparently simple. Formally it broke new ground by dividing the year into 13 months, each containing 28 days or four seven-day weeks; these accounted for 364 days. The remaining day (or two days in leap years) were complementary epagomenal days placed at the end of the year; they did not belong to any week, nor were assigned a weekday name.

Mapping Time: The Calendar and its History, E.G. Richards

One of the nice things about the positivist calendar is that each day is dedicated to a particular person from history, ranging from Prometheus at the start of the year, all the way to Gall (a pioneer of neuroanatomy) at its end. This is also one of the reasons that few people other than Comte and his positivist friends took it seriously. Less fanciful attempts to reform the calendar have often failed, so Comte’s positivist calendar never stood a chance. These days it’s nothing more than an amusing historical footnote, which is a pity because even though it’s kind of ridiculous, it would be nice to live in a world where I could refer to today’s date as “Friday 19th Bichat, the day of Berthollet in the month of industry.” (That’s Marie François Xavier Bichat, an 18th Century French anatomist, and Claude Louis Berthollet, French chemist who helped devise modern chemical nomenclature.)

Obviously something had to be done. You can view the positivist date here. You can also download the source of the python script.


Dec 8 2008

Retro Browser Games

Back in the day before all this modern flash and ajax stuff, we’d use javascript for our in-browser games. And we liked it. And we had to code using our teeth to press the keys on our keyboards because we couldn’t afford arms.

Anyway, here’s a couple of slider games I made a long time ago, updated into modern javascript for your gaming pleasure. Go on – bask in the circa-1998 goodness.


Dec 8 2008

One-dimensional cellular automata in javascript

Here‘s my implementation of a simple cellular automata generator that runs entirely in your browser. Won’t work in Internet Explorer. Definitely works in Firefox. (Modern versions of IE don’t support X-Bitmap images). It’s more a curiosity than anything else and it’s not going to win any prizes for speed, but it’s a good example of image generation using pure client-side javascript.