{"id":245,"date":"2010-04-10T23:08:50","date_gmt":"2010-04-11T07:08:50","guid":{"rendered":"http:\/\/www.madpickles.org\/rokjoo\/?p=245"},"modified":"2012-04-09T20:10:54","modified_gmt":"2012-04-10T04:10:54","slug":"project-euler-problems-12-13-14","status":"publish","type":"post","link":"https:\/\/www.madpickles.org\/rokjoo\/2010\/04\/10\/project-euler-problems-12-13-14\/","title":{"rendered":"Project Euler Problems #12, #13, #14"},"content":{"rendered":"<p>Problem #12<br \/>\nFind the first triangle number to have over 500 divisors.<\/p>\n<p>As I&#8217;m progressing through these problems, certain types\/sequences of numbers keep popping up. I&#8217;ve started a library of functions called eulerLib.py. The first thing I did was add a triangle number generator to my library:<\/p>\n<pre>\r\ndef triangleNumber():\r\n num = 1\r\n add = 2\r\n while True:\r\n  yield num\r\n  num += add\r\n  add += 1\r\n<\/pre>\n<p>I can assign that to a variable and then invoke next() repeatedly to get triangle numbers ad infinitum.<\/p>\n<p>Then I needed a function that could factor numbers. One way I could go about things would be to figure out all the proper divisors; however, since I didn&#8217;t actually care what the divisors were, just the number of them, another thing I could do is figure out the prime factorization and then use the divisor function to calculate the number of proper divisors. I added another function to my library:<\/p>\n<pre>\r\ndef primeFactorization(num):\r\n factors = []\r\n while 2 <= num:\r\n  if num &#038; 1:\r\n   break\r\n  else:\r\n   num = num >> 1\r\n   factors.append(2)\r\n factor = 3\r\n while factor <= num:\r\n  if num % factor == 0:\r\n   num \/= factor\r\n   factors.append(factor)\r\n  else:\r\n   factor += 2\r\n return factors\r\n<\/pre>\n<p>This may not be the fastest algorithm, but it is fast enough. 2 is the smallest and only even prime number, so while num is even, it keeps adding 2 to the list of factors and dividing num. After that it starts with 3 and does the same thing for every subsequent odd number. It's inefficient as it will try to divide num by 9 after it has reduced num such that 3 will no longer divide it. At some point it will probably be useful to create a list of prime numbers so I don't have to keep generating them over and over...<\/p>\n<p>Once I have the prime factorization, I need to figure out the number of times each factor occurs in the list. Since my list is sorted, I can just loop through:<\/p>\n<pre>\r\ndef uniqueCounts(l):\r\n counts = []\r\n count = 0\r\n previous = None\r\n for x in l:\r\n  if x == previous:\r\n   count += 1\r\n  else:\r\n   counts.append(count+1)\r\n   count = 1\r\n   previous = x\r\n counts.append(count+1)\r\n return counts\r\n<\/pre>\n<p>Then the divisor function is simply:<\/p>\n<pre>\r\ndef divisorFunction(factors):\r\n return reduce(operator.mul,uniqueCounts(factors))\r\n<\/pre>\n<p>Clearly I could have kept count while figuring out the prime factorization, but then the function is not as reusable. I suppose I could have passed in a function that operated on the factors as they were discovered, even blending the divisor function in as well, but for understandability, I've kept them separate. At this point, all the pieces are there and it's just a matter of looping through triangle numbers and figuring out the number of divisors. When the number of divisors is > 500, return that triangle number...it's less than 100,000,000.<\/p>\n<p>Problem #13<br \/>\nFigure out the first 10 digits of the sum of <a href=\"http:\/\/projecteuler.net\/index.php?section=problems&#038;id=13\" target=\"_blank\">100 50 digit numbers<\/a>.<\/p>\n<p>Even though Python supports <a href=\"http:\/\/en.wikipedia.org\/wiki\/Arbitrary-precision_arithmetic\" target=\"_blank\">arbitrary-precision arithmetic<\/a>, in this particular case there's no need to add every digit of every number. Since we've only been asked to provide the first 10 digits of the sum, we only need to add the first 11 digits of each number since none of the others happen to affect the first 10 digits of the sum.<\/p>\n<pre>\r\ntotal = 0\r\nfile = open(\"problem0013.txt\",\"r\")\r\nwhile True:\r\n temp = file.readline()\r\n if not temp:\r\n  break\r\n total += int(temp[0:11])\r\nfile.close()\r\nprint str(total)[:10]\r\n<\/pre>\n<p>Problem #14<br \/>\nThe following iterative sequence is defined for the set of positive integers:<\/p>\n<p>n -> n\/2 (n is even)<br \/>\nn -> 3n + 1 (n is odd)<\/p>\n<p>Using the rule above and starting with 13, we generate the following sequence of 10 numbers:<br \/>\n13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1<br \/>\nWhich starting number, under one million, produces the longest sequence?<\/p>\n<p>It seemed like a brute force algorithm with some caching would likely solve this relatively quickly.<\/p>\n<pre>\r\ncache = dict()\r\ncache[1] = 1\r\nmaxCount = [1,1]\r\n\r\ndef find(n,m):\r\n newN = 0\r\n if n in cache:\r\n  return cache[n]\r\n elif n % 2 == 0:\r\n  newN = n \/ 2\r\n else:\r\n  newN = 3 * n +1\r\n temp = 1 + find(newN,m)\r\n cache[n] = temp \r\n if temp > m[1] and n < 1000000:\r\n  m[0] = n\r\n  m[1] = temp\r\n return cache[n]\r\n\r\nfor i in xrange(2,1000000):\r\n find(i,maxCount)\r\nprint maxCount\r\n<\/pre>\n<p>This solves the problem in about 10 seconds on my EeePC. It's an interesting fact that the cache contains 2,168,611 values even though it's only calculating the counts for numbers < 1,000,000 because any odd number > 333,333 creates a value greater than 1,000,000 in the sequence.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Problem #12 Find the first triangle number to have over 500 divisors. As I&#8217;m progressing through these problems, certain types\/sequences of numbers keep popping up. I&#8217;ve started a library of functions called eulerLib.py. The first thing I did was add a triangle number generator to my library: def triangleNumber(): num = 1 add = 2 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[18,11,19,17],"_links":{"self":[{"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/posts\/245"}],"collection":[{"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":8,"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"predecessor-version":[{"id":667,"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/posts\/245\/revisions\/667"}],"wp:attachment":[{"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.madpickles.org\/rokjoo\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}