stern_brocot_encoding_matrix_form.sf 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 10 February 2018
  4. # https://github.com/trizen
  5. # Encode a given fraction into a string of L's and R's,
  6. # indicating the turning points in the Stern-Brocot tree.
  7. # The decoding function takes a string of L's and R's and
  8. # constructs the fraction by navigating the Stern-Brocot tree.
  9. # See also:
  10. # https://www.youtube.com/watch?v=qPeD87HJ0UA
  11. # https://en.wikipedia.org/wiki/Stern%E2%80%93Brocot_tree
  12. func stern_brocot_encode (Number r) {
  13. var (m, n) = r.abs.nude
  14. var e = ''
  15. while (m != n) {
  16. if (m < n) {
  17. e += 'L'
  18. n -= m
  19. }
  20. else {
  21. e += 'R'
  22. m -= n
  23. }
  24. }
  25. return e
  26. }
  27. func stern_brocot_decode (String e) {
  28. var (a, b, c, d) = (1, 0, 0, 1)
  29. e.each { |t|
  30. if (t == 'L') {
  31. a += b
  32. c += d
  33. }
  34. else {
  35. b += a
  36. d += c
  37. }
  38. }
  39. return [[a,b],[c,d]]
  40. }
  41. func matrix2rat (Array A) {
  42. (A[0][0] + A[0][1]) / (A[1][0] + A[1][1])
  43. }
  44. say stern_brocot_decode(stern_brocot_encode(5/7)) # [[3, 2], [4, 3]]
  45. say stern_brocot_decode(stern_brocot_encode(43/97)) # [[4, 39], [9, 88]]
  46. say stern_brocot_decode(stern_brocot_encode(97/43)) # [[88, 9], [39, 4]]
  47. say ''
  48. say stern_brocot_encode(3/11) # LLLRL
  49. say stern_brocot_encode(19/8) # RRLLRL
  50. say ''
  51. say stern_brocot_decode('LLLRL') # [[2, 1], [7, 4]]
  52. say stern_brocot_decode('RRLLRL') # [[12, 7], [5, 3]]
  53. say ''
  54. say stern_brocot_decode('LRLRLRLRLRLRLRLRLRLRLRLRLRLRLR') # [[514229, 832040], [832040, 1346269]]
  55. say stern_brocot_decode('RLRLRLRLRLRLRLRLRLRLRLRLRLRLRL') # [[1346269, 832040], [832040, 514229]]
  56. say ''
  57. say stern_brocot_decode('RLLRR') # [[3, 7], [2, 5]]
  58. say stern_brocot_decode('RLLRRLL') # [[17, 7], [12, 5]]
  59. say stern_brocot_decode('RLLRRLLRR') # [[17, 41], [12, 29]]
  60. say stern_brocot_decode('RLLRRLLRRLL') # [[99, 41], [70, 29]]
  61. say stern_brocot_decode('RLLRRLLRRLLRR') # [[99, 239], [70, 169]]
  62. say stern_brocot_decode('RLLRRLLRRLLRRLL') # [[577, 239], [408, 169]]
  63. say stern_brocot_decode('RLLRRLLRRLLRRLLRR') # [[577, 1393], [408, 985]]
  64. say ''
  65. say matrix2rat(stern_brocot_decode('RLLRRLLRRLLRRLLRRLL')) # 1.414213...