Number curiosities
What a number's digits do: happy numbers and the cycle every other number falls into, Armstrong numbers, the digital root beside its formula, and Kaprekar's routine to 6174 and 495, step by step.
Every screen below was recorded under CPython. When this page was built, the EML interpreter replayed each session from the same input and printed the same bytes.
About
What a number's digits do, four ways: happy numbers, Armstrong numbers, the digital root, and Kaprekar's routine.
main.eml- the menu, one number four ways, the lists, and Kaprekar's routine step by stepcurious.eml- digits, the happy chain, Armstrong sums, digital roots and Kaprekar's steps
How each part works:
- Happy numbers, as in the corpus case
happy-number: replace a number by the sum of the squares of its digits, again and again. A happy number reaches 1. Every other number falls into the cycle 4, 16, 37, 58, 89, 145, 42, 20 and never reaches 1. The chain stops at the first number seen twice. - Armstrong numbers, as in the corpus case
armstrong-number-checker: the digits, each raised to the number of digits, add up to the number itself. Up to 10,000 there are 16: the nine single digits, 153, 370, 371, 407, 1634, 8208 and 9474. - The digital root, as in the corpus case
digital-root-recursive: add the digits until one is left. It equals 1 + (n - 1) mod 9, and the program shows both. - Kaprekar's routine: sort the digits high to low, subtract them sorted low to high, and repeat, keeping zeros in front. Every number from 1000 to 9999 whose digits are not all the same reaches 6174 within 7 steps, and every one from 100 to 999 reaches 495 within 6. That was found by trying all 8,991 and all 891 of them, in the cross-check; the program states the result.
What is checked: menu choices 1 to 5; a number from 1 to 999,999,999; up to 1,000 for the happy list and 10,000 for the Armstrong list; 3 or 4 digits for Kaprekar's routine, zeros in front allowed. An empty answer cancels.
Sessions: sessions/basic.in gives: - 7 (happy, Armstrong) and 4 (unhappy, inside the cycle); - 153 (Armstrong, Kaprekar to 495 in 3 steps), 3087, 9474 (Armstrong, 5 steps to 6174) and 999,999,999; - the happy numbers to 100 and the Armstrong numbers to 10,000; - Kaprekar's routine on 0021, 495, 2111 (through 0999) and 5555 (all digits the same).
sessions/bad-input.in gives: - menu choices 0 and x; - numbers 0, 1,000,000,000 and abc, then a cancel; - list limits 0, 1,001 and 10,001, with cancels; - Kaprekar inputs: a cancel, 12, 12345, abc, and 000.
Built on the verified corpus cases happy-number (the sum of squared digits, followed to 1 or to a cycle), armstrong-number-checker (digits to the power of their count) and digital-root-recursive (digit sums down to one digit).
Recorded sessions
What the screen shows while someone uses the program. Each typed line appears after its prompt, the way a terminal shows it.
bad-input
interpreter: byte-equal== Number curiosities ==
What a number's digits do: happy numbers, Armstrong numbers, the digital root and Kaprekar's routine.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 0
Pick a number from 1 to 5.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> x
Pick a number from 1 to 5.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 0
Type a whole number from 1 to 999999999.
number (1 to 999999999)> 1000000000
Type a whole number from 1 to 999999999.
number (1 to 999999999)> abc
Type a whole number from 1 to 999999999.
number (1 to 999999999)>
Cancelled.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 2
up to (1 to 1000)> 0
Type a whole number from 1 to 1000.
up to (1 to 1000)> 1001
Type a whole number from 1 to 1000.
up to (1 to 1000)>
Cancelled.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 3
up to (1 to 10000)> 10001
Type a whole number from 1 to 10000.
up to (1 to 10000)>
Cancelled.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)>
Cancelled.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 12
Type 3 or 4 digits.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 12345
Type 3 or 4 digits.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> abc
Type 3 or 4 digits.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 000
Kaprekar's routine needs at least two different digits; 000 goes straight to 000.
Every number from 100 to 999 whose digits are not all the same reaches 495 within 6 steps.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 5
Bye.
What was typed (25 lines)
0
x
1
0
1000000000
abc
2
0
1001
3
10001
4
4
12
4
12345
4
abc
4
000
5
basic
interpreter: byte-equal== Number curiosities ==
What a number's digits do: happy numbers, Armstrong numbers, the digital root and Kaprekar's routine.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 7
Happy: 7 -> 49 -> 97 -> 130 -> 10 -> 1.
Armstrong: 7^1 = 7, the number itself.
Digital root 7: 7; and 1 + (7 - 1) mod 9 = 7.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 4
Not happy: 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4, round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.
Armstrong: 4^1 = 4, the number itself.
Digital root 4: 4; and 1 + (4 - 1) mod 9 = 4.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 153
Not happy: 153 -> 35 -> 34 -> 25 -> 29 -> 85 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16 -> 37 -> 58 -> 89, round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.
Armstrong: 1^3 + 5^3 + 3^3 = 153, the number itself.
Digital root 9: 153 -> 9; and 1 + (153 - 1) mod 9 = 9.
Kaprekar's routine on 3 digits:
531 - 135 = 396
963 - 369 = 594
954 - 459 = 495
954 - 459 = 495
It reaches 495 in 3 steps, and 495 gives itself again.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 3087
Not happy: 3087 -> 122 -> 9 -> 81 -> 65 -> 61 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16 -> 37, round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.
Not Armstrong: 3^4 + 0^4 + 8^4 + 7^4 = 6578.
Digital root 9: 3087 -> 18 -> 9; and 1 + (3087 - 1) mod 9 = 9.
Kaprekar's routine on 4 digits:
8730 - 0378 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
It reaches 6174 in 2 steps, and 6174 gives itself again.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 9474
Not happy: 9474 -> 162 -> 41 -> 17 -> 50 -> 25 -> 29 -> 85 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16 -> 37 -> 58 -> 89, round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.
Armstrong: 9^4 + 4^4 + 7^4 + 4^4 = 9474, the number itself.
Digital root 6: 9474 -> 24 -> 6; and 1 + (9474 - 1) mod 9 = 6.
Kaprekar's routine on 4 digits:
9744 - 4479 = 5265
6552 - 2556 = 3996
9963 - 3699 = 6264
6642 - 2466 = 4176
7641 - 1467 = 6174
7641 - 1467 = 6174
It reaches 6174 in 5 steps, and 6174 gives itself again.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 1
number (1 to 999999999)> 999999999
Not happy: 999999999 -> 729 -> 134 -> 26 -> 40 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16, round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.
Not Armstrong: 9^9 + 9^9 + 9^9 + 9^9 + 9^9 + 9^9 + 9^9 + 9^9 + 9^9 = 3486784401.
Digital root 9: 999999999 -> 81 -> 9; and 1 + (999999999 - 1) mod 9 = 9.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 2
up to (1 to 1000)> 100
20 happy numbers up to 100: 1 7 10 13 19 23 28 31 32 44 49 68 70 79 82 86 91 94 97 100
Every other number falls into the cycle 4, 16, 37, 58, 89, 145, 42, 20 and never reaches 1.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 3
up to (1 to 10000)> 10000
16 Armstrong numbers up to 10000: 1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474
Each single digit is one; after them the next are 153, 370, 371 and 407, then 1634, 8208 and 9474.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 0021
Kaprekar's routine on 4 digits:
2100 - 0012 = 2088
8820 - 0288 = 8532
8532 - 2358 = 6174
7641 - 1467 = 6174
It reaches 6174 in 3 steps, and 6174 gives itself again.
Every number from 1000 to 9999 whose digits are not all the same reaches 6174 within 7 steps.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 495
Kaprekar's routine on 3 digits:
954 - 459 = 495
It reaches 495 in 1 step, and 495 gives itself again.
Every number from 100 to 999 whose digits are not all the same reaches 495 within 6 steps.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 2111
Kaprekar's routine on 4 digits:
2111 - 1112 = 0999
9990 - 0999 = 8991
9981 - 1899 = 8082
8820 - 0288 = 8532
8532 - 2358 = 6174
7641 - 1467 = 6174
It reaches 6174 in 5 steps, and 6174 gives itself again.
Every number from 1000 to 9999 whose digits are not all the same reaches 6174 within 7 steps.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 4
a number of 3 or 4 digits, zeros in front allowed (such as 0021)> 5555
Kaprekar's routine needs at least two different digits; 5555 goes straight to 0000.
Every number from 1000 to 9999 whose digits are not all the same reaches 6174 within 7 steps.
1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit
choice> 5
Bye.
What was typed (25 lines)
1
7
1
4
1
153
1
3087
1
9474
1
999999999
2
100
3
10000
4
0021
4
495
4
2111
4
5555
5
Modules
The program as written, entry module first. Each module transpiles to its own Python file, which is what eml project run executes.
main.eml(entry)
eml# P113 number curiosities: one number's digits four ways, happy and
# Armstrong numbers up to a limit, and Kaprekar's routine step by step.
import curious
def plain(s):
0 => i
len(s) => j
while i < j and s[i] == " ":
i + 1 => i
while j > i and s[j - 1] == " ":
j - 1 => j
return s[i:j]
def number(s, most):
if len(s) == 0 or len(s) > most:
return -1
0 => n
for c in s:
if not (c >= "0" and c <= "9"):
return -1
n * 10 + int(c) => n
return n
def ask(prompt, low, high):
while True:
plain(input(prompt + " (" + str(low) + " to " + str(high) + ")> ")) => a
if a == "":
return -1
number(a, 10) => n
if n >= low and n <= high:
return n
("Type a whole number from " + str(low) + " to " + str(high) + ".") ^0
def arrows(xs):
"" => out
for x in xs:
if out != "":
out + " -> " => out
out + str(x) => out
return out
def padded(n, width):
str(n) => s
while len(s) < width:
"0" + s => s
return s
def one():
ask("number", 1, 999999999) => n
if n == -1:
"Cancelled." ^0
return
curious.happy_chain(n) => h
if h[0]:
("Happy: " + arrows(h[1]) + ".") ^0
else:
("Not happy: " + arrows(h[1]) + ", round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.") ^0
curious.digits(n) => ds
curious.armstrong_sum(n) => a
"" => terms
for d in ds:
if terms != "":
terms + " + " => terms
terms + str(d) + "^" + str(len(ds)) => terms
if a == n:
("Armstrong: " + terms + " = " + str(a) + ", the number itself.") ^0
else:
("Not Armstrong: " + terms + " = " + str(a) + ".") ^0
curious.root_steps(n) => r
("Digital root " + str(r[len(r) - 1]) + ": " + arrows(r) + "; and 1 + (" + str(n) + " - 1) mod 9 = " + str(curious.root_formula(n)) + ".") ^0
if len(ds) == 3 or len(ds) == 4:
kap(n, len(ds))
def kap(n, width):
if curious.same_digits(n, width):
("Kaprekar's routine needs at least two different digits; " + padded(n, width) + " goes straight to " + padded(0, width) + ".") ^0
return
curious.kaprekar(n, width) => st
("Kaprekar's routine on " + str(width) + " digits:") ^0
0 => k
-1 => reached
for s in st:
k + 1 => k
(" " + padded(s[0], width) + " - " + padded(s[1], width) + " = " + padded(s[2], width)) ^0
if reached == -1 and (s[2] == 6174 or s[2] == 495):
k => reached
if reached >= 0:
("It reaches " + str(st[reached - 1][2]) + " in " + str(reached) + " step" + plural(reached) + ", and " + str(st[reached - 1][2]) + " gives itself again.") ^0
def plural(n):
if n == 1:
return ""
return "s"
def list_happy():
ask("up to", 1, 1000) => n
if n == -1:
"Cancelled." ^0
return
[] => hs
for k in [1:n]:
if curious.happy_chain(k)[0]:
hs + [k] => hs
"" => line
for h in hs:
if line != "":
line + " " => line
line + str(h) => line
(str(len(hs)) + " happy numbers up to " + str(n) + ": " + line) ^0
"Every other number falls into the cycle 4, 16, 37, 58, 89, 145, 42, 20 and never reaches 1." ^0
def list_armstrong():
ask("up to", 1, 10000) => n
if n == -1:
"Cancelled." ^0
return
"" => line
0 => c
for k in [1:n]:
if curious.armstrong_sum(k) == k:
c + 1 => c
if line != "":
line + " " => line
line + str(k) => line
(str(c) + " Armstrong numbers up to " + str(n) + ": " + line) ^0
"Each single digit is one; after them the next are 153, 370, 371 and 407, then 1634, 8208 and 9474." ^0
def kaprekar_menu():
plain(input("a number of 3 or 4 digits, zeros in front allowed (such as 0021)> ")) => t
if t == "":
"Cancelled." ^0
return
number(t, 4) => n
if n < 0 or len(t) < 3:
"Type 3 or 4 digits." ^0
return
kap(n, len(t))
if len(t) == 4:
"Every number from 1000 to 9999 whose digits are not all the same reaches 6174 within 7 steps." ^0
else:
"Every number from 100 to 999 whose digits are not all the same reaches 495 within 6 steps." ^0
"== Number curiosities ==" ^0
"What a number's digits do: happy numbers, Armstrong numbers, the digital root and Kaprekar's routine." ^0
True => running
while running:
"" ^0
"1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit" ^0
plain(input("choice> ")) => choice
if choice == "1":
one()
elif choice == "2":
list_happy()
elif choice == "3":
list_armstrong()
elif choice == "4":
kaprekar_menu()
elif choice == "5":
False => running
else:
"Pick a number from 1 to 5." ^0
"Bye." ^0
Python projection (main.py)
import curious
def plain(s):
i = 0
j = len(s)
while i < j and s[i] == " ":
i = i + 1
while j > i and s[j - 1] == " ":
j = j - 1
return s[i:j]
def number(s, most):
if len(s) == 0 or len(s) > most:
return -1
n = 0
for c in s:
if not (c >= "0" and c <= "9"):
return -1
n = n * 10 + int(c)
return n
def ask(prompt, low, high):
while True:
a = plain(input(prompt + " (" + str(low) + " to " + str(high) + ")> "))
if a == "":
return -1
n = number(a, 10)
if n >= low and n <= high:
return n
print("Type a whole number from " + str(low) + " to " + str(high) + ".")
def arrows(xs):
out = ""
for x in xs:
if out != "":
out = out + " -> "
out = out + str(x)
return out
def padded(n, width):
s = str(n)
while len(s) < width:
s = "0" + s
return s
def one():
n = ask("number", 1, 999999999)
if n == -1:
print("Cancelled.")
return
h = curious.happy_chain(n)
if h[0]:
print("Happy: " + arrows(h[1]) + ".")
else:
print("Not happy: " + arrows(h[1]) + ", round the cycle of 4, 16, 37, 58, 89, 145, 42 and 20.")
ds = curious.digits(n)
a = curious.armstrong_sum(n)
terms = ""
for d in ds:
if terms != "":
terms = terms + " + "
terms = terms + str(d) + "^" + str(len(ds))
if a == n:
print("Armstrong: " + terms + " = " + str(a) + ", the number itself.")
else:
print("Not Armstrong: " + terms + " = " + str(a) + ".")
r = curious.root_steps(n)
print("Digital root " + str(r[len(r) - 1]) + ": " + arrows(r) + "; and 1 + (" + str(n) + " - 1) mod 9 = " + str(curious.root_formula(n)) + ".")
if len(ds) == 3 or len(ds) == 4:
kap(n, len(ds))
def kap(n, width):
if curious.same_digits(n, width):
print("Kaprekar's routine needs at least two different digits; " + padded(n, width) + " goes straight to " + padded(0, width) + ".")
return
st = curious.kaprekar(n, width)
print("Kaprekar's routine on " + str(width) + " digits:")
k = 0
reached = -1
for s in st:
k = k + 1
print(" " + padded(s[0], width) + " - " + padded(s[1], width) + " = " + padded(s[2], width))
if reached == -1 and (s[2] == 6174 or s[2] == 495):
reached = k
if reached >= 0:
print("It reaches " + str(st[reached - 1][2]) + " in " + str(reached) + " step" + plural(reached) + ", and " + str(st[reached - 1][2]) + " gives itself again.")
def plural(n):
if n == 1:
return ""
return "s"
def list_happy():
n = ask("up to", 1, 1000)
if n == -1:
print("Cancelled.")
return
hs = []
for k in range(1, n+1):
if curious.happy_chain(k)[0]:
hs = hs + [k]
line = ""
for h in hs:
if line != "":
line = line + " "
line = line + str(h)
print(str(len(hs)) + " happy numbers up to " + str(n) + ": " + line)
print("Every other number falls into the cycle 4, 16, 37, 58, 89, 145, 42, 20 and never reaches 1.")
def list_armstrong():
n = ask("up to", 1, 10000)
if n == -1:
print("Cancelled.")
return
line = ""
c = 0
for k in range(1, n+1):
if curious.armstrong_sum(k) == k:
c = c + 1
if line != "":
line = line + " "
line = line + str(k)
print(str(c) + " Armstrong numbers up to " + str(n) + ": " + line)
print("Each single digit is one; after them the next are 153, 370, 371 and 407, then 1634, 8208 and 9474.")
def kaprekar_menu():
t = plain(input("a number of 3 or 4 digits, zeros in front allowed (such as 0021)> "))
if t == "":
print("Cancelled.")
return
n = number(t, 4)
if n < 0 or len(t) < 3:
print("Type 3 or 4 digits.")
return
kap(n, len(t))
if len(t) == 4:
print("Every number from 1000 to 9999 whose digits are not all the same reaches 6174 within 7 steps.")
else:
print("Every number from 100 to 999 whose digits are not all the same reaches 495 within 6 steps.")
print("== Number curiosities ==")
print("What a number's digits do: happy numbers, Armstrong numbers, the digital root and Kaprekar's routine.")
running = True
while running:
print("")
print("1) one number 2) happy numbers 3) Armstrong numbers 4) Kaprekar's routine 5) quit")
choice = plain(input("choice> "))
if choice == "1":
one()
elif choice == "2":
list_happy()
elif choice == "3":
list_armstrong()
elif choice == "4":
kaprekar_menu()
elif choice == "5":
running = False
else:
print("Pick a number from 1 to 5.")
print("Bye.")
curious.eml
eml# P113 number curiosities - four things a number's digits do:
# happy numbers: replace a number by the sum of the squares of its digits;
# it reaches 1 (happy) or falls into 4, 16, 37, 58, 89, 145, 42, 20
# (the corpus case happy-number);
# Armstrong numbers: the sum of the digits, each raised to the number of
# digits, is the number itself (the corpus case armstrong-number-checker);
# the digital root: add the digits until one is left; it is 1 + (n - 1)
# mod 9 for n above 0 (the corpus case digital-root-recursive);
# Kaprekar's routine: the digits sorted high to low, minus sorted low to
# high, again and again; four digits reach 6174, three reach 495.
def digits(n):
# most significant first
[] => out
n => x
if x == 0:
return [0]
while x > 0:
[x % 10] + out => out
int((x - x % 10) / 10) => x
return out
def square_sum(n):
0 => s
for d in digits(n):
s + d * d => s
return s
def happy_chain(n):
# [happy, the numbers visited]: stops at 1, or at the first number seen
# twice
[n] => seen
n => x
while x != 1:
square_sum(x) => x
for y in seen:
if y == x:
return [False, seen + [x]]
seen + [x] => seen
return [True, seen]
def power(b, e):
1 => p
for i in [1:e]:
p * b => p
return p
def armstrong_sum(n):
digits(n) => ds
0 => s
for d in ds:
s + power(d, len(ds)) => s
return s
def root_steps(n):
# the digit sums down to one digit, n first
[n] => out
n => x
while x > 9:
0 => s
for d in digits(x):
s + d => s
s => x
out + [x] => out
return out
def root_formula(n):
if n == 0:
return 0
return 1 + (n - 1) % 9
def kaprekar_step(n, width):
# [big, small, big - small], with leading zeros kept to `width` digits
digits(n) => ds
while len(ds) < width:
[0] + ds => ds
# sort low to high
for i in [1:len(ds) - 1]:
i => j
while j > 0 and ds[j] < ds[j - 1]:
ds[j] => t
ds[j - 1] => ds[j]
t => ds[j - 1]
j - 1 => j
0 => small
0 => big
for d in ds:
small * 10 + d => small
for k in [0:len(ds) - 1]:
big * 10 + ds[len(ds) - 1 - k] => big
return [big, small, big - small]
def kaprekar(n, width):
# the steps until the number repeats: [[big, small, result], ...]
[] => out
[n] => seen
n => x
True => going
while going:
kaprekar_step(x, width) => st
out + [st] => out
st[2] => x
for y in seen:
if y == x:
False => going
seen + [x] => seen
return out
def same_digits(n, width):
digits(n) => ds
while len(ds) < width:
[0] + ds => ds
for d in ds:
if d != ds[0]:
return False
return True
Python projection (curious.py)
def digits(n):
out = []
x = n
if x == 0:
return [0]
while x > 0:
out = [x % 10] + out
x = int((x - x % 10) / 10)
return out
def square_sum(n):
s = 0
for d in digits(n):
s = s + d * d
return s
def happy_chain(n):
seen = [n]
x = n
while x != 1:
x = square_sum(x)
for y in seen:
if y == x:
return [False, seen + [x]]
seen = seen + [x]
return [True, seen]
def power(b, e):
p = 1
for i in range(1, e+1):
p = p * b
return p
def armstrong_sum(n):
ds = digits(n)
s = 0
for d in ds:
s = s + power(d, len(ds))
return s
def root_steps(n):
out = [n]
x = n
while x > 9:
s = 0
for d in digits(x):
s = s + d
x = s
out = out + [x]
return out
def root_formula(n):
if n == 0:
return 0
return 1 + (n - 1) % 9
def kaprekar_step(n, width):
ds = digits(n)
while len(ds) < width:
ds = [0] + ds
for i in range(1, len(ds)):
j = i
while j > 0 and ds[j] < ds[j - 1]:
t = ds[j]
ds[j] = ds[j - 1]
ds[j - 1] = t
j = j - 1
small = 0
big = 0
for d in ds:
small = small * 10 + d
for k in range(0, len(ds)):
big = big * 10 + ds[len(ds) - 1 - k]
return [big, small, big - small]
def kaprekar(n, width):
out = []
seen = [n]
x = n
going = True
while going:
st = kaprekar_step(x, width)
out = out + [st]
x = st[2]
for y in seen:
if y == x:
going = False
seen = seen + [x]
return out
def same_digits(n, width):
ds = digits(n)
while len(ds) < width:
ds = [0] + ds
for d in ds:
if d != ds[0]:
return False
return True