prog.sf 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/ruby
  2. # Smallest fraction using palindromes that approximates 'Pi' to at least n digits after the decimal point.
  3. # https://oeis.org/A048429 -- numerators
  4. # https://oeis.org/A048430 -- denominators
  5. func next_palindrome (n, b=10) {
  6. var d = n.digits(b)
  7. var l = d.end
  8. var i = (((d.len+1)>>1) - 1)
  9. while ((i >= 0) && (d[i] == b-1)) {
  10. d[i,l-i] = (0,0)
  11. --i
  12. }
  13. if (i >= 0) {
  14. d[i]++
  15. d[l-i] = d[i]
  16. }
  17. else {
  18. d = (d.len+1).of(0)
  19. d[0,-1] = (1,1)
  20. }
  21. d.digits2num(b)
  22. }
  23. func a(n) {
  24. var pi = Num.pi
  25. var pi_s = pi.to_s.first(n+2)
  26. var pi_r = pi.round(-(n-1))
  27. var l = Num(pi_s).rat_approx.de.len
  28. var p = Num('1' + '0'*(l-2) + '1')
  29. func check(t) {
  30. t.to_s.is_palindrome && (t/p -> as_float.begins_with(pi_s))
  31. }
  32. loop {
  33. with (pi_r * p -> floor) { |t|
  34. return [t.to_i, p] if check(t)
  35. }
  36. #~ with(pi_r * p -> ceil) { |t|
  37. #~ return [t.to_i, p] if check(t)
  38. #~ }
  39. with (pi * p -> round) {|t|
  40. return [t.to_i, p] if check(t)
  41. }
  42. p = next_palindrome(p)
  43. }
  44. }
  45. var nums = [22, 22, 666, 666, 1186811, 1633361, 7327237, 204656402, 971292179, 32418381423, 185295592581, 5760554550675, 6259909099526, 148967656769841]
  46. var dens = [7, 7, 212, 212, 377773, 519915, 2332332, 65144156, 309171903, 10319091301, 58981418985, 1833641463381, 1992590952991, 47417877871474]
  47. for k in (1..10) {
  48. var (n,d) = a(k)...
  49. var w = nums[k-1]/dens[k-1]
  50. say "a(#{k}) = #{n}/#{d} = #{n/d}"
  51. if (n/d != w) {
  52. say "\n\tHowever, the smallest such fraction is #{w.as_rat}\n"
  53. }
  54. #assert_eq(nums[k-1], n)
  55. #assert_eq(dens[k-1], d)
  56. }
  57. __END__
  58. a(3) = 666/212 = 3.14150943396226415094339622641509433962264150943
  59. a(4) = 666/212 = 3.14150943396226415094339622641509433962264150943
  60. a(5) = 1186811/377773 = 3.14159826138977640011329555050255047343245811638
  61. a(6) = 1633361/519915 = 3.1415923756767933219853245242010713289672350288
  62. a(7) = 7327237/2332332 = 3.14159262060461375138702380278622425966800609862
  63. a(8) = 204656402/65144156 = 3.14159265491136303922641963463307437738544037626
  64. a(9) = 971292179/309171903 = 3.14159265306847757119766475027971736487322394235
  65. a(10) = 32418381423/10319091301 = 3.14159265359522571007824829400644528709553666929