One of the things I learned by reading AIM 239 is the Game of Life and Cellular Automata. One particular kind of one dimensional cellular automata, Rule 110 popped by my twitter stream the other day, so I thought I could try and code it with the minimal Haskell subset that I can handle.

Rule 110 is special because it is proven to be able to simulate a Turing machine. Head over to its Wikipedia page if you want to learn more about the proof and the interesting story around it.

Rule 110 starts with a string of zeros and ones and a transition table that decides the next state of the automaton. If you put each line of the strings after the other, interesting patterns can emerge. Let’s see the transition state:

Current pattern | 111 | 110 | 101 | 100 | 011 | 010 | 001 | 000 |
---|---|---|---|---|---|---|---|---|

New state for center cell | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |

If you look closely, you can use a list of eight digits and its index in order to encode the above state transitions:

rule110 = [ 0, -- ((0,0,0), 0) 1, -- ((0,0,1), 1) 1, -- ((0,1,0), 1) 1, -- ((0,1,1), 1) 0, -- ((1,0,0), 0) 1, -- ((1,0,1), 1) 1, -- ((1,1,0), 1) 0 -- ((1,1,1), 0) ] :: [Int]

But what about the transitions of the leftmost and rightmost digit you might think. Let’s assume that their missing neighbor is zero. Therefore, given an initial state and a rule that governs the transitions, we may calculate the next state with:

nextState :: [Int] -> [Int] -> [Int] nextState state rule = [ rule !! x | let t = [0] ++ state ++ [0], i <- [1..(length(t)-2)], let x = (t !! (i-1)) * 4 + (t !! i) * 2 + (t !! (i+1)) ] -- construct an infinite sequence of next states sequenceState :: [Int] -> [Int] -> [[Int]] sequenceState state rule = [state] ++ sequenceState (nextState state rule) rule

Example:

*Main> state = [0,1,1,0] *Main> nextState state rule110 [1,1,1,0]

One of the most interesting patterns occurs when we begin with the right most digit being 1 and all the rest being zeros:

*Main> state = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1] :: [Int] *Main> x = take 30 $ sequenceState state rule110 *Main> showState x * ** *** ** * ***** ** * *** ** ** * *** ******* * ** *** *** ** * ** * ***** ***** ** * ** * *** ** *** **** * *** ** * ** ***** * ******** ** *** ** **** ** * *** ** * ***** ** * *** **** * ***** ** *** * ** ** * ***** * ** *** *** ** ** ******** * ** * ****** ** *** ******* * *** ** * ** * **** * ***** *** ** ** *** ** * ** * *** *** ** * *** ** ***** ** *** ****** ** * *** ** * ***** *** ******** * *Main>

The output was somehow pretty printed:

showState [] = return () showState state = do -- putStrLn $ show (state !! 0) putStrLn $ [ c | d <- (state !! 0), let c = if d == 0 then ' ' else '*' ] showState $ tail state

I wish I can find time and play more with cellular automata. I kind of find a day every five years or so.

**Update:** Here is a pattern using Rule 90:

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *]]>

I am coninuing my adventure in Haskell. In order to make it a bit more fun, I decided to code a simple yet very intriguing problem, I first heard of when I read AI Memo 239: The Collatz conjecture.

Construct a sequence of integers where given an arbitrary interger the value of the next is:

* If the number is even, divide it by two.

* If the number is odd, triple it and add one.

This can easily be coded in Haskell as follows:

collatz :: Int -> Int collatz 1 = 1 collatz n = if (even n) then (n `div` 2) else (3 * n + 1)

But how can one obtain a sequence of numbers from this? A very clever solution is here where the author implements a variation of takeWhile which includes also the first list item that fails the test the first time. So my question became, can it be done in another way? Yes it can:

collatzSequence :: Int -> [Int] collatzSequence n = if n == 1 then [1] else [n] ++ collatzSequence (collatz n)

Let's see some test runs:

*Main> collatzSequence 5 [5,16,8,4,2,1] *Main> collatzSequence 50 [50,25,76,38,19,58,29,88,44,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1] *Main> collatzSequence 500 [500,250,125,376,188,94,47,142,71,214,107,322,161,484,242,121,364,182,91,274,137,412,206,103,310,155,466,233,700,350,175,526,263,790,395,1186,593,1780,890,445,1336,668,334,167,502,251,754,377,1132,566,283,850,425,1276,638,319,958,479,1438,719,2158,1079,3238,1619,4858,2429,7288,3644,1822,911,2734,1367,4102,2051,6154,3077,9232,4616,2308,1154,577,1732,866,433,1300,650,325,976,488,244,122,61,184,92,46,23,70,35,106,53,160,80,40,20,10,5,16,8,4,2,1] *Main> collatzSequence 512 [512,256,128,64,32,16,8,4,2,1] *Main> collatzSequence 513 [513,1540,770,385,1156,578,289,868,434,217,652,326,163,490,245,736,368,184,92,46,23,70,35,106,53,160,80,40,20,10,5,16,8,4,2,1] *Main>

You may have observed we only run it on positive integers. When we run it with negative integers, there are a few more cycles that we need to take into account. Here is the updated sequence function, written with guards:

collatzSequence :: Int -> [Int] collatzSequence n | n == 1 = [1] | n == (-2) = [(-2)] | n == (-5) = [(-5)] | n == (-17) = [(-17)] | otherwise = [n] ++ collatzSequence (collatz n)

Test:

*Main> collatzSequence (-50) [-50,-25,-74,-37,-110,-55,-164,-82,-41,-122,-61,-182,-91,-272,-136,-68,-34,-17]

Now if there was also a way to prove the conjecture…

Please note that in Haskell the unary minus is a function and not an operator, hence, you need to parenthesize. This also works:

*Main> collatzSequence $ -50 [-50,-25,-74,-37,-110,-55,-164,-82,-41,-122,-61,-182,-91,-272,-136,-68,-34,-17]

**Update:** A friend posted me his own elegant version of the Collatz sequence:

collatz :: Int -> [Int] collatz 1 = [1] collatz n | even n = n : collatz (n `div` 2) | odd n = n : collatz (n * 3 + 1) main = do putStrLn $ show $ collatz 1 putStrLn $ show $ collatz 6 putStrLn $ show $ collatz 23]]>

The year is 1998 and @mtheofy then at Glasgow tells me about a relatively new (then) language called Haskell. I’m intrigued but do not do much. A few years later I buy The Haskell School of Expression since The Craft of Functional Programming did not seem enough to motivate me. Time passes and around 2007 I try yet another start. Nothing. I promised my self yet another restart for a 2017 new year’s resolution. Still nothing. So when the current employer offered Haskell classes I could not say no. Armed with the weekly classes and a Safari Learning Path I am trying to correct this. And I am having some fun with list comprehensions. Because as a friend says, if it makes you feel good, go.

So how do you write an infinite list? Let’s say you want list x to include all numbers from 0 to infinity. *stack ghci* is my friend. Others might try repl.it:

x = [ n | n <- [0..]]

Now you can have the first 20 items of x:

Prelude> x = [ n | n <- [0..]] Prelude> take 20 x [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] Prelude>

So next I wanted to make an infinite list of the same character. Enter the underscore variable:

Prelude> x = [ 'a' | _ <- [0..]] Prelude> take 20 x "aaaaaaaaaaaaaaaaaaaa" Prelude>

OK, so now let’s try to cycle infinitely characters from a string. I end up with:

