Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>There's a new, radically faster version as <a href="https://stackoverflow.com/questions/1269795/unusual-speed-difference-between-python-and-c/1275074#1275074">a separate answer</a>, so this answer is deprecated.</strong></p> <hr> <p>I rewrote your algorithm by making it cache whenever it finds the number to be happy or unhappy. I also tried to make it as pythonic as I could, for example by creating separate functions <code>digits()</code> and <code>happy()</code>. Sorry for using Python 3, but I get to show off a couple a useful things from it as well.</p> <p>This version is <strong>much faster</strong>. It runs at <strong>1.7s</strong> which is <strong>10 times</strong> faster than your original program that takes <strong>18s</strong> (well, my MacBook is quite old and slow :) )</p> <pre><code>#!/usr/bin/env python3 from timeit import Timer from itertools import count print_numbers = False upperBound = 10**5 # Default value, can be overidden by user. def digits(x:'nonnegative number') -&gt; "yields number's digits": if not (x &gt;= 0): raise ValueError('Number should be nonnegative') while x: yield x % 10 x //= 10 def happy(number, known = {1}, happies = {1}) -&gt; 'True/None': '''This function tells if the number is happy or not, caching results. It uses two static variables, parameters known and happies; the first one contains known happy and unhappy numbers; the second contains only happy ones. If you want, you can pass your own known and happies arguments. If you do, you should keep the assumption commented out on the 1 line. ''' # assert 1 in known and happies &lt;= known # &lt;= is expensive if number in known: return number in happies history = set() while True: history.add(number) number = sum(x**2 for x in digits(number)) if number in known or number in history: break known.update(history) if number in happies: happies.update(history) return True def calcMain(): happies = {x for x in range(upperBound) if happy(x) } if print_numbers: print(happies) if __name__ == '__main__': upperBound = eval( input("Pick an upper bound [default {0}]: " .format(upperBound)).strip() or repr(upperBound)) result = Timer(calcMain).timeit(1) print ('This computation took {0} seconds'.format(result)) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload