This post is part of F# Advent calender. Thanks Sergey Tihon for arranging this and giving me chance.

First I like to clarify that this was not my original choice for FSAdvent calender. I was going to write long post about web, AKKA, api and real time system. My current working area. But this time’s calender entries are reaching new level and dimension. And recent post from Evelina Gabasova is kind of reason behind change. Do read the post and you may like to re-watch Star Wars series. Evelina you are super awesome. And post was too good.

So, why 1729?

I have special love for Mathematics. Unluckily I never got chance to take formal mathematics training. I’m an engineer so know things here and there to solve the problem. May be more than others for Physics and Mathematics just because of my love. It is so much fun doing them.

In our side of country if you are scoring good marks in School either you become doctor or if little less then engineer. Normally there is no other choices. Hope you got the point why I’m engineer (mine was little too less). But if you ask a name of well known gifted mathematician from India first name come is Srinivasa Ramanujan. And we have a exam series on his name. It is way tough, I still remember that I prepared and never gather enough guts to give one. Damn afraid of failing. But my senior and first leaving mathematics role model my senior in school Dr.Vithal Rangarajan scored 2nd rank and joined Medicine. Yet, my another friend Dr.Parth Ganatra same story. You mostly getting gist why we are having rare Ramanujans in India. Because most of them become Doctors.

Enough of back ground noise. Let’s have some fun with numbers. You can check out wiki page for the story of 1729 number. It is the smallest number expressible as the sum of two cubes in two different ways.

Ok, that is good. But I don’t have enough brain power to cross check that. And if that is smallest which are others?

So, I decided to find out by self. And at midnight I started working on this.

My first try was going to question form the result. But for some reason Math.Floor (1728.0 ** (1.0/3.0)) is resulting in 11.0. I have no idea why. It should come 12.0. Then I thought how he has arrived to this number. It is smallest so he must have started from 1.

F# gurus can you please tell me why 1728.0 ** (1.0/3.0) = 12.0 //false ?

Here is code snippet. I start with sequence of numbers and cube it.

let posNum = seq {1..101}

let cube x = x * x * x 

let cubeposNum = 
    posNum 
    |> Seq.map (fun x -> (x, cube x))

I have returned tuple instead of cube result so I can use it afterwords in visualizing data.

Now, its time to find out total combinations

let totalCombination = 
    cubeposNum 
    |> Seq.map (fun (a,b) -> cubeposNum |> Seq.map (fun (x,y) -> (a,x,b+y)))
    |> Seq.concat

It gives all the possible combinations numbers. Again in tuple I am returning result and numbers that are being cubed and added. Same reason for display purpose.

Now, time for truth.

Here is final result

let finalResult =
    totalCombination
    |> Seq.countBy (fun (x,y,z) -> z)
    |> Seq.filter (fun (x,y) -> y >= 4)
    |> Seq.map (fun (x,y) -> x)

It will return Sequence of numbers fulfilling above condition. if you are wondering for y>=4 then 4 is because (1,2,9) is same as (2,1,9). As I need two distinct pair, I having four pair. I did have used greater than 4 but couldn’t found any pair bigger than 4 for given set.

Time for doing some analysis of numbers.

let dirtyHack (inputSeq)=
    let a = inputSeq |> Seq.item 0
    let b = inputSeq |> Seq.item 1
    let c = inputSeq |> Seq.item 2
    (a, b, c)

let pairValues =
    finalResult 
    |> Seq.map (fun x -> totalCombination |> Seq.filter (fun (a,b,c) -> c = x ))
    |> Seq.map (fun a -> a |> Seq.map (fun (x,y,z) -> seq[x;y;z] |> Seq.sort |> dirtyHack))
    |> Seq.map (fun x -> x |> Seq.distinct)

It will give Sequence of Sequences which contains tuple of numbers. Where tuple is in form of (a , b, a^3 + b^3). Dirty hack part I couldn’t get it right so I will be grateful if someone can provide better solution in that part.

We have all the things. It’s time to put data to view.

//form crazyness - a copy paste from 2010 code :P

let form = new Form(Visible = true, Text = "A Simple F# Form",
                    TopMost = true, Size = Size(600,600))

let data = new DataGridView(Dock = DockStyle.Fill, Text = "Hardy–Ramanujan number",
                            Font = new Font("Lucida Console",12.0f),
                            ForeColor = Color.DarkBlue
                            )


form.Controls.Add(data)

data.DataSource <- (pairValues |> Seq.concat |> Seq.sortBy (fun (x,y,z) -> z) |> Seq.toArray)
data.Columns.[0].Width <- 200
data.Columns.[1].Width <- 200
data.Columns.[2].Width <- 200

data.Columns.[0].HeaderText <- "a"
data.Columns.[1].HeaderText <- "b"
data.Columns.[2].HeaderText <- "(a^3 + b^3)"

Clearing up the data showing up in grid view. Below are screen shots of complete data.

Looks good.

Put on chart to see where data is moving.

let taxicabnumbers = pairValues 
                     |> Seq.concat 
                     |> Seq.sortBy (fun (x,y,z) -> z) 
                     |> Seq.map (fun (x,y,z) -> z) 
                     |> Seq.distinct

Chart.Point (taxicabnumbers,"TaxiCabNumbers","TaxiCab Number")

above chart is showing distribution of result of numbers which are fulfilling above condition.

let taxicabnumbersX = pairValues 
                     |> Seq.concat 
                     |> Seq.sortBy (fun (x,y,z) -> z) 
                     |> Seq.map (fun (x,y,z) -> (x,z)) 


Chart.Point (taxicabnumbersX,"TaxiCabNumbersX","TaxiCab Number in ref to X")

above chart is showing distribution in compare to number X

let taxicabnumbersY = pairValues 
                     |> Seq.concat 
                     |> Seq.sortBy (fun (x,y,z) -> z) 
                     |> Seq.map (fun (x,y,z) -> (y,z)) 


Chart.Point (taxicabnumbersY,"TaxiCabNumbersY","TaxiCab Number in ref to Y")

above chart is showing distribution in compare to number Y

Chart.Combine[
    Chart.Point(taxicabnumbersX, "TaxiCabNumbersX")
    Chart.Point(taxicabnumbersY, "TaxiCabNumbersY")
]

above chart is showing both X,Y. Here, X and Y is pretty much interchangeable.

Code is not that good. But F# makes it pretty easy to work with. I will not bash any other language or style of programming today. As it is my *BirthDay today (1712 was pretty boring number and so I took 1729. :P ). But you can make it out. How, easy it can be.

Ramanujan is having many other interesting formula that can be proved and analyst same way. One of them I personally like is Partition Number Theory ).

I will really appreciate any input for code. I know it is pretty poor in quality. Gist is here. I love to have comments and PR. I will update my code/blog accordingly.

Special request. It will be great if someone can compress the code that can be tweeted to fsibot and it will return 1729.

Thanks for wonderful and supporting community. Merry Christmas and Happy New Year to all.

Update1

Special thanks to Stachu Korick complete logic comes in single tweet. Here it is.

This is the reason I love F# community so much.

Update2

Stachu Korick is not stopping at all. Here is second version more legitimate one from him.

This is fun part with F# and in general functional language. You make thing work with ugly and simple code. And then re-factor it with beautiful and simple code.

Update3

Oh man things are getting better (shorter.) Have a look at Mathias Brandewinder version

Sweeeeettttt :)

Update4

Yukitos made it even shorter. Hufff this is getting more and more fun.

Update5

Tomas Petricek make it even shorter. Beat this…

Update6

Above version is beaten already. New, record is by Scott Wlaschin.

PS: I can’t exactly say what is going on here. But I am enjoying it a lot.