fork download
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Apr 13 17:07:03 2011
  4.  
  5. @author: pmav99
  6.  
  7. Project Euler - Problem 22
  8.  
  9. Using names.txt (right click and 'Save Link/Target As...'),
  10. a 46K text file containing over five-thousand first names,
  11. begin by sorting it into alphabetical order.
  12. Then working out the alphabetical value for each name,
  13. multiply this value by its alphabetical position in the
  14. list to obtain a name score.
  15.  
  16. For example, when the list is sorted into alphabetical order,
  17. COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th
  18. name in the list. So, COLIN would obtain a score of 938 × 53 = 49714.
  19.  
  20. What is the total of all the name scores in the file?
  21.  
  22. """
  23. ##------------------------------------------------------------------------------
  24.  
  25. from __future__ import division
  26. import sys
  27. import timeit
  28.  
  29. # needed for pyeuler
  30. import string
  31.  
  32. # needed for lambdas2
  33. if sys.version_info.major == 3:
  34. from functools import reduce
  35.  
  36. # needed for regex
  37. import re
  38.  
  39. def simple(fname = "names.txt"):
  40. """ 2 consecutive loops. """
  41. with open(fname, "r") as f:
  42. names = sorted(f.read().replace('"', "").split(","))
  43.  
  44. tot = 0
  45. for i, name in enumerate(names):
  46. for char in name:
  47. tot += (i + 1) * (ord(char) - 64)
  48.  
  49. return tot
  50.  
  51. def simple2(fname = "names.txt"):
  52. """ 2 consecutive loops - a bit faster """
  53. with open(fname, "r") as f:
  54. names = sorted(f.read().replace('"', "").split(","))
  55.  
  56. tot = 0
  57. for i, name in enumerate(names):
  58. tot_name = 0
  59. for char in name:
  60. tot_name += (ord(char) - 64)
  61. tot += (i + 1) * tot_name
  62.  
  63. return tot
  64.  
  65. def simple3(fname = "names.txt"):
  66. """ One loop and a list comprehension. """
  67. with open(fname, "r") as f:
  68. names = sorted(f.read().replace('"', "").split(","))
  69.  
  70. tot = 0
  71. for i, name in enumerate(names):
  72. tot += (i + 1) * sum([ord(char) - 64 for char in name])
  73.  
  74. return tot
  75.  
  76. def list_generators(fname = "names.txt"):
  77. """ One liner with list generator. Better memory usage, a little bit slower."""
  78. with open(fname, "r") as f:
  79. names = sorted(f.read().replace('"', "").split(","))
  80.  
  81. return sum((i+1) * sum(ord(c) - 64 for c in n) for i, n in enumerate(names))
  82.  
  83. def list_comprehension(fname = "names.txt"):
  84. """ One liner with list comprehension. Worse memory usage, maybe a little bit faster."""
  85. with open(fname, "r") as f:
  86. names = sorted(f.read().replace('"', "").split(","))
  87.  
  88. return sum([(i+1) * sum(ord(c) - 64 for c in n) for i, n in enumerate(names)])
  89.  
  90. def lambdas(fname = "names.txt"):
  91. """ from project euler solutions."""
  92. with open(fname, "r") as f:
  93. names = sorted(f.read().replace('"', "").split(","))
  94.  
  95. return sum(map(lambda x: (x[0]+1)*sum(map(lambda c: ord(c) - 64,x[1])),enumerate(names)))
  96.  
  97. def lambdas2(fname = "names.txt"):
  98. """ from project euler solutions."""
  99. with open(fname, "r") as f:
  100. x = sorted(f.read().replace('"', "").split(","))
  101.  
  102. return reduce(lambda x, y: x + y, [reduce(lambda x, y: x + y, [(j + 1) * (ord(i) - 64) for i in x[j]]) for j in range(len(x))])
  103.  
  104. def lambdas3(fname = "names.txt"):
  105. """ from project euler solutions."""
  106. with open(fname, "r") as f:
  107. names = sorted(f.read().replace('"', "").split(","))
  108.  
  109. return sum(sum(map(lambda x: ord(x) - 64, names[index])) * (index + 1) for index in range(len(names)))
  110.  
  111. def pyeuler(fname = "names.txt"):
  112. """ from pyeuler at github solutions."""
  113. with open(fname, "r") as f:
  114. names = sorted(f.read().replace('"', "").split(","))
  115.  
  116. dictionary = dict((c, n) for (n, c) in enumerate(string.ascii_uppercase, 1))
  117.  
  118. return sum(i*sum(dictionary[c] for c in name) for (i, name) in enumerate(names, 1))
  119.  
  120. def pyeuler2(fname = "names.txt"):
  121. """ from project euler solutions, with dictionary definition from pyeuler."""
  122. with open(fname, "r") as f:
  123. names = sorted(f.read().replace('"', "").split(","))
  124.  
  125. dictionary = dict((c, n) for (n, c) in enumerate(string.ascii_uppercase, 1))
  126.  
  127. return sum([sum([dictionary[x] for x in names[i]])*(i+1) for i in range(len(names))])
  128.  
  129. def regex(fname = "names.txt"):
  130. """
  131. It is the same algorithm as simple2. The only difference is the usage
  132. of the re module. It is slower, for this file size.
  133. """
  134. tot = 0
  135.  
  136. for i, name in enumerate(sorted(re.compile("\"([A-Z]+)\"").findall(open(fname,"r").read()))):
  137. name_total = 0
  138. for c in name:
  139. name_total += (ord(c) - 64)
  140. tot += (i + 1) * name_total
  141.  
  142. return tot
  143.  
  144. def main():
  145. repeat = 5
  146. number = 1 # for time comparison
  147.  
  148. funcs = (simple, simple2, simple3, list_generators, list_comprehension,
  149. lambdas, lambdas2, lambdas3, pyeuler, pyeuler2, regex)
  150.  
  151. print(50 * "-")
  152. print("System information")
  153. print(sys.version)
  154.  
  155. print(50 * "-")
  156. print("Check solutions")
  157. print(50 * "-")
  158. for f in funcs:
  159. print(f())
  160.  
  161. print(50 * "-")
  162. print("Time comparison")
  163. print(50 * "-")
  164. for f in funcs:
  165. t = timeit.Timer("{0}()".format(f.__name__),
  166. "from __main__ import {0}".format(f.__name__))
  167. print("{0:20} => {1}".format(f.__name__, min(t.repeat(repeat = repeat,
  168. number = number))))
  169.  
  170. if __name__ == "__main__":
  171. main()
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty