Advertisement
Guest User

Untitled

a guest
Apr 16th, 2014
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.72 KB | None | 0 0
  1. class Rope
  2.  
  3. # Cat two ropes by building a new binary node.
  4. # The parent count is the left child's length.
  5. def cat(s)
  6. if self.len == 0
  7. s
  8. elsif s.len == 0
  9. self
  10. else
  11. Node.new(self, s, len)
  12. end
  13. end
  14.  
  15. # Insert a new string into a rope by splitting it
  16. # and concatenating twice with a new leaf in the middle.
  17. def insert(s, p)
  18. a, b = split_at(p)
  19. a.cat(Leaf.new(s)).cat(b)
  20. end
  21.  
  22. end
  23.  
  24. class Leaf < Rope
  25. # A leaf holds characters as a string.
  26. attr_accessor :chars
  27.  
  28. # Construct a new leaf with given characters.
  29. def initialize(chars)
  30. @chars = chars
  31. end
  32.  
  33. # The count in this rope is just the number of characters.
  34. def count
  35. chars.length
  36. end
  37.  
  38. # The length is kind of obvious.
  39. def len
  40. chars.length
  41. end
  42.  
  43. # Convert to a string by just returning the characters.
  44. def to_s
  45. chars
  46. end
  47.  
  48. # Split by dividing the string.
  49. def split_at(p)
  50. [ Leaf.new(chars[0...p]), Leaf.new(chars[p..-1]) ]
  51. end
  52. end
  53.  
  54. class Node < Rope
  55. # Fields of the binary node.
  56. attr_accessor :left, :right, :count
  57.  
  58. # Construct a new binary node.
  59. def initialize(left, right, count)
  60. @left = left
  61. @right = right
  62. @count = count
  63. end
  64.  
  65. # Length is our count plus right subtree length. Memoize for efficiency.
  66. def len
  67. @len ||= count + right.len
  68. end
  69.  
  70. # The string rep is just concatenating the children's string reps.
  71. def to_s
  72. left.to_s + right.to_s
  73. end
  74.  
  75. # Split recursively by splitting the left or right
  76. # subtree and recombining the results.
  77. def split_at(p)
  78. if p < count
  79. a, b = left.split_at(p)
  80. [ a, b.cat(right) ]
  81. elsif p > count
  82. a, b = right.split_at(p - count)
  83. [ left.cat(a), b ]
  84. else
  85. [ left, right ]
  86. end
  87. end
  88. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement