remainder_tree.sf 559 B

12345678910111213141516171819202122232425262728
  1. #!/usr/bin/ruby
  2. # Remainder tree algorithm.
  3. # Algorithm from:
  4. # https://facthacks.cr.yp.to/remainder.html
  5. func product_tree(X) {
  6. gather {
  7. take(X)
  8. while (X.len > 1) {
  9. X = range((X.len+1)>>1).map{|i| X.slice(i<<1, 2).prod }
  10. take(X)
  11. }
  12. }
  13. }
  14. func remainders(n,X) {
  15. var result = [n]
  16. product_tree(X).flip.each {|t|
  17. result = t.map_kv {|k,v| result[k>>1] % v }
  18. }
  19. return result
  20. }
  21. say var r = remainders(8675309, [11,13,17,19,23]) #=> [5, 6, 5, 4, 8]
  22. assert_eq(r, [5, 6, 5, 4, 8])