The closing date of the the inaugural Functional Fun programming competition has passed, and I’m relieved to say I actually had some judging to do. Further to my post on Monday, two bits are now required to hold the number of submissions I have to choose between - though not used to full capacity.
The Winner
Our winner is Jamie, a High School Student from Massachusetts, whose code surpasses in elegance my attempt at solving my own problem. Jamie gets the prize of £25 in Amazon gift vouchers. Honourable mention goes to Dan Dumitru who was the first to submit a solution.
Congratulations to Jamie, and thanks to all 10 of you who entered!
The Solution
The puzzle that Jamie and Dan solved was as follows;
Which Mathematicians have found themselves prime positions in the grid below?
So who were the coy Mathematicians, and how did they conceal themselves? Well, given the maths connection, “prime positions” must surely have something to do with prime numbers? So what happens if we count along the cells of the grid (wrapping over from the end of one row to the beginning of the following row) and note down the characters we find at indices which are prime-numbered?
Interesting! We get the string
tinyurl#teyuir#gqrtyh#hyirtq##
Teyuir? What theorem did he prove? must be Slovakian with a name like that. Now tinyurl – that rings a bell. Hey! I wonder what tinyurl.com/ teyuir looks like?
Huh! XML?
But wait: Leonhard Euler. There’s a name I recognise. Didn’t he dabble in mathematics, and prove a lemma or two?
And having reasoned thus, all that remains is to craft a handful of LINQ queries to winkle all three mathematicians out of the hiding places: Euler, Euclid and Cantor.
Here’s Jamie’s solution in its entirety. The code speaks for itself.
// Gets all the nonwhitespace characters var rawChars = from ch in File.ReadAllText("HiddenMathematicians.txt") where !char.IsWhiteSpace(ch) select ch; // Gets only the chars at prime indices (char[0] is at index 1) var primeChars = from num in Enumerable.Range(2, rawChars.Count() - 1) // creates all indices from 1 to numRawChars let divisors = Enumerable.Range(2, num - 2) // all possible divisors, 2 to num - 1 let isPrime = !divisors.Any(div => num % div == 0) where isPrime select rawChars.ElementAt(num - 1); // All the words, including the beginning hint var words = from str in primeChars.Aggregate(string.Empty, (str, ch) => str += ch).Split('#') where !string.IsNullOrEmpty(str) select str; var names = from word in words.Skip(1) let url = "http://" + words.First() + ".com/" + word let xmlData = XDocument.Load(url) let element = xmlData.XPathSelectElement("./api/query/pages/page") let attribute = element.Attribute("title") select attribute.Value; foreach (var name in names) Console.WriteLine(name); Console.ReadLine();