Mittwoch, 9. März 2011

Building a Word Clock - Part 1: Genetic Algorithms

UPDATE: part two

UPDATE 11-APR-2012: removed typos (fourty -> forty), changed the :05 times to "o five" (thanks Thopter and Andrew from Hack-A-Day) and added a German circular clock.

UPDATE 12-APR-2012: put the code on github and added an english 10x10 clock.

One day I came by a shop that sold this fancy QLOCKTWO word clock and decided that I want one of these. The only problem is that they cost around 1000€ - which is kind of a lot for a clock. The obvious solution? Build one yourself!

Other Word Clocks

After a little bit of googling I found a couple of people that had already done that.

[Doug Jackson] made one using a etched PCB as stencil for the letters and is even selling kits if you want to build one. He also posted the instructions for building one here and here and here .

A deriavate from [scottbez1] can be found here .

There is a Polish version of the clock from [miswierz] which can be found here

A guy called [Christian] build a German version of the word clock which you can find here

They all have one thing in common (beside having a lot of LEDs and a stencil that is):
they use more or less the same word pattern for the clock - pretty much identical to the QLOCKTWO.

Make it different

First of all I don't like to just copy other peoples work and second I wanted to find out if you can do that different.
The idea is to write a genetic algorithm that actually computes a stencil for the word clock.

Theory

Ok, I'm going to keep this one short. I'm not an expert in GA so feel free to correct me if some details are a little bit fuzzy or just plain wrong.

I just wanted to really understand the GAs and decided to program it completely by myself. For a real problem you would of course use one of the many GA frameworks (JGAP for example)

A GA works on a so called population of candidates. Each candidate represents one possible solution to a given problem. The GA now tries to find a better candidate by modifying or combining candidates in the population.

In order to be able to do that the GA needs something called a fitness function. Basically this function evaluates how good of a solution for the problem the candidate is.

The second thing a GA needs is a set of operations that it can perform on the population in order to create new candidates. This could be the crossover (i.e. combination of two candidates) or the mutation (i.e. random changing of parts of a candidate).

After the GA created a new candidate it calculate its fitness and decides if it keeps it (i.e. put it in the population) or not. By keeping the good and discarding the bad candidates the population evolves and we end up having better and better candidates. Sounds simple enough, lets try it!

GA applied to a word clock

First we need to represent the word clock in a manner that we can work with it. I decided to go with the format
XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX|XXXXXXXXXX
with X being a random letter and | being a line break. The example above would be the 10x10 word clock
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX

The fitness function

So how good is the candidate above? Well obviously its a pretty bad one - it cant represent even a single time. And that's exactly our fitness function: out of all 144 possible times (12 hour clock with 5 minute interval) how many of them can we represent?

The candidate above can represent 0, the one below (for a 11x11 English word clock) can represent 159 out of 144

elevenntsix|sevenfourty|twelvehotwo|eightoneten|threertnine|fivefifteen|twentypastl|fourthytenv|fiftythirty|clockfourty|gtwofiveten
Why 159 out of 144? Well because some times can be written in multiple formats - e.g. 04:10 can be written as "four ten"
elevenntsix|sevenFOURty|twelvehotwo|eightoneTEN|threertnine|fivefifteen|twentypastl|fourthytenv|fiftythirty|clockfourty|gtwofiveten
or as "ten past four"
elevenntsix|sevenfourty|twelvehotwo|eightoneTEN|threertnine|fivefifteen|twentyPASTl|fourthytenv|fiftythirty|clockFOURty|gtwofiveten
The actual algorithm (sources can be find below) uses regular expressions to find out how many times can be represented. For the example above 04:10 would be either .*four.+ten.* or .*ten+*past+*four.*. If the regex matches the time can be represented, if not it can't.

By building a regex for every single time you can check if the clock can represent every time of the day.

You can find all regular expressions at the end of the post.

The operators

I played around with a couple of operators but in the end the following two turned out to be the most useful:
  • Combination: just take two candidates from the population (prefer the good ones but sometimes also pick bad ones) and combine them together (e.g. take the first 10 characters for the first candidate and the rest from the second)
  • Word Insertion: pick a random candidate and insert a random word at a random position - with the list of words being given by the times (e.g. "four", "ten", "past", ...)

The Results

Well, the GA works, but sometimes it gets stuck in a local minimum and needs to be reset. But in the end it turned out to work quite well. I used it to generate the 10x10 German word clock that I actually build and to generate the 11x11 English version mentioned above.

I don't exactly know why but it wasn't able to find any english word clock solution smaller than 11x11, maybe I messed things up somewhere. Here is a small JavaScript version of the clock (it doesn't show the real time but you can play around with it)

German 10x10

English 10x10

English 11x11

Actually there is no reason why you couldn't build not rectangular clocks.

Why not build a circular clock?

Or triangular?

Diamond shaped?

Circular clock in German

The Code

This are the regular expressions for English and German word clocks.
01:00 : (.*)(one)(.+)(o)(.+)(clock)(.*)
01:05 : (.*)(five)(.+)(past)(.+)(one)(.*)
01:05 : (.*)(one)(.+)(o)(.+)(five)(.*)
01:10 : (.*)(ten)(.+)(past)(.+)(one)(.*)
01:10 : (.*)(one)(.+)(ten)(.*)
01:15 : (.*)(fifteen)(.+)(past)(.+)(one)(.*)
01:15 : (.*)(one)(.+)(fifteen)(.*)
01:15 : (.*)(quarter)(.+)(past)(.+)(one)(.*)
01:20 : (.*)(twenty)(.+)(past)(.+)(one)(.*)
01:20 : (.*)(one)(.+)(twenty)(.*)
01:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(one)(.*)
01:25 : (.*)(one)(.+)(twenty)(.*)(five)(.*)
01:30 : (.*)(thirty)(.+)(past)(.+)(one)(.*)
01:30 : (.*)(one)(.+)(thirty)(.*)
01:30 : (.*)(half)(.+)(past)(.+)(one)(.*)
01:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(one)(.*)
01:35 : (.*)(one)(.+)(thirty)(.*)(five)(.*)
01:40 : (.*)(forty)(.+)(past)(.+)(one)(.*)
01:40 : (.*)(one)(.+)(forty)(.*)
01:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(one)(.*)
01:45 : (.*)(one)(.+)(forty)(.*)(five)(.*)
01:45 : (.*)(quarter)(.+)(to)(.+)(two)(.*)
01:50 : (.*)(fifty)(.+)(past)(.+)(one)(.*)
01:50 : (.*)(one)(.+)(fifty)(.*)
01:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(one)(.*)
01:55 : (.*)(one)(.+)(fifty)(.*)(five)(.*)
02:00 : (.*)(two)(.+)(o)(.+)(clock)(.*)
02:05 : (.*)(five)(.+)(past)(.+)(two)(.*)
02:05 : (.*)(two)(.+)(o)(.+)(five)(.*)
02:10 : (.*)(ten)(.+)(past)(.+)(two)(.*)
02:10 : (.*)(two)(.+)(ten)(.*)
02:15 : (.*)(fifteen)(.+)(past)(.+)(two)(.*)
02:15 : (.*)(two)(.+)(fifteen)(.*)
02:15 : (.*)(quarter)(.+)(past)(.+)(two)(.*)
02:20 : (.*)(twenty)(.+)(past)(.+)(two)(.*)
02:20 : (.*)(two)(.+)(twenty)(.*)
02:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(two)(.*)
02:25 : (.*)(two)(.+)(twenty)(.*)(five)(.*)
02:30 : (.*)(thirty)(.+)(past)(.+)(two)(.*)
02:30 : (.*)(two)(.+)(thirty)(.*)
02:30 : (.*)(half)(.+)(past)(.+)(two)(.*)
02:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(two)(.*)
02:35 : (.*)(two)(.+)(thirty)(.*)(five)(.*)
02:40 : (.*)(forty)(.+)(past)(.+)(two)(.*)
02:40 : (.*)(two)(.+)(forty)(.*)
02:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(two)(.*)
02:45 : (.*)(two)(.+)(forty)(.*)(five)(.*)
02:45 : (.*)(quarter)(.+)(to)(.+)(three)(.*)
02:50 : (.*)(fifty)(.+)(past)(.+)(two)(.*)
02:50 : (.*)(two)(.+)(fifty)(.*)
02:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(two)(.*)
02:55 : (.*)(two)(.+)(fifty)(.*)(five)(.*)
03:00 : (.*)(three)(.+)(o)(.+)(clock)(.*)
03:05 : (.*)(five)(.+)(past)(.+)(three)(.*)
03:05 : (.*)(three)(.+)(o)(.+)(five)(.*)
03:10 : (.*)(ten)(.+)(past)(.+)(three)(.*)
03:10 : (.*)(three)(.+)(ten)(.*)
03:15 : (.*)(fifteen)(.+)(past)(.+)(three)(.*)
03:15 : (.*)(three)(.+)(fifteen)(.*)
03:15 : (.*)(quarter)(.+)(past)(.+)(three)(.*)
03:20 : (.*)(twenty)(.+)(past)(.+)(three)(.*)
03:20 : (.*)(three)(.+)(twenty)(.*)
03:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(three)(.*)
03:25 : (.*)(three)(.+)(twenty)(.*)(five)(.*)
03:30 : (.*)(thirty)(.+)(past)(.+)(three)(.*)
03:30 : (.*)(three)(.+)(thirty)(.*)
03:30 : (.*)(half)(.+)(past)(.+)(three)(.*)
03:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(three)(.*)
03:35 : (.*)(three)(.+)(thirty)(.*)(five)(.*)
03:40 : (.*)(forty)(.+)(past)(.+)(three)(.*)
03:40 : (.*)(three)(.+)(forty)(.*)
03:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(three)(.*)
03:45 : (.*)(three)(.+)(forty)(.*)(five)(.*)
03:45 : (.*)(quarter)(.+)(to)(.+)(four)(.*)
03:50 : (.*)(fifty)(.+)(past)(.+)(three)(.*)
03:50 : (.*)(three)(.+)(fifty)(.*)
03:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(three)(.*)
03:55 : (.*)(three)(.+)(fifty)(.*)(five)(.*)
04:00 : (.*)(four)(.+)(o)(.+)(clock)(.*)
04:05 : (.*)(five)(.+)(past)(.+)(four)(.*)
04:05 : (.*)(four)(.+)(o)(.+)(five)(.*)
04:10 : (.*)(ten)(.+)(past)(.+)(four)(.*)
04:10 : (.*)(four)(.+)(ten)(.*)
04:15 : (.*)(fifteen)(.+)(past)(.+)(four)(.*)
04:15 : (.*)(four)(.+)(fifteen)(.*)
04:15 : (.*)(quarter)(.+)(past)(.+)(four)(.*)
04:20 : (.*)(twenty)(.+)(past)(.+)(four)(.*)
04:20 : (.*)(four)(.+)(twenty)(.*)
04:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(four)(.*)
04:25 : (.*)(four)(.+)(twenty)(.*)(five)(.*)
04:30 : (.*)(thirty)(.+)(past)(.+)(four)(.*)
04:30 : (.*)(four)(.+)(thirty)(.*)
04:30 : (.*)(half)(.+)(past)(.+)(four)(.*)
04:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(four)(.*)
04:35 : (.*)(four)(.+)(thirty)(.*)(five)(.*)
04:40 : (.*)(forty)(.+)(past)(.+)(four)(.*)
04:40 : (.*)(four)(.+)(forty)(.*)
04:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(four)(.*)
04:45 : (.*)(four)(.+)(forty)(.*)(five)(.*)
04:45 : (.*)(quarter)(.+)(to)(.+)(five)(.*)
04:50 : (.*)(fifty)(.+)(past)(.+)(four)(.*)
04:50 : (.*)(four)(.+)(fifty)(.*)
04:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(four)(.*)
04:55 : (.*)(four)(.+)(fifty)(.*)(five)(.*)
05:00 : (.*)(five)(.+)(o)(.+)(clock)(.*)
05:05 : (.*)(five)(.+)(past)(.+)(five)(.*)
05:05 : (.*)(five)(.+)(o)(.+)(five)(.*)
05:10 : (.*)(ten)(.+)(past)(.+)(five)(.*)
05:10 : (.*)(five)(.+)(ten)(.*)
05:15 : (.*)(fifteen)(.+)(past)(.+)(five)(.*)
05:15 : (.*)(five)(.+)(fifteen)(.*)
05:15 : (.*)(quarter)(.+)(past)(.+)(five)(.*)
05:20 : (.*)(twenty)(.+)(past)(.+)(five)(.*)
05:20 : (.*)(five)(.+)(twenty)(.*)
05:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(five)(.*)
05:25 : (.*)(five)(.+)(twenty)(.*)(five)(.*)
05:30 : (.*)(thirty)(.+)(past)(.+)(five)(.*)
05:30 : (.*)(five)(.+)(thirty)(.*)
05:30 : (.*)(half)(.+)(past)(.+)(five)(.*)
05:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(five)(.*)
05:35 : (.*)(five)(.+)(thirty)(.*)(five)(.*)
05:40 : (.*)(forty)(.+)(past)(.+)(five)(.*)
05:40 : (.*)(five)(.+)(forty)(.*)
05:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(five)(.*)
05:45 : (.*)(five)(.+)(forty)(.*)(five)(.*)
05:45 : (.*)(quarter)(.+)(to)(.+)(six)(.*)
05:50 : (.*)(fifty)(.+)(past)(.+)(five)(.*)
05:50 : (.*)(five)(.+)(fifty)(.*)
05:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(five)(.*)
05:55 : (.*)(five)(.+)(fifty)(.*)(five)(.*)
06:00 : (.*)(six)(.+)(o)(.+)(clock)(.*)
06:05 : (.*)(five)(.+)(past)(.+)(six)(.*)
06:05 : (.*)(six)(.+)(o)(.+)(five)(.*)
06:10 : (.*)(ten)(.+)(past)(.+)(six)(.*)
06:10 : (.*)(six)(.+)(ten)(.*)
06:15 : (.*)(fifteen)(.+)(past)(.+)(six)(.*)
06:15 : (.*)(six)(.+)(fifteen)(.*)
06:15 : (.*)(quarter)(.+)(past)(.+)(six)(.*)
06:20 : (.*)(twenty)(.+)(past)(.+)(six)(.*)
06:20 : (.*)(six)(.+)(twenty)(.*)
06:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(six)(.*)
06:25 : (.*)(six)(.+)(twenty)(.*)(five)(.*)
06:30 : (.*)(thirty)(.+)(past)(.+)(six)(.*)
06:30 : (.*)(six)(.+)(thirty)(.*)
06:30 : (.*)(half)(.+)(past)(.+)(six)(.*)
06:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(six)(.*)
06:35 : (.*)(six)(.+)(thirty)(.*)(five)(.*)
06:40 : (.*)(forty)(.+)(past)(.+)(six)(.*)
06:40 : (.*)(six)(.+)(forty)(.*)
06:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(six)(.*)
06:45 : (.*)(six)(.+)(forty)(.*)(five)(.*)
06:45 : (.*)(quarter)(.+)(to)(.+)(seven)(.*)
06:50 : (.*)(fifty)(.+)(past)(.+)(six)(.*)
06:50 : (.*)(six)(.+)(fifty)(.*)
06:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(six)(.*)
06:55 : (.*)(six)(.+)(fifty)(.*)(five)(.*)
07:00 : (.*)(seven)(.+)(o)(.+)(clock)(.*)
07:05 : (.*)(five)(.+)(past)(.+)(seven)(.*)
07:05 : (.*)(seven)(.+)(o)(.+)(five)(.*)
07:10 : (.*)(ten)(.+)(past)(.+)(seven)(.*)
07:10 : (.*)(seven)(.+)(ten)(.*)
07:15 : (.*)(fifteen)(.+)(past)(.+)(seven)(.*)
07:15 : (.*)(seven)(.+)(fifteen)(.*)
07:15 : (.*)(quarter)(.+)(past)(.+)(seven)(.*)
07:20 : (.*)(twenty)(.+)(past)(.+)(seven)(.*)
07:20 : (.*)(seven)(.+)(twenty)(.*)
07:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(seven)(.*)
07:25 : (.*)(seven)(.+)(twenty)(.*)(five)(.*)
07:30 : (.*)(thirty)(.+)(past)(.+)(seven)(.*)
07:30 : (.*)(seven)(.+)(thirty)(.*)
07:30 : (.*)(half)(.+)(past)(.+)(seven)(.*)
07:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(seven)(.*)
07:35 : (.*)(seven)(.+)(thirty)(.*)(five)(.*)
07:40 : (.*)(forty)(.+)(past)(.+)(seven)(.*)
07:40 : (.*)(seven)(.+)(forty)(.*)
07:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(seven)(.*)
07:45 : (.*)(seven)(.+)(forty)(.*)(five)(.*)
07:45 : (.*)(quarter)(.+)(to)(.+)(eight)(.*)
07:50 : (.*)(fifty)(.+)(past)(.+)(seven)(.*)
07:50 : (.*)(seven)(.+)(fifty)(.*)
07:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(seven)(.*)
07:55 : (.*)(seven)(.+)(fifty)(.*)(five)(.*)
08:00 : (.*)(eight)(.+)(o)(.+)(clock)(.*)
08:05 : (.*)(five)(.+)(past)(.+)(eight)(.*)
08:05 : (.*)(eight)(.+)(o)(.+)(five)(.*)
08:10 : (.*)(ten)(.+)(past)(.+)(eight)(.*)
08:10 : (.*)(eight)(.+)(ten)(.*)
08:15 : (.*)(fifteen)(.+)(past)(.+)(eight)(.*)
08:15 : (.*)(eight)(.+)(fifteen)(.*)
08:15 : (.*)(quarter)(.+)(past)(.+)(eight)(.*)
08:20 : (.*)(twenty)(.+)(past)(.+)(eight)(.*)
08:20 : (.*)(eight)(.+)(twenty)(.*)
08:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(eight)(.*)
08:25 : (.*)(eight)(.+)(twenty)(.*)(five)(.*)
08:30 : (.*)(thirty)(.+)(past)(.+)(eight)(.*)
08:30 : (.*)(eight)(.+)(thirty)(.*)
08:30 : (.*)(half)(.+)(past)(.+)(eight)(.*)
08:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(eight)(.*)
08:35 : (.*)(eight)(.+)(thirty)(.*)(five)(.*)
08:40 : (.*)(forty)(.+)(past)(.+)(eight)(.*)
08:40 : (.*)(eight)(.+)(forty)(.*)
08:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(eight)(.*)
08:45 : (.*)(eight)(.+)(forty)(.*)(five)(.*)
08:45 : (.*)(quarter)(.+)(to)(.+)(nine)(.*)
08:50 : (.*)(fifty)(.+)(past)(.+)(eight)(.*)
08:50 : (.*)(eight)(.+)(fifty)(.*)
08:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(eight)(.*)
08:55 : (.*)(eight)(.+)(fifty)(.*)(five)(.*)
09:00 : (.*)(nine)(.+)(o)(.+)(clock)(.*)
09:05 : (.*)(five)(.+)(past)(.+)(nine)(.*)
09:05 : (.*)(nine)(.+)(o)(.+)(five)(.*)
09:10 : (.*)(ten)(.+)(past)(.+)(nine)(.*)
09:10 : (.*)(nine)(.+)(ten)(.*)
09:15 : (.*)(fifteen)(.+)(past)(.+)(nine)(.*)
09:15 : (.*)(nine)(.+)(fifteen)(.*)
09:15 : (.*)(quarter)(.+)(past)(.+)(nine)(.*)
09:20 : (.*)(twenty)(.+)(past)(.+)(nine)(.*)
09:20 : (.*)(nine)(.+)(twenty)(.*)
09:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(nine)(.*)
09:25 : (.*)(nine)(.+)(twenty)(.*)(five)(.*)
09:30 : (.*)(thirty)(.+)(past)(.+)(nine)(.*)
09:30 : (.*)(nine)(.+)(thirty)(.*)
09:30 : (.*)(half)(.+)(past)(.+)(nine)(.*)
09:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(nine)(.*)
09:35 : (.*)(nine)(.+)(thirty)(.*)(five)(.*)
09:40 : (.*)(forty)(.+)(past)(.+)(nine)(.*)
09:40 : (.*)(nine)(.+)(forty)(.*)
09:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(nine)(.*)
09:45 : (.*)(nine)(.+)(forty)(.*)(five)(.*)
09:45 : (.*)(quarter)(.+)(to)(.+)(ten)(.*)
09:50 : (.*)(fifty)(.+)(past)(.+)(nine)(.*)
09:50 : (.*)(nine)(.+)(fifty)(.*)
09:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(nine)(.*)
09:55 : (.*)(nine)(.+)(fifty)(.*)(five)(.*)
10:00 : (.*)(ten)(.+)(o)(.+)(clock)(.*)
10:05 : (.*)(five)(.+)(past)(.+)(ten)(.*)
10:05 : (.*)(ten)(.+)(o)(.+)(five)(.*)
10:10 : (.*)(ten)(.+)(past)(.+)(ten)(.*)
10:10 : (.*)(ten)(.+)(ten)(.*)
10:15 : (.*)(fifteen)(.+)(past)(.+)(ten)(.*)
10:15 : (.*)(ten)(.+)(fifteen)(.*)
10:15 : (.*)(quarter)(.+)(past)(.+)(ten)(.*)
10:20 : (.*)(twenty)(.+)(past)(.+)(ten)(.*)
10:20 : (.*)(ten)(.+)(twenty)(.*)
10:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(ten)(.*)
10:25 : (.*)(ten)(.+)(twenty)(.*)(five)(.*)
10:30 : (.*)(thirty)(.+)(past)(.+)(ten)(.*)
10:30 : (.*)(ten)(.+)(thirty)(.*)
10:30 : (.*)(half)(.+)(past)(.+)(ten)(.*)
10:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(ten)(.*)
10:35 : (.*)(ten)(.+)(thirty)(.*)(five)(.*)
10:40 : (.*)(forty)(.+)(past)(.+)(ten)(.*)
10:40 : (.*)(ten)(.+)(forty)(.*)
10:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(ten)(.*)
10:45 : (.*)(ten)(.+)(forty)(.*)(five)(.*)
10:45 : (.*)(quarter)(.+)(to)(.+)(eleven)(.*)
10:50 : (.*)(fifty)(.+)(past)(.+)(ten)(.*)
10:50 : (.*)(ten)(.+)(fifty)(.*)
10:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(ten)(.*)
10:55 : (.*)(ten)(.+)(fifty)(.*)(five)(.*)
11:00 : (.*)(eleven)(.+)(o)(.+)(clock)(.*)
11:05 : (.*)(five)(.+)(past)(.+)(eleven)(.*)
11:05 : (.*)(eleven)(.+)(o)(.+)(five)(.*)
11:10 : (.*)(ten)(.+)(past)(.+)(eleven)(.*)
11:10 : (.*)(eleven)(.+)(ten)(.*)
11:15 : (.*)(fifteen)(.+)(past)(.+)(eleven)(.*)
11:15 : (.*)(eleven)(.+)(fifteen)(.*)
11:15 : (.*)(quarter)(.+)(past)(.+)(eleven)(.*)
11:20 : (.*)(twenty)(.+)(past)(.+)(eleven)(.*)
11:20 : (.*)(eleven)(.+)(twenty)(.*)
11:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(eleven)(.*)
11:25 : (.*)(eleven)(.+)(twenty)(.*)(five)(.*)
11:30 : (.*)(thirty)(.+)(past)(.+)(eleven)(.*)
11:30 : (.*)(eleven)(.+)(thirty)(.*)
11:30 : (.*)(half)(.+)(past)(.+)(eleven)(.*)
11:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(eleven)(.*)
11:35 : (.*)(eleven)(.+)(thirty)(.*)(five)(.*)
11:40 : (.*)(forty)(.+)(past)(.+)(eleven)(.*)
11:40 : (.*)(eleven)(.+)(forty)(.*)
11:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(eleven)(.*)
11:45 : (.*)(eleven)(.+)(forty)(.*)(five)(.*)
11:45 : (.*)(quarter)(.+)(to)(.+)(twelve)(.*)
11:50 : (.*)(fifty)(.+)(past)(.+)(eleven)(.*)
11:50 : (.*)(eleven)(.+)(fifty)(.*)
11:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(eleven)(.*)
11:55 : (.*)(eleven)(.+)(fifty)(.*)(five)(.*)
12:00 : (.*)(twelve)(.+)(o)(.+)(clock)(.*)
12:05 : (.*)(five)(.+)(past)(.+)(twelve)(.*)
12:05 : (.*)(twelve)(.+)(o)(.+)(five)(.*)
12:10 : (.*)(ten)(.+)(past)(.+)(twelve)(.*)
12:10 : (.*)(twelve)(.+)(ten)(.*)
12:15 : (.*)(fifteen)(.+)(past)(.+)(twelve)(.*)
12:15 : (.*)(twelve)(.+)(fifteen)(.*)
12:15 : (.*)(quarter)(.+)(past)(.+)(twelve)(.*)
12:20 : (.*)(twenty)(.+)(past)(.+)(twelve)(.*)
12:20 : (.*)(twelve)(.+)(twenty)(.*)
12:25 : (.*)(twenty)(.*)(five)(.+)(past)(.+)(twelve)(.*)
12:25 : (.*)(twelve)(.+)(twenty)(.*)(five)(.*)
12:30 : (.*)(thirty)(.+)(past)(.+)(twelve)(.*)
12:30 : (.*)(twelve)(.+)(thirty)(.*)
12:30 : (.*)(half)(.+)(past)(.+)(twelve)(.*)
12:35 : (.*)(thirty)(.*)(five)(.+)(past)(.+)(twelve)(.*)
12:35 : (.*)(twelve)(.+)(thirty)(.*)(five)(.*)
12:40 : (.*)(forty)(.+)(past)(.+)(twelve)(.*)
12:40 : (.*)(twelve)(.+)(forty)(.*)
12:45 : (.*)(forty)(.*)(five)(.+)(past)(.+)(twelve)(.*)
12:45 : (.*)(twelve)(.+)(forty)(.*)(five)(.*)
12:45 : (.*)(quarter)(.+)(to)(.+)(one)(.*)
12:50 : (.*)(fifty)(.+)(past)(.+)(twelve)(.*)
12:50 : (.*)(twelve)(.+)(fifty)(.*)
12:55 : (.*)(fifty)(.*)(five)(.+)(past)(.+)(twelve)(.*)
12:55 : (.*)(twelve)(.+)(fifty)(.*)(five)(.*)
 1:00 : (.*)(ein)(.+)(uhr)(.*)
 1:00 : (.*)(punkt)(.+)(eins)(.*)
 1:05 : (.*)(ein)(.+)(uhr)(.+)(fünf)(.*)
 1:05 : (.*)(fünf)(.+)(nach)(.+)(eins)(.*)
 1:10 : (.*)(ein)(.+)(uhr)(.+)(zehn)(.*)
 1:10 : (.*)(zehn)(.+)(nach)(.+)(eins)(.*)
 1:15 : (.*)(ein)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 1:15 : (.*)(viertel)(.+)(nach)(.+)(eins)(.*)
 1:20 : (.*)(ein)(.+)(uhr)(.+)(zwanzig)(.*)
 1:20 : (.*)(zwanzig)(.+)(nach)(.+)(eins)(.*)
 1:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(zwei)(.*)
 1:25 : (.*)(ein)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 1:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(zwei)(.*)
 1:30 : (.*)(ein)(.+)(uhr)(.+)(dreissig)(.*)
 1:30 : (.*)(halb)(.+)(zwei)(.*)
 1:35 : (.*)(ein)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 1:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(zwei)(.*)
 1:40 : (.*)(ein)(.+)(uhr)(.+)(vierzig)(.*)
 1:40 : (.*)(zwanzig)(.+)(vor)(.+)(zwei)(.*)
 1:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(zwei)(.*)
 1:45 : (.*)(ein)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 1:45 : (.*)(drei)(.*)(viertel)(.+)(zwei)(.*)
 1:50 : (.*)(ein)(.+)(uhr)(.+)(fünfzig)(.*)
 1:50 : (.*)(zehn)(.+)(vor)(.+)(zwei)(.*)
 1:55 : (.*)(ein)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 1:55 : (.*)(fünf)(.+)(vor)(.+)(zwei)(.*)
 2:00 : (.*)(zwei)(.+)(uhr)(.*)
 2:00 : (.*)(punkt)(.+)(zwei)(.*)
 2:05 : (.*)(zwei)(.+)(uhr)(.+)(fünf)(.*)
 2:05 : (.*)(fünf)(.+)(nach)(.+)(zwei)(.*)
 2:10 : (.*)(zwei)(.+)(uhr)(.+)(zehn)(.*)
 2:10 : (.*)(zehn)(.+)(nach)(.+)(zwei)(.*)
 2:15 : (.*)(zwei)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 2:15 : (.*)(viertel)(.+)(nach)(.+)(zwei)(.*)
 2:20 : (.*)(zwei)(.+)(uhr)(.+)(zwanzig)(.*)
 2:20 : (.*)(zwanzig)(.+)(nach)(.+)(zwei)(.*)
 2:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(drei)(.*)
 2:25 : (.*)(zwei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 2:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(drei)(.*)
 2:30 : (.*)(zwei)(.+)(uhr)(.+)(dreissig)(.*)
 2:30 : (.*)(halb)(.+)(drei)(.*)
 2:35 : (.*)(zwei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 2:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(drei)(.*)
 2:40 : (.*)(zwei)(.+)(uhr)(.+)(vierzig)(.*)
 2:40 : (.*)(zwanzig)(.+)(vor)(.+)(drei)(.*)
 2:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(drei)(.*)
 2:45 : (.*)(zwei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 2:45 : (.*)(drei)(.*)(viertel)(.+)(drei)(.*)
 2:50 : (.*)(zwei)(.+)(uhr)(.+)(fünfzig)(.*)
 2:50 : (.*)(zehn)(.+)(vor)(.+)(drei)(.*)
 2:55 : (.*)(zwei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 2:55 : (.*)(fünf)(.+)(vor)(.+)(drei)(.*)
 3:00 : (.*)(drei)(.+)(uhr)(.*)
 3:00 : (.*)(punkt)(.+)(drei)(.*)
 3:05 : (.*)(drei)(.+)(uhr)(.+)(fünf)(.*)
 3:05 : (.*)(fünf)(.+)(nach)(.+)(drei)(.*)
 3:10 : (.*)(drei)(.+)(uhr)(.+)(zehn)(.*)
 3:10 : (.*)(zehn)(.+)(nach)(.+)(drei)(.*)
 3:15 : (.*)(drei)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 3:15 : (.*)(viertel)(.+)(nach)(.+)(drei)(.*)
 3:20 : (.*)(drei)(.+)(uhr)(.+)(zwanzig)(.*)
 3:20 : (.*)(zwanzig)(.+)(nach)(.+)(drei)(.*)
 3:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(vier)(.*)
 3:25 : (.*)(drei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 3:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(vier)(.*)
 3:30 : (.*)(drei)(.+)(uhr)(.+)(dreissig)(.*)
 3:30 : (.*)(halb)(.+)(vier)(.*)
 3:35 : (.*)(drei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 3:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(vier)(.*)
 3:40 : (.*)(drei)(.+)(uhr)(.+)(vierzig)(.*)
 3:40 : (.*)(zwanzig)(.+)(vor)(.+)(vier)(.*)
 3:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(vier)(.*)
 3:45 : (.*)(drei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 3:45 : (.*)(drei)(.*)(viertel)(.+)(vier)(.*)
 3:50 : (.*)(drei)(.+)(uhr)(.+)(fünfzig)(.*)
 3:50 : (.*)(zehn)(.+)(vor)(.+)(vier)(.*)
 3:55 : (.*)(drei)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 3:55 : (.*)(fünf)(.+)(vor)(.+)(vier)(.*)
 4:00 : (.*)(vier)(.+)(uhr)(.*)
 4:00 : (.*)(punkt)(.+)(vier)(.*)
 4:05 : (.*)(vier)(.+)(uhr)(.+)(fünf)(.*)
 4:05 : (.*)(fünf)(.+)(nach)(.+)(vier)(.*)
 4:10 : (.*)(vier)(.+)(uhr)(.+)(zehn)(.*)
 4:10 : (.*)(zehn)(.+)(nach)(.+)(vier)(.*)
 4:15 : (.*)(vier)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 4:15 : (.*)(viertel)(.+)(nach)(.+)(vier)(.*)
 4:20 : (.*)(vier)(.+)(uhr)(.+)(zwanzig)(.*)
 4:20 : (.*)(zwanzig)(.+)(nach)(.+)(vier)(.*)
 4:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(fünf)(.*)
 4:25 : (.*)(vier)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 4:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(fünf)(.*)
 4:30 : (.*)(vier)(.+)(uhr)(.+)(dreissig)(.*)
 4:30 : (.*)(halb)(.+)(fünf)(.*)
 4:35 : (.*)(vier)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 4:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(fünf)(.*)
 4:40 : (.*)(vier)(.+)(uhr)(.+)(vierzig)(.*)
 4:40 : (.*)(zwanzig)(.+)(vor)(.+)(fünf)(.*)
 4:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(fünf)(.*)
 4:45 : (.*)(vier)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 4:45 : (.*)(drei)(.*)(viertel)(.+)(fünf)(.*)
 4:50 : (.*)(vier)(.+)(uhr)(.+)(fünfzig)(.*)
 4:50 : (.*)(zehn)(.+)(vor)(.+)(fünf)(.*)
 4:55 : (.*)(vier)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 4:55 : (.*)(fünf)(.+)(vor)(.+)(fünf)(.*)
 5:00 : (.*)(fünf)(.+)(uhr)(.*)
 5:00 : (.*)(punkt)(.+)(fünf)(.*)
 5:05 : (.*)(fünf)(.+)(uhr)(.+)(fünf)(.*)
 5:05 : (.*)(fünf)(.+)(nach)(.+)(fünf)(.*)
 5:10 : (.*)(fünf)(.+)(uhr)(.+)(zehn)(.*)
 5:10 : (.*)(zehn)(.+)(nach)(.+)(fünf)(.*)
 5:15 : (.*)(fünf)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 5:15 : (.*)(viertel)(.+)(nach)(.+)(fünf)(.*)
 5:20 : (.*)(fünf)(.+)(uhr)(.+)(zwanzig)(.*)
 5:20 : (.*)(zwanzig)(.+)(nach)(.+)(fünf)(.*)
 5:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(sechs)(.*)
 5:25 : (.*)(fünf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 5:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(sechs)(.*)
 5:30 : (.*)(fünf)(.+)(uhr)(.+)(dreissig)(.*)
 5:30 : (.*)(halb)(.+)(sechs)(.*)
 5:35 : (.*)(fünf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 5:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(sechs)(.*)
 5:40 : (.*)(fünf)(.+)(uhr)(.+)(vierzig)(.*)
 5:40 : (.*)(zwanzig)(.+)(vor)(.+)(sechs)(.*)
 5:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(sechs)(.*)
 5:45 : (.*)(fünf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 5:45 : (.*)(drei)(.*)(viertel)(.+)(sechs)(.*)
 5:50 : (.*)(fünf)(.+)(uhr)(.+)(fünfzig)(.*)
 5:50 : (.*)(zehn)(.+)(vor)(.+)(sechs)(.*)
 5:55 : (.*)(fünf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 5:55 : (.*)(fünf)(.+)(vor)(.+)(sechs)(.*)
 6:00 : (.*)(sechs)(.+)(uhr)(.*)
 6:00 : (.*)(punkt)(.+)(sechs)(.*)
 6:05 : (.*)(sechs)(.+)(uhr)(.+)(fünf)(.*)
 6:05 : (.*)(fünf)(.+)(nach)(.+)(sechs)(.*)
 6:10 : (.*)(sechs)(.+)(uhr)(.+)(zehn)(.*)
 6:10 : (.*)(zehn)(.+)(nach)(.+)(sechs)(.*)
 6:15 : (.*)(sechs)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 6:15 : (.*)(viertel)(.+)(nach)(.+)(sechs)(.*)
 6:20 : (.*)(sechs)(.+)(uhr)(.+)(zwanzig)(.*)
 6:20 : (.*)(zwanzig)(.+)(nach)(.+)(sechs)(.*)
 6:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(sieben)(.*)
 6:25 : (.*)(sechs)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 6:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(sieben)(.*)
 6:30 : (.*)(sechs)(.+)(uhr)(.+)(dreissig)(.*)
 6:30 : (.*)(halb)(.+)(sieben)(.*)
 6:35 : (.*)(sechs)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 6:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(sieben)(.*)
 6:40 : (.*)(sechs)(.+)(uhr)(.+)(vierzig)(.*)
 6:40 : (.*)(zwanzig)(.+)(vor)(.+)(sieben)(.*)
 6:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(sieben)(.*)
 6:45 : (.*)(sechs)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 6:45 : (.*)(drei)(.*)(viertel)(.+)(sieben)(.*)
 6:50 : (.*)(sechs)(.+)(uhr)(.+)(fünfzig)(.*)
 6:50 : (.*)(zehn)(.+)(vor)(.+)(sieben)(.*)
 6:55 : (.*)(sechs)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 6:55 : (.*)(fünf)(.+)(vor)(.+)(sieben)(.*)
 7:00 : (.*)(sieben)(.+)(uhr)(.*)
 7:00 : (.*)(punkt)(.+)(sieben)(.*)
 7:05 : (.*)(sieben)(.+)(uhr)(.+)(fünf)(.*)
 7:05 : (.*)(fünf)(.+)(nach)(.+)(sieben)(.*)
 7:10 : (.*)(sieben)(.+)(uhr)(.+)(zehn)(.*)
 7:10 : (.*)(zehn)(.+)(nach)(.+)(sieben)(.*)
 7:15 : (.*)(sieben)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 7:15 : (.*)(viertel)(.+)(nach)(.+)(sieben)(.*)
 7:20 : (.*)(sieben)(.+)(uhr)(.+)(zwanzig)(.*)
 7:20 : (.*)(zwanzig)(.+)(nach)(.+)(sieben)(.*)
 7:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(acht)(.*)
 7:25 : (.*)(sieben)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 7:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(acht)(.*)
 7:30 : (.*)(sieben)(.+)(uhr)(.+)(dreissig)(.*)
 7:30 : (.*)(halb)(.+)(acht)(.*)
 7:35 : (.*)(sieben)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 7:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(acht)(.*)
 7:40 : (.*)(sieben)(.+)(uhr)(.+)(vierzig)(.*)
 7:40 : (.*)(zwanzig)(.+)(vor)(.+)(acht)(.*)
 7:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(acht)(.*)
 7:45 : (.*)(sieben)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 7:45 : (.*)(drei)(.*)(viertel)(.+)(acht)(.*)
 7:50 : (.*)(sieben)(.+)(uhr)(.+)(fünfzig)(.*)
 7:50 : (.*)(zehn)(.+)(vor)(.+)(acht)(.*)
 7:55 : (.*)(sieben)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 7:55 : (.*)(fünf)(.+)(vor)(.+)(acht)(.*)
 8:00 : (.*)(acht)(.+)(uhr)(.*)
 8:00 : (.*)(punkt)(.+)(acht)(.*)
 8:05 : (.*)(acht)(.+)(uhr)(.+)(fünf)(.*)
 8:05 : (.*)(fünf)(.+)(nach)(.+)(acht)(.*)
 8:10 : (.*)(acht)(.+)(uhr)(.+)(zehn)(.*)
 8:10 : (.*)(zehn)(.+)(nach)(.+)(acht)(.*)
 8:15 : (.*)(acht)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 8:15 : (.*)(viertel)(.+)(nach)(.+)(acht)(.*)
 8:20 : (.*)(acht)(.+)(uhr)(.+)(zwanzig)(.*)
 8:20 : (.*)(zwanzig)(.+)(nach)(.+)(acht)(.*)
 8:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(neun)(.*)
 8:25 : (.*)(acht)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 8:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(neun)(.*)
 8:30 : (.*)(acht)(.+)(uhr)(.+)(dreissig)(.*)
 8:30 : (.*)(halb)(.+)(neun)(.*)
 8:35 : (.*)(acht)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 8:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(neun)(.*)
 8:40 : (.*)(acht)(.+)(uhr)(.+)(vierzig)(.*)
 8:40 : (.*)(zwanzig)(.+)(vor)(.+)(neun)(.*)
 8:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(neun)(.*)
 8:45 : (.*)(acht)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 8:45 : (.*)(drei)(.*)(viertel)(.+)(neun)(.*)
 8:50 : (.*)(acht)(.+)(uhr)(.+)(fünfzig)(.*)
 8:50 : (.*)(zehn)(.+)(vor)(.+)(neun)(.*)
 8:55 : (.*)(acht)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 8:55 : (.*)(fünf)(.+)(vor)(.+)(neun)(.*)
 9:00 : (.*)(neun)(.+)(uhr)(.*)
 9:00 : (.*)(punkt)(.+)(neun)(.*)
 9:05 : (.*)(neun)(.+)(uhr)(.+)(fünf)(.*)
 9:05 : (.*)(fünf)(.+)(nach)(.+)(neun)(.*)
 9:10 : (.*)(neun)(.+)(uhr)(.+)(zehn)(.*)
 9:10 : (.*)(zehn)(.+)(nach)(.+)(neun)(.*)
 9:15 : (.*)(neun)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
 9:15 : (.*)(viertel)(.+)(nach)(.+)(neun)(.*)
 9:20 : (.*)(neun)(.+)(uhr)(.+)(zwanzig)(.*)
 9:20 : (.*)(zwanzig)(.+)(nach)(.+)(neun)(.*)
 9:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(zehn)(.*)
 9:25 : (.*)(neun)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
 9:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(zehn)(.*)
 9:30 : (.*)(neun)(.+)(uhr)(.+)(dreissig)(.*)
 9:30 : (.*)(halb)(.+)(zehn)(.*)
 9:35 : (.*)(neun)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
 9:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(zehn)(.*)
 9:40 : (.*)(neun)(.+)(uhr)(.+)(vierzig)(.*)
 9:40 : (.*)(zwanzig)(.+)(vor)(.+)(zehn)(.*)
 9:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(zehn)(.*)
 9:45 : (.*)(neun)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
 9:45 : (.*)(drei)(.*)(viertel)(.+)(zehn)(.*)
 9:50 : (.*)(neun)(.+)(uhr)(.+)(fünfzig)(.*)
 9:50 : (.*)(zehn)(.+)(vor)(.+)(zehn)(.*)
 9:55 : (.*)(neun)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
 9:55 : (.*)(fünf)(.+)(vor)(.+)(zehn)(.*)
10:00 : (.*)(zehn)(.+)(uhr)(.*)
10:00 : (.*)(punkt)(.+)(zehn)(.*)
10:05 : (.*)(zehn)(.+)(uhr)(.+)(fünf)(.*)
10:05 : (.*)(fünf)(.+)(nach)(.+)(zehn)(.*)
10:10 : (.*)(zehn)(.+)(uhr)(.+)(zehn)(.*)
10:10 : (.*)(zehn)(.+)(nach)(.+)(zehn)(.*)
10:15 : (.*)(zehn)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
10:15 : (.*)(viertel)(.+)(nach)(.+)(zehn)(.*)
10:20 : (.*)(zehn)(.+)(uhr)(.+)(zwanzig)(.*)
10:20 : (.*)(zwanzig)(.+)(nach)(.+)(zehn)(.*)
10:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(elf)(.*)
10:25 : (.*)(zehn)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
10:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(elf)(.*)
10:30 : (.*)(zehn)(.+)(uhr)(.+)(dreissig)(.*)
10:30 : (.*)(halb)(.+)(elf)(.*)
10:35 : (.*)(zehn)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
10:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(elf)(.*)
10:40 : (.*)(zehn)(.+)(uhr)(.+)(vierzig)(.*)
10:40 : (.*)(zwanzig)(.+)(vor)(.+)(elf)(.*)
10:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(elf)(.*)
10:45 : (.*)(zehn)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
10:45 : (.*)(drei)(.*)(viertel)(.+)(elf)(.*)
10:50 : (.*)(zehn)(.+)(uhr)(.+)(fünfzig)(.*)
10:50 : (.*)(zehn)(.+)(vor)(.+)(elf)(.*)
10:55 : (.*)(zehn)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
10:55 : (.*)(fünf)(.+)(vor)(.+)(elf)(.*)
11:00 : (.*)(elf)(.+)(uhr)(.*)
11:00 : (.*)(punkt)(.+)(elf)(.*)
11:05 : (.*)(elf)(.+)(uhr)(.+)(fünf)(.*)
11:05 : (.*)(fünf)(.+)(nach)(.+)(elf)(.*)
11:10 : (.*)(elf)(.+)(uhr)(.+)(zehn)(.*)
11:10 : (.*)(zehn)(.+)(nach)(.+)(elf)(.*)
11:15 : (.*)(elf)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
11:15 : (.*)(viertel)(.+)(nach)(.+)(elf)(.*)
11:20 : (.*)(elf)(.+)(uhr)(.+)(zwanzig)(.*)
11:20 : (.*)(zwanzig)(.+)(nach)(.+)(elf)(.*)
11:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(zwölf)(.*)
11:25 : (.*)(elf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
11:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(zwölf)(.*)
11:30 : (.*)(elf)(.+)(uhr)(.+)(dreissig)(.*)
11:30 : (.*)(halb)(.+)(zwölf)(.*)
11:35 : (.*)(elf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
11:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(zwölf)(.*)
11:40 : (.*)(elf)(.+)(uhr)(.+)(vierzig)(.*)
11:40 : (.*)(zwanzig)(.+)(vor)(.+)(zwölf)(.*)
11:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(zwölf)(.*)
11:45 : (.*)(elf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
11:45 : (.*)(drei)(.*)(viertel)(.+)(zwölf)(.*)
11:50 : (.*)(elf)(.+)(uhr)(.+)(fünfzig)(.*)
11:50 : (.*)(zehn)(.+)(vor)(.+)(zwölf)(.*)
11:55 : (.*)(elf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
11:55 : (.*)(fünf)(.+)(vor)(.+)(zwölf)(.*)
12:00 : (.*)(zwölf)(.+)(uhr)(.*)
12:00 : (.*)(punkt)(.+)(zwölf)(.*)
12:05 : (.*)(zwölf)(.+)(uhr)(.+)(fünf)(.*)
12:05 : (.*)(fünf)(.+)(nach)(.+)(zwölf)(.*)
12:10 : (.*)(zwölf)(.+)(uhr)(.+)(zehn)(.*)
12:10 : (.*)(zehn)(.+)(nach)(.+)(zwölf)(.*)
12:15 : (.*)(zwölf)(.+)(uhr)(.+)(fünf)(.*)(zehn)(.*)
12:15 : (.*)(viertel)(.+)(nach)(.+)(zwölf)(.*)
12:20 : (.*)(zwölf)(.+)(uhr)(.+)(zwanzig)(.*)
12:20 : (.*)(zwanzig)(.+)(nach)(.+)(zwölf)(.*)
12:20 : (.*)(zehn)(.+)(vor)(.+)(halb)(.+)(eins)(.*)
12:25 : (.*)(zwölf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(zwanzig)(.*)
12:25 : (.*)(fünf)(.+)(vor)(.+)(halb)(.+)(eins)(.*)
12:30 : (.*)(zwölf)(.+)(uhr)(.+)(dreissig)(.*)
12:30 : (.*)(halb)(.+)(eins)(.*)
12:35 : (.*)(zwölf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(dreissig)(.*)
12:35 : (.*)(fünf)(.+)(nach)(.+)(halb)(.+)(eins)(.*)
12:40 : (.*)(zwölf)(.+)(uhr)(.+)(vierzig)(.*)
12:40 : (.*)(zwanzig)(.+)(vor)(.+)(eins)(.*)
12:40 : (.*)(zehn)(.+)(nach)(.+)(halb)(.+)(eins)(.*)
12:45 : (.*)(zwölf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(vierzig)(.*)
12:45 : (.*)(drei)(.*)(viertel)(.+)(eins)(.*)
12:50 : (.*)(zwölf)(.+)(uhr)(.+)(fünfzig)(.*)
12:50 : (.*)(zehn)(.+)(vor)(.+)(eins)(.*)
12:55 : (.*)(zwölf)(.+)(uhr)(.+)(fünf)(.*)(und)(.*)(fünfzig)(.*)
12:55 : (.*)(fünf)(.+)(vor)(.+)(eins)(.*)

Downloads

Thats the Java source code for the genetic algorithm - but be warned, it's just a hack and is by no means a usable program.

It's a multi-threaded console application that saves the state every couple of generations in an XML file - so it can be started and stopped without loosing data.

GenAlg.java is the main file, within its run() you can switch the language between English and German. The file Candidate.java contains the initial pattern for the word clock, just change it and the GA will try to find a solution for that clock.

The program will output a line on the console every couple of generations. It contains information about the current best solution, most importantly the number of times that the clock can display and the nuber it can't (labeled "ok" and "nok").

You can download the source code for the GA from github.

19 Kommentare:

  1. Very cool, but I found, that the diamond shape variant uses a new word for me "FOURTHY".

    AntwortenLöschen
  2. In English 40 is spelled out "forty". I see you used "fourty" and "fourthy". Changing this might give you a smaller array.

    AntwortenLöschen
  3. ok, spelling words correctly doesn't seem to be my strength...
    I'll fix that in the next days

    AntwortenLöschen
  4. Will, the program eventually finish, or will it just keep trying to get a better result?

    AntwortenLöschen
    Antworten
    1. no, it will keep running.
      Of course you could stop as soon as you find a good enough solution but I never bothered implementing that function...

      Löschen
  5. Another word clock:
    http://chriative.com/blog/projects/word-clock/

    AntwortenLöschen
  6. I don't know if it would make the English one more likely or less likely to fit in a smaller space, but 40 = forty rather than fourty or fourthy

    http://en.wikipedia.org/wiki/40_(number)

    AntwortenLöschen
  7. In English, for a time like 3:05, we usually say "three oh five" and not "three five". Can you modify your regex to reflect this?

    AntwortenLöschen
  8. Lovely Work!
    Just found this link through Hack-A-Day, and now Damned temped to build a circular German word clock!
    -GCS

    AntwortenLöschen
    Antworten
    1. would love to see that,
      I added a German version of the circular clock so you can play around with it.

      Löschen
  9. i'd gladly build that clock but in my opinion it requires more wpierdol.

    AntwortenLöschen
  10. Got the code to run, ran it in English until it had 0 "nok".

    best: 2380000: 190000: splits: 44, check ok: 191, nok: 121, times ok: 144, nok 0, twononefour|thirtyseven|sixtothreeo|fiftyeforty|wfifteenten|twentyfivee|thirtyhpast|oninetwelve|fiveeighten|selevenfour|tclocktwone

    How is that supposed to represent "thirty past three", or six, or seven? After "past" there are only 9, 12, 5, 8, 10, 11, 4, 2, and 1. How is it reporting "times nok: 0" when three times are missing?

    AntwortenLöschen
    Antworten
    1. Notice there are two ok/nok pairs, check and times. The times nok means that all possible times can be represented(3:30 as three thirty). The check ok/nok is for all possible word combinations, of which you have 191/312.

      Took me a while to work that out too.

      Löschen
  11. What about vertical? In theory, you should be able to make it smaller, if you allow both vertical and horizontal words.

    AntwortenLöschen
    Antworten
    1. True, it should be possible.
      The problem is that it is quite likely to get unreadable variants and I didn't find an easy way to describe how readable a clock is.

      Example for 12:20

      bad example:

      t.....
      w.....
      e.....
      n.....
      twelve
      y.....

      good example

      .......t
      .......w
      twelve
      .......n
      .......t
      .......y

      Löschen
  12. very nice idea. And I love genetic algorithms =)

    Notice though, that this is actually a solved problem and you don't need such an search algorithm.

    Choose all the formulations you want (eg. "quarter past two"), construct a graph of "must appear before"-connections (eg. "quarter" must appear before "past" before "two", also "past" before "three" etc.) and use this graph of dependencies for a topological sorting. http://en.wikipedia.org/wiki/Topological_sort

    AntwortenLöschen
    Antworten
    1. I have to look into it, but I'm not sure if this is possible.
      Take the following German example:
      08:10 = ZEHN NACH ACHT
      08:10 = ACHT UHR ZEHN
      (zehn = ten, nach = after, acht = eight, uhr = in this context something like o'clock)

      so you get a circular graph like:
      ZEHN -> NACH -> ACHT -> UHR -> ZEHN -> ...

      this could be solved somehow (I think...)
      The "cool" thing about the GA is that it found a solution that I really didn't expect:
      see the words NACH and ACHT? It found a solution containing NACHT which can be NACHt and nACHT. I didn't think of that, with a graph I would have to encode that in the graph somehow...

      anyway, I'll look into it...

      Löschen
  13. Anybody tried to build it rectangular instead of square?
    Maybe the vertical build is readable if you put more words in a line than just one?

    AntwortenLöschen
  14. I noticed a slight bug sometime it make a solution where for example it use an "o" that is part of two, if you're light boxing the individual words you can't share two and o

    AntwortenLöschen