Skip to content

Instantly share code, notes, and snippets.

@cies
Created November 9, 2022 07:38
Show Gist options
  • Save cies/63bf1fafd8dc3947178fdcad54265649 to your computer and use it in GitHub Desktop.
Save cies/63bf1fafd8dc3947178fdcad54265649 to your computer and use it in GitHub Desktop.
Research patterns in "reverse substracting" numbers from themselves
#!/usr/bin/env ruby
# Bit of code to research patterns in "reverse substracting" numbers from themselves. Observations:
# * Mostly they reduce to zero; this can be by several routes:
# * Quick
# * 9's route (also: 99, 909, 999, 9009, 9999, 90009, 99099, 99999, etc.)
# * 54-45 route (also: 54945, 549945, 5499945, 54999945, etc.)
# * End up in a loop, which is always by route of a 2 sets of "magic numbers":
# * 2187, 21987, 219987, 2199987, 21999987, etc.
# * 6534, 65934, 659934, 6599934, 65999934, etc.
# reduce a number by subtracting it from its reverse, and then take absolute of the result
def revsub(n)
# we reverse in base10, hence the algorithm is base10 specific
(n - n.to_s.reverse.to_i).abs
end
# true for numbers like 2178, 6534, 21978, 65934, 219978, 659934, 2199978, 6599934, etc.
# 2178: 2+7=9, 1+8=9; 6534: 6+3=9, 5+4=9; 2178 * 3 = 6534 (this also holds true outside of base10)
def is_magic1?(n)
return false if n < 2178
s = n.to_s
((s[0..1] == "21" && s[-2..-1] == "78") || (s[0..1] == "65" && s[-2..-1] == "34")) && s[2..-3] =~ /[9]*/
end
# TODO: define test for magic2, /[9]+[0]*[9]+/ || /54[9]*45/ # palindromes, but not all palindromes!
# keep some counts to get a grip on frequencies
c = {:looped => 0, :is_magic1 => 0, :by_5445 => 0, :nines => 0, :quick => 0}
(0..10000_000_000).each do |i|
a = [i]
r = i
uniq = true
while r > 0 && uniq
# not many steps are needed, even when i grows really big
r = revsub(r)
uniq = !a.include?(r)
a << r
end
# do the counting
c[:looped] += 1 if !uniq
c[:is_magic1] += 1 if is_magic1?(a[-1])
c[:by_5445] += 1 if a[-2] == 5445
c[:nines] += 1 if a[-2].to_s =~ /[9]+/
c[:quick] += 1 if a[-2] == i
unless is_magic1?(a[-1])
p [i, a.reverse[0..5]]
p [:uniq, a] unless uniq
p [:not_hidden, a] unless a[-2].to_s =~ /[9]+/ || a[-2] == i || a[-2] == 5445
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment