esthetic_numbers.sf 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 30 May 2020
  4. # https://github.com/trizen
  5. # Fast algorithm for generating esthetic numbers in a given base.
  6. # See also:
  7. # https://rosettacode.org/wiki/Esthetic_numbers
  8. # OEIS:
  9. # https://oeis.org/A000975 -- base 2
  10. # https://oeis.org/A033068 -- base 3
  11. # https://oeis.org/A033075 -- base 10
  12. func generate_esthetic(root, upto, callback, b=10) {
  13. var v = root.digits2num(b)
  14. return nil if (v > upto)
  15. callback(v)
  16. var t = root.head
  17. __FUNC__([t+1, root...], upto, callback, b) if (t+1 < b)
  18. __FUNC__([t-1, root...], upto, callback, b) if (t-1 >= 0)
  19. }
  20. func between_esthetic(from, upto, b=10) {
  21. gather {
  22. for k in (1..^b) {
  23. generate_esthetic([k], upto, { take(_) if (_ >= from) }, b)
  24. }
  25. }.sort
  26. }
  27. func first_n_esthetic(n, b=10) {
  28. for (var m = n**2; true ; m *= b) {
  29. var list = between_esthetic(1, m, b)
  30. return list.first(n) if (list.len >= n)
  31. }
  32. }
  33. for b in (2..16) {
  34. say ("First 20 esthetic numbers in base #{'%2d'%b}: ",
  35. first_n_esthetic(20, b))
  36. }
  37. __END__
  38. First 20 esthetic numbers in base 2: [1, 2, 5, 10, 21, 42, 85, 170, 341, 682, 1365, 2730, 5461, 10922, 21845, 43690, 87381, 174762, 349525, 699050]
  39. First 20 esthetic numbers in base 3: [1, 2, 3, 5, 7, 10, 16, 21, 23, 30, 32, 48, 50, 64, 70, 91, 97, 145, 151, 192]
  40. First 20 esthetic numbers in base 4: [1, 2, 3, 4, 6, 9, 11, 14, 17, 25, 27, 36, 38, 46, 57, 59, 68, 70, 100, 102]
  41. First 20 esthetic numbers in base 5: [1, 2, 3, 4, 5, 7, 11, 13, 17, 19, 23, 26, 36, 38, 55, 57, 67, 69, 86, 88]
  42. First 20 esthetic numbers in base 6: [1, 2, 3, 4, 5, 6, 8, 13, 15, 20, 22, 27, 29, 34, 37, 49, 51, 78, 80, 92]
  43. First 20 esthetic numbers in base 7: [1, 2, 3, 4, 5, 6, 7, 9, 15, 17, 23, 25, 31, 33, 39, 41, 47, 50, 64, 66]
  44. First 20 esthetic numbers in base 8: [1, 2, 3, 4, 5, 6, 7, 8, 10, 17, 19, 26, 28, 35, 37, 44, 46, 53, 55, 62]
  45. First 20 esthetic numbers in base 9: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 19, 21, 29, 31, 39, 41, 49, 51, 59, 61]
  46. First 20 esthetic numbers in base 10: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 21, 23, 32, 34, 43, 45, 54, 56, 65]
  47. First 20 esthetic numbers in base 11: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 23, 25, 35, 37, 47, 49, 59, 61]
  48. First 20 esthetic numbers in base 12: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 25, 27, 38, 40, 51, 53, 64]
  49. First 20 esthetic numbers in base 13: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 27, 29, 41, 43, 55, 57]
  50. First 20 esthetic numbers in base 14: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 29, 31, 44, 46, 59]
  51. First 20 esthetic numbers in base 15: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 31, 33, 47, 49]
  52. First 20 esthetic numbers in base 16: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 33, 35, 50]