Prelude> x = [ c | i take 20 x "abcdabcdabcdabcdabcd" Prelude>

I am kind of unsure why the let statements are needed since I am ~10 days into typing stuff and posted my creation to twitter. What my expression says is that x is comprised of characters from string “abcd”, where given a sequence of numbers, each time a character is chosen based on the sequence number modulo 4. Strings are lists of characters in Haskell and list indexing starts from zero. Helpful comments come my way. Like the obvious cycle (there is a *cycle* function? Yes ):

Prelude> take 20 (cycle "abcd") "abcdabcdabcdabcdabcd" Prelude> take 20 $ cycle "abcd" "abcdabcdabcdabcdabcd" Prelude>

Is not the dollar operator nice to get rid of parentheses? Here is another suggestion about cycling a string:

Prelude> x = [ "abcd" !! (i `mod` 4) | i take 20 x "abcdabcdabcdabcdabcd" Prelude>

This one is more concise and does the same thing, always picking a character from "abcd". If the infix notation for *mod* confuses you, you can:

Prelude> x = [ "abcd" !! (mod i 4) | i take 20 x "abcdabcdabcdabcdabcd" Prelude>

But the Internet does not stop there. It comes back with more helpful suggestions:

Welcome! A little feedback then if I may: the

`!!`

operator should be used VERY cautiously it is not typesafe and lists are not random access anyway. Opt for a function returning`Maybe x`

and for a random access datastructure (strings are by default lists).

Which made me think: How about an infinite string randomly chosen from “abcd”?

$ stack install random $ stack ghci : Prelude> import System.Random Prelude System.Random> g <- newStdGen Prelude System.Random> x = [ "abcd" !! i | i <- randomRs (0,3) g ] Prelude System.Random> take 10 x "bcbbddcdab" Prelude System.Random>

If you want a sequence with a different order, you need to reinitialise both g and x. I will figure out a better way some other time when …I have time.

Adventures with Maybe maybe in another post.

*Formatting this post in WordPress.com was a great pain.*

“The stock was down 86 cents over the day. That means Bill lost $70 million today, whereas I only lost fuck all. But guess who’ll sleep better?”

]]>This is not something new. In Beggars in Spain (the first book) there are also genetically engineered people who do not sleep with this being a competitive advantage and causing friction among sleepers and non-sleepers.

And then I remember Marissa Mayer talking about being *“strategic about when you sleep, when you shower, and how often you go to the bathroom”*.

I think Age of Em deals with this in a better way having Ems slow down their CPUs (making it a matter of energy cost, but I have not finished that book, so I am not sure how this idea gets developed).

Which is why I want to leave you with the 6-2-1 rule that popped into my twitter stream: *6 hours of sleep, 2 meals per day, 1 shower*. Analytics from my Nokia Go say that I am not really following this.

Happy New Year.

]]>So for this year I will promise myself something simpler, as a continuation of things I still do in 2017: simply improve my Go-fu. And yes, I also tried to learn Go and miserably failed. Let’s see about that too.

]]>Matt Parker took it upon himself to debunk junk science related to precise geometry choices by Ancient People. The particular junk piece that triggered his analysis was the assertion of a prehistoric navigation system. However, you may not be familiar with it, but you may have heard terms like “holy geometry” and the like to prove that some Ancient tribe either held some technology now long gone or was in contact with some alien race. But do they really stand?

So Matt, took it upon himself to analyse the locations of the Woolworths in order to figure out whether they had some “outer” help in choosing their store locations:

The results revealed an exact and precise geometric placement of the Woolworths locations. Three stores around Birmingham formed an exact equilateral triangle (Wolverhampton, Lichfield and Birmingham stores) and if the base of the triangle is extended, it forms a 173.8 mile line linking the Conwy and Luton stores. Despite the 173.8 mile distance involved, the Conway Woolworths store is only 40 feet off the exact line and the Luton site is within 30 feet. All four stores align with an accuracy of 0.05%

So there, proof! Aliens helped them :) Plus, sometimes you need to remind people that 3 points always make a triangle, no coincidence there.

You can read the whole analysis here thanks to the Internet Archive. Given enough data, if you’re looking for a pattern, you’re going to find it I guess.

]]>As long as P versus NP remains a mystery we do not know what we cannot do, and that’s liberating.

I follow Lance Fortnow’s blog from time to time. So when the book was out, I fired up the kindle and bought it. And then it stayed there for some time. Most likely because two out of seven days of the week I am not sure I can explain P vs NP. The rest I might be able, but the difficulty of the problem makes one double think about it, even when it is a book that makes it accessible to the general public. After all, it is The Problem.

And then came a plane trip. And with nowhere to go for the next 2,5 hours I started reading it. Fast. The history of the problem is there. Examples that are very easily understood are there. The hop from the example to the equivalent real problem is there, so you get to understand vertex cover before ever knowing the name. Plus you get to learn a bit about complexity during the Cold War and about quantum computing too.

We know for example that if P=NP, then cryptography as we know it will be defeated. But how will other aspects of our World change? Fortnow offers a glimpse. Is it worth it? Maybe. You will be the judge. Is it likely that P=NP? The author does not believe so (I do not want it to be, and want versus believe denotes the vast skill difference between him and me).

Chapter 2 was a bit boring for me and I almost gave up on the book. Fortunately I did not. If you are a computational complexity theorist then the book is not for you, but if you are not and you want to ask clear questions to one, then it will definitely help.

]]>“I think we’ve had a reduction from, say, if you think about 1995, which was when I went to college, you could typically rely on an undergraduate having done a substantial amount of real programming, often quite a deep level of technical work on one or more platforms. Many of us could program in one or more assembly languages. And yeah, within 10 years of that point, we were getting to a point where your average applicant was maybe somebody who’d done, as you say, a little bit of Web design, maybe a little bit of Web programming—you know, we saw quite a bit of people who‘d maybe done some PHP but not that kind of deep technical understanding of how machines work.”

This was from an Eben Upton interview. So much progress has happened that people entering the profession do so with a distance from the hardware.

]]>