Labels

3G (1) 8600GT (1) AI (4) amazon (1) API (1) apple (3) apple mail (1) atlassian (1) audio (1) bambo (1) Bamboo (1) bloat (1) boost (1) bugbear (1) C++ (5) calling conventions (1) cdecl (1) chromecast (1) CI (1) compiler (1) continuous integration (1) coursera (1) custom domain (1) debugging (1) deltanine (1) diagnosis (1) diy (5) DLL (1) dns (1) don't be evil (1) ec2 (1) education (1) electronics (1) express checkout (1) fail (6) fink (1) firewire (1) free hosting (1) GAE (1) google (1) Google App Engine (4) H170 (1) hackerx (1) hackintosh (1) Haskell (3) homebrew (2) i1394 (1) icloud (2) iOS 9 (1) ipad2 (2) jobhunting (2) lag (1) letsencrypt (2) libjpeg (1) linux (1) mac (2) mbcs (1) mechanic (1) memory (1) MFC (3) Microsoft (1) migration (1) ML (1) mobile (1) movi (1) MSBuild (1) music (1) naked domain (1) NLP (2) o2 sensor (1) obd (1) Optiplex960 (1) osx (1) outlook express (1) payments (1) paypal (1) photos (2) PIL (1) Project Euler (1) projectmix (1) python (2) raspberrypi (3) recruitment (1) renwal (1) skylake (1) soundcloud (1) ssl (2) stdcall (1) stripe (1) subaru (2) supermemo (1) supermemo anki java (1) sync (2) Telstra (1) tests (1) thunderbird (1) udacity (1) unicode (1) Uniform Cost Search (1) university (1) upgrade (2) vodafail (1) vodafone (1) VS2010 (1) vs2013 (1) VS6.0 (1) weather (1) win (1) Win32 (1) Z170 (1)

Thursday, 1 September 2011

Project Euler Problem 2

Due to my upcoming redundancy, I thought it is about time I learned  some new skills, so naturally I have chosen to learn a language with virtually zero commercial application - Haskell.

If you don't know what Haskell is, it's a functional programming language, which means that is it it deals with what to do, rather than how to do it, as most people are used to with typical procedural languages such as C.

Anyway, a good way to learn a new language is to try it out on some classic problems, such as those on the Project Euler page.

Problem 2 states:


The fibonacci sequence starts with 0, 1.. then subsequent entries are constructed by summing the previous two entries. This conveniently recursive definition can be specified in Haskell recursively, ie:

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib(n-1) + fib(n-2)

So the first step in solving this problem is to generate a list of fibonacci numbers... which is very easy to do using Haskell's list comprehension feature:

[ fib x | x <- [0..] ]
This basically says construct a list by calling the function fib x, where x is bound to the range of numbers from 0 to infinity. Infinite lists are a quirky feature of Haskell made possible by its use of lazy evaluation,  which means Haskell will defer actually calculating a result until it absolutely has to. The above expression will keep printing the list until the cows come home, but you will notice that after around 30 elements it gets slower and slower...


This is because it is fiendishly inefficient, having to recalculate each entry in the list from scratch, rather than re-using the previous two entries calculation. Clearly, this approach will not satisfy the Project Euler criteria that the solution should take less than a minute to run.

A new approach to calculate the fibonacci sequence using the results of the previous calculation is shown below:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs )
Note that it is recursively defined also. By way of explanation, zipWith is a function which takes two lists and applies a function to the elements in the same corresponding positions in the list and tail is a function which returns a list minus the first element.

So in this case the effect of zipWith is to add the nth element of fibs with the n-1th element of fibs. This function will generate an infinite fibonacci sequence.

We can use a list comprehension to filter out the odd valued terms using the predicate x `mod` 2 == 0.
mod is actually a prefix function (ie: called before its arguments, eg: mod x 2 ), but using `backticks` allows us to call it using infix notation, which is more natural for mathematical functions.
[ x | x <- fibs, x `mod` 2 == 0 ]
Note that the predicate x <= 4000000 will also filter out all values less than 4000000, but the list comprehension will never terminate.

Instead, we can use the takeWhile function which takes values from a list whilst as a boolean criterion is satisfied, eg:

takeWhile ( <= 4000000 ) [ x | x <- fibs, x `mod` 2 == 0 ]
[0,2,8,34,144,610,2584,10946,46368,196418,832040,3524578]
Now all that is left if to sum the list to get our answer

sum (takeWhile ( <= 4000000 ) [ x | x <- fibs, x `mod` 2 == 0 ])


4613732
Which makes me the 139646th person to solve that problem on the Project Euler page. Only 342 left to solve!

Thursday, 4 August 2011

SuperMemo to Anki database converter...

My girlfriend recently decided to move her study materials from SuperMemo to Anki, due to Anki's better support for Mac and a superior iPhone app that allows study cards to contain media such as images and sound.

However, she faced the prospect of losing all her learning history on thousands of cards, which would have meant unnecessary repetitions as Anki rebuilt her learning database.

Thankfully I found this useful project on GitHub:

https://github.com/ggodlewski/smux-anki-converter

It's a java program that converts the SuperMemo UX course data into Anki format. It seems to have been written to work on courses published from the SuperMemo website - but when I tried it on her data and it failed :(

It parses the supermemo SMPAK file, which is akin to the MS compound document file, ie: a single file which contains multiple streams of data. The course data is found in the course.xml and item####.xml streams in the SMPAK file. However, it seems that self created supermemo courses actually store the course data as XML files in a subdirectory called "override"- with the same names as the streams in the SMPAK file.

Grzegorz Godlewski's code did all the heavy lifting of parsing the course data and repetitions and then writing the data in Anki format. All I had to do was make a small change to first look on the filesystem for the courses xml files.


The only problem was I'm not a java programmer - C++ and C# are my areas of expertise, so I was forced to download the JDK, Eclipse and Maven and see what I could do. It was suprisingly not too painful... and I managed to knock up something that worked.


You can find my efforts here on GitHub:


https://github.com/pceccato/smux-anki-converter

Thanks to Gregorz for his hard work and sharing his code with the world!

Welcome

Welcome to my first ever blog post.

I finally decided to create this blog as a way to keep track of all those annoying issues that get in your way whilst programming and their resolutions, and also other computer and tech related stuff.

I hope that someone else may find some of this information useful...