compsci 0.1.1.1 → 0.2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +74 -5
- data/Rakefile +20 -9
- data/VERSION +1 -1
- data/compsci.gemspec +1 -0
- data/examples/binary_search_tree.rb +16 -0
- data/examples/heap.rb +0 -42
- data/examples/heap_push.rb +46 -0
- data/examples/tree.rb +2 -1
- data/examples/{binary_tree.rb → tree_push.rb} +3 -2
- data/lib/compsci/binary_search_tree.rb +86 -0
- data/lib/compsci/fibonacci.rb +1 -9
- data/lib/compsci/fit.rb +34 -14
- data/lib/compsci/names.rb +3 -4
- data/lib/compsci/node.rb +66 -19
- data/lib/compsci/simplex.rb +173 -0
- data/lib/compsci/simplex/parse.rb +125 -0
- data/lib/compsci/tree.rb +14 -1
- data/test/bench/complete_tree.rb +59 -0
- data/test/bench/fibonacci.rb +0 -4
- data/test/bench/simplex.rb +141 -0
- data/test/bench/tree.rb +20 -15
- data/test/binary_search_tree.rb +106 -0
- data/test/fit.rb +5 -11
- data/test/node.rb +55 -4
- data/test/simplex.rb +291 -0
- data/test/simplex_parse.rb +94 -0
- data/test/tree.rb +33 -9
- metadata +27 -3
    
        data/test/simplex.rb
    ADDED
    
    | @@ -0,0 +1,291 @@ | |
| 1 | 
            +
            require 'minitest/autorun'
         | 
| 2 | 
            +
            require 'compsci/simplex'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            include CompSci
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class SimplexTest < Minitest::Test
         | 
| 7 | 
            +
              def test_2x2
         | 
| 8 | 
            +
                result = Simplex.new(
         | 
| 9 | 
            +
                  [1, 1],
         | 
| 10 | 
            +
                  [
         | 
| 11 | 
            +
                    [ 2,  1],
         | 
| 12 | 
            +
                    [ 1,  2],
         | 
| 13 | 
            +
                  ],
         | 
| 14 | 
            +
                  [4, 3]
         | 
| 15 | 
            +
                ).solution
         | 
| 16 | 
            +
                assert_equal [Rational(5, 3), Rational(2, 3)], result
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def test_2x2_b
         | 
| 20 | 
            +
                result = Simplex.new(
         | 
| 21 | 
            +
                  [3, 4],
         | 
| 22 | 
            +
                  [
         | 
| 23 | 
            +
                    [ 1,  1],
         | 
| 24 | 
            +
                    [ 2,  1],
         | 
| 25 | 
            +
                  ],
         | 
| 26 | 
            +
                  [4, 5]
         | 
| 27 | 
            +
                ).solution
         | 
| 28 | 
            +
                assert_equal [0, 4], result
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              def test_2x2_c
         | 
| 32 | 
            +
                result = Simplex.new(
         | 
| 33 | 
            +
                  [2, -1],
         | 
| 34 | 
            +
                  [
         | 
| 35 | 
            +
                    [ 1,  2],
         | 
| 36 | 
            +
                    [ 3,  2],
         | 
| 37 | 
            +
                  ],
         | 
| 38 | 
            +
                  [6, 12]
         | 
| 39 | 
            +
                ).solution
         | 
| 40 | 
            +
                assert_equal [4, 0], result
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              def test_3x3_a
         | 
| 44 | 
            +
                result = Simplex.new(
         | 
| 45 | 
            +
                  [60, 90, 300],
         | 
| 46 | 
            +
                  [
         | 
| 47 | 
            +
                    [1, 1, 1],
         | 
| 48 | 
            +
                    [1, 3, 0],
         | 
| 49 | 
            +
                    [2, 0, 1]
         | 
| 50 | 
            +
                  ],
         | 
| 51 | 
            +
                  [600, 600, 900]
         | 
| 52 | 
            +
                ).solution
         | 
| 53 | 
            +
                assert_equal [0, 0, 600], result
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              def test_3x3_b
         | 
| 57 | 
            +
                result = Simplex.new(
         | 
| 58 | 
            +
                  [70, 210, 140],
         | 
| 59 | 
            +
                  [
         | 
| 60 | 
            +
                    [ 1,  1,  1],
         | 
| 61 | 
            +
                    [ 5,  4,  4],
         | 
| 62 | 
            +
                    [40, 20, 30]
         | 
| 63 | 
            +
                  ],
         | 
| 64 | 
            +
                  [100, 480, 3200]
         | 
| 65 | 
            +
                ).solution
         | 
| 66 | 
            +
                assert_equal [0, 100, 0], result
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              def test_3x3_c
         | 
| 70 | 
            +
                result = Simplex.new(
         | 
| 71 | 
            +
                  [2, -1, 2],
         | 
| 72 | 
            +
                  [
         | 
| 73 | 
            +
                    [ 2,  1,  0],
         | 
| 74 | 
            +
                    [ 1,  2, -2],
         | 
| 75 | 
            +
                    [ 0,  1,  2]
         | 
| 76 | 
            +
                  ],
         | 
| 77 | 
            +
                  [10, 20, 5]
         | 
| 78 | 
            +
                ).solution
         | 
| 79 | 
            +
                assert_equal [5, 0, Rational(5, 2)], result
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              def test_3x3_d
         | 
| 83 | 
            +
                result = Simplex.new(
         | 
| 84 | 
            +
                  [11, 16, 15],
         | 
| 85 | 
            +
                  [
         | 
| 86 | 
            +
                    [             1,              2, Rational(3, 2)],
         | 
| 87 | 
            +
                    [Rational(2, 3), Rational(2, 3),              1],
         | 
| 88 | 
            +
                    [Rational(1, 2), Rational(1, 3), Rational(1, 2)]
         | 
| 89 | 
            +
                  ],
         | 
| 90 | 
            +
                  [12_000, 4_600, 2_400]
         | 
| 91 | 
            +
                ).solution
         | 
| 92 | 
            +
                assert_equal [600, 5_100, 800], result
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
              def test_3x3_e
         | 
| 96 | 
            +
                simplex = Simplex.new(
         | 
| 97 | 
            +
                  [5, 4, 3],
         | 
| 98 | 
            +
                  [
         | 
| 99 | 
            +
                    [2, 3, 1],
         | 
| 100 | 
            +
                    [4, 1, 2],
         | 
| 101 | 
            +
                    [3, 4, 2]
         | 
| 102 | 
            +
                  ],
         | 
| 103 | 
            +
                  [5, 11, 8]
         | 
| 104 | 
            +
                )
         | 
| 105 | 
            +
                assert_equal [2, 0, 1], simplex.solution
         | 
| 106 | 
            +
              end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
              def test_3x3_f
         | 
| 109 | 
            +
                simplex = Simplex.new(
         | 
| 110 | 
            +
                  [3, 2, -4],
         | 
| 111 | 
            +
                  [
         | 
| 112 | 
            +
                    [1, 4, 0],
         | 
| 113 | 
            +
                    [2, 4,-2],
         | 
| 114 | 
            +
                    [1, 1,-2]
         | 
| 115 | 
            +
                  ],
         | 
| 116 | 
            +
                  [5, 6, 2]
         | 
| 117 | 
            +
                )
         | 
| 118 | 
            +
                assert_equal [4, 0, 1], simplex.solution
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              def test_3x3_g
         | 
| 122 | 
            +
                simplex = Simplex.new(
         | 
| 123 | 
            +
                  [2, -1, 8],
         | 
| 124 | 
            +
                  [
         | 
| 125 | 
            +
                    [2, -4, 6],
         | 
| 126 | 
            +
                    [-1, 3, 4],
         | 
| 127 | 
            +
                    [0, 0, 2]
         | 
| 128 | 
            +
                  ],
         | 
| 129 | 
            +
                  [3, 2, 1]
         | 
| 130 | 
            +
                )
         | 
| 131 | 
            +
                assert_equal [Rational(17, 2), Rational(7,2), 0], simplex.solution
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              def test_3x4
         | 
| 135 | 
            +
                result = Simplex.new(
         | 
| 136 | 
            +
                  [100_000, 40_000, 18_000],
         | 
| 137 | 
            +
                  [
         | 
| 138 | 
            +
                    [20, 6, 3],
         | 
| 139 | 
            +
                    [ 0, 1, 0],
         | 
| 140 | 
            +
                    [-1,-1, 1],
         | 
| 141 | 
            +
                    [-9, 1, 1]
         | 
| 142 | 
            +
                  ],
         | 
| 143 | 
            +
                  [182, 10, 0, 0]
         | 
| 144 | 
            +
                ).solution
         | 
| 145 | 
            +
                assert_equal [4, 10, 14], result
         | 
| 146 | 
            +
              end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
              def test_4x4
         | 
| 149 | 
            +
                result = Simplex.new(
         | 
| 150 | 
            +
                  [1, 2, 1, 2],
         | 
| 151 | 
            +
                  [
         | 
| 152 | 
            +
                    [1, 0, 1, 0],
         | 
| 153 | 
            +
                    [0, 1, 0, 1],
         | 
| 154 | 
            +
                    [1, 1, 0, 0],
         | 
| 155 | 
            +
                    [0, 0, 1, 1]
         | 
| 156 | 
            +
                  ],
         | 
| 157 | 
            +
                  [1, 4, 2, 2]
         | 
| 158 | 
            +
                ).solution
         | 
| 159 | 
            +
                assert_equal [0, 2, 0, 2], result
         | 
| 160 | 
            +
              end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              def test_cycle
         | 
| 163 | 
            +
                result = Simplex.new(
         | 
| 164 | 
            +
                  [10, -57, -9, -24],
         | 
| 165 | 
            +
                  [
         | 
| 166 | 
            +
                    [0.5, -5.5, -2.5, 9],
         | 
| 167 | 
            +
                    [0.5, -1.5, -0.5, 1],
         | 
| 168 | 
            +
                    [  1,    0,    0, 0]
         | 
| 169 | 
            +
                  ],
         | 
| 170 | 
            +
                  [0, 0, 1]
         | 
| 171 | 
            +
                ).solution
         | 
| 172 | 
            +
                assert_equal [1, 0, 1, 0], result
         | 
| 173 | 
            +
              end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
              def test_cycle2
         | 
| 176 | 
            +
                simplex = Simplex.new(
         | 
| 177 | 
            +
                  [2, 3, -1, -12],
         | 
| 178 | 
            +
                  [
         | 
| 179 | 
            +
                    [-2, -9, 1, 9],
         | 
| 180 | 
            +
                    [Rational(1, 3), 1, Rational(-1, 3), -2],
         | 
| 181 | 
            +
                  ],
         | 
| 182 | 
            +
                  [0, 0]
         | 
| 183 | 
            +
                )
         | 
| 184 | 
            +
                assert_raises Simplex::UnboundedProblem do
         | 
| 185 | 
            +
                  simplex.solution
         | 
| 186 | 
            +
                end
         | 
| 187 | 
            +
              end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
              def test_error_mismatched_dimensions
         | 
| 190 | 
            +
                assert_raises ArgumentError do
         | 
| 191 | 
            +
                  Simplex.new(
         | 
| 192 | 
            +
                    [10, -57, -9],
         | 
| 193 | 
            +
                    [
         | 
| 194 | 
            +
                      [0.5, -5.5, -2.5, 9],
         | 
| 195 | 
            +
                      [0.5, -1.5, -0.5, 1],
         | 
| 196 | 
            +
                      [  1,    0,    0, 0]
         | 
| 197 | 
            +
                    ],
         | 
| 198 | 
            +
                    [0, 0, 1]
         | 
| 199 | 
            +
                  )
         | 
| 200 | 
            +
                end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                assert_raises ArgumentError do
         | 
| 203 | 
            +
                  Simplex.new(
         | 
| 204 | 
            +
                    [10, -57, -9, 2],
         | 
| 205 | 
            +
                    [
         | 
| 206 | 
            +
                      [0.5, -5.5, 9, 4],
         | 
| 207 | 
            +
                      [0.5, -1.5, 1],
         | 
| 208 | 
            +
                      [  1,    0, 0]
         | 
| 209 | 
            +
                    ],
         | 
| 210 | 
            +
                    [0, 0, 1]
         | 
| 211 | 
            +
                  )
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                assert_raises ArgumentError do
         | 
| 215 | 
            +
                  Simplex.new(
         | 
| 216 | 
            +
                    [10, -57, -9, 2],
         | 
| 217 | 
            +
                    [
         | 
| 218 | 
            +
                      [0.5, -5.5, 9, 4],
         | 
| 219 | 
            +
                      [0.5, -1.5, 1, 5],
         | 
| 220 | 
            +
                      [  1,    0, 0, 5]
         | 
| 221 | 
            +
                    ],
         | 
| 222 | 
            +
                    [0, 1]
         | 
| 223 | 
            +
                  )
         | 
| 224 | 
            +
                end
         | 
| 225 | 
            +
              end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
              def test_manual_iteration
         | 
| 228 | 
            +
                simplex = Simplex.new(
         | 
| 229 | 
            +
                  [10, -57, -9, -24],
         | 
| 230 | 
            +
                  [
         | 
| 231 | 
            +
                    [0.5, -5.5, -2.5, 9],
         | 
| 232 | 
            +
                    [0.5, -1.5, -0.5, 1],
         | 
| 233 | 
            +
                    [  1,    0,    0, 0]
         | 
| 234 | 
            +
                  ],
         | 
| 235 | 
            +
                  [0, 0, 1]
         | 
| 236 | 
            +
                )
         | 
| 237 | 
            +
                while simplex.can_improve?
         | 
| 238 | 
            +
                  assert simplex.formatted_tableau.is_a?(String)
         | 
| 239 | 
            +
                  simplex.pivot
         | 
| 240 | 
            +
                end
         | 
| 241 | 
            +
                result = simplex.solution
         | 
| 242 | 
            +
                assert_equal [1, 0, 1, 0], result
         | 
| 243 | 
            +
              end
         | 
| 244 | 
            +
             | 
| 245 | 
            +
              def test_cup_factory
         | 
| 246 | 
            +
                result = Simplex.new(
         | 
| 247 | 
            +
                  [25, 20],
         | 
| 248 | 
            +
                  [
         | 
| 249 | 
            +
                    [20, 12],
         | 
| 250 | 
            +
                    [1, 1]
         | 
| 251 | 
            +
                  ],
         | 
| 252 | 
            +
                  [1800, 8*15]
         | 
| 253 | 
            +
                )
         | 
| 254 | 
            +
                assert_equal [45, 75], result.solution
         | 
| 255 | 
            +
              end
         | 
| 256 | 
            +
             | 
| 257 | 
            +
              #def test_infeasible1
         | 
| 258 | 
            +
              #  simplex = Simplex.new(
         | 
| 259 | 
            +
              #    [2, -1],
         | 
| 260 | 
            +
              #    [
         | 
| 261 | 
            +
              #      [1, -1],
         | 
| 262 | 
            +
              #      [-1, 1]
         | 
| 263 | 
            +
              #    ],
         | 
| 264 | 
            +
              #    [1, -2]
         | 
| 265 | 
            +
              #  )
         | 
| 266 | 
            +
              #  while simplex.can_improve?
         | 
| 267 | 
            +
              #    puts
         | 
| 268 | 
            +
              #    puts simplex.formatted_tableau
         | 
| 269 | 
            +
              #    simplex.pivot
         | 
| 270 | 
            +
              #  end
         | 
| 271 | 
            +
              #  p :done
         | 
| 272 | 
            +
              #  puts
         | 
| 273 | 
            +
              #  puts simplex.formatted_tableau
         | 
| 274 | 
            +
             | 
| 275 | 
            +
              #end
         | 
| 276 | 
            +
             | 
| 277 | 
            +
              def test_unbounded
         | 
| 278 | 
            +
                simplex = Simplex.new(
         | 
| 279 | 
            +
                  [1, 1, 1],
         | 
| 280 | 
            +
                  [
         | 
| 281 | 
            +
                    [3, 1, -2],
         | 
| 282 | 
            +
                    [4, 3, 0]
         | 
| 283 | 
            +
                  ],
         | 
| 284 | 
            +
                  [5, 7]
         | 
| 285 | 
            +
                )
         | 
| 286 | 
            +
                assert_raises Simplex::UnboundedProblem do
         | 
| 287 | 
            +
                  simplex.solution
         | 
| 288 | 
            +
                end
         | 
| 289 | 
            +
              end
         | 
| 290 | 
            +
             | 
| 291 | 
            +
            end
         | 
| @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            require 'compsci/simplex/parse'
         | 
| 2 | 
            +
            require 'minitest/autorun'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            include CompSci
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            describe Simplex::Parse do
         | 
| 7 | 
            +
              P = Simplex::Parse
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              describe "Parse.term" do
         | 
| 10 | 
            +
                it "must parse valid terms" do
         | 
| 11 | 
            +
                  { "-1.2A" => [-1.2, :A],
         | 
| 12 | 
            +
                    "99x"   => [99.0, :x],
         | 
| 13 | 
            +
                    "z"     => [ 1.0, :z],
         | 
| 14 | 
            +
                    "-b"    => [-1.0, :b] }.each { |valid, expected|
         | 
| 15 | 
            +
                    P.term(valid).must_equal expected
         | 
| 16 | 
            +
                  }
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                it "must reject invalid terms" do
         | 
| 20 | 
            +
                  ["3xy", "24/7x", "x17", "2*x"].each { |invalid|
         | 
| 21 | 
            +
                    proc { P.term(invalid) }.must_raise RuntimeError
         | 
| 22 | 
            +
                  }
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              describe "Parse.expression" do
         | 
| 27 | 
            +
                it "must parse valid expressions" do
         | 
| 28 | 
            +
                  { "x + y"             => { x:  1.0, y:  1.0 },
         | 
| 29 | 
            +
                    "2x - 5y"           => { x:  2.0, y: -5.0 },
         | 
| 30 | 
            +
                    "-2x - 3y + -42.7z" => { x: -2.0, y: -3.0, z: -42.7 },
         | 
| 31 | 
            +
                    " -5y + -x  "       => { y: -5.0, x: -1.0 },
         | 
| 32 | 
            +
                    "a - -b"            => { a:  1.0, b:  1.0 },
         | 
| 33 | 
            +
                    "a A b"             => { a:  1.0, :A => 1.0, b: 1.0 },
         | 
| 34 | 
            +
                  }.each { |valid, expected|
         | 
| 35 | 
            +
                    P.expression(valid).must_equal expected
         | 
| 36 | 
            +
                  }
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                it "must reject invalid expressions" do
         | 
| 40 | 
            +
                  ["a2 + b2 = c2",
         | 
| 41 | 
            +
                   "x + xy",
         | 
| 42 | 
            +
                   "x * 2"].each { |invalid|
         | 
| 43 | 
            +
                    proc { P.expression(invalid) }.must_raise P::Error
         | 
| 44 | 
            +
                  }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              describe "Parse.tokenize" do
         | 
| 49 | 
            +
                it "ignores leading or trailing whitespace" do
         | 
| 50 | 
            +
                  P.tokenize("  5x + 2.9y ").must_equal ["5x", "+", "2.9y"]
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                it "ignores multiple spaces" do
         | 
| 54 | 
            +
                  P.tokenize("5x   +   2.9y").must_equal ["5x", "+", "2.9y"]
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              describe "Parse.inequality" do
         | 
| 59 | 
            +
                it "must parse valid inequalities" do
         | 
| 60 | 
            +
                  { "x + y <= 4"              => [{ x: 1.0, y: 1.0 }, 4.0],
         | 
| 61 | 
            +
                    "0.94a - 22.1b <= -14.67" => [{ a: 0.94, b: -22.1 }, -14.67],
         | 
| 62 | 
            +
                    "x <= 0"                  => [{ x: 1.0 }, 0],
         | 
| 63 | 
            +
                  }.each { |valid, expected|
         | 
| 64 | 
            +
                    P.inequality(valid).must_equal expected
         | 
| 65 | 
            +
                  }
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                it "must reject invalid inequalities" do
         | 
| 69 | 
            +
                  ["x + y >= 4",
         | 
| 70 | 
            +
                   "0.94a - 22.1b <= -14.67c",
         | 
| 71 | 
            +
                   "x < 0",
         | 
| 72 | 
            +
                  ].each { |invalid|
         | 
| 73 | 
            +
                    proc { P.inequality(invalid) }.must_raise P::Error
         | 
| 74 | 
            +
                  }
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            describe "Simplex.maximize" do
         | 
| 80 | 
            +
              it "must problem stuff" do
         | 
| 81 | 
            +
                prob = Simplex.problem(maximize: 'x + y',
         | 
| 82 | 
            +
                                       constraints: ['2x + y <= 4',
         | 
| 83 | 
            +
                                                     'x + 2y <= 3'])
         | 
| 84 | 
            +
                sol = prob.solution
         | 
| 85 | 
            +
                sol.must_equal [Rational(5, 3), Rational(2, 3)]
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              it "must maximize stuff" do
         | 
| 89 | 
            +
                Simplex.maximize('x + y',
         | 
| 90 | 
            +
                                 '2x + y <= 4',
         | 
| 91 | 
            +
                                 'x + 2y <= 3').must_equal [Rational(5, 3),
         | 
| 92 | 
            +
                                                            Rational(2, 3)]
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
            end
         | 
    
        data/test/tree.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            require 'compsci/node'
         | 
| 1 2 | 
             
            require 'compsci/tree'
         | 
| 2 3 | 
             
            require 'minitest/autorun'
         | 
| 3 4 |  | 
| @@ -5,7 +6,7 @@ include CompSci | |
| 5 6 |  | 
| 6 7 | 
             
            describe Tree do
         | 
| 7 8 | 
             
              before do
         | 
| 8 | 
            -
                @tree = Tree.new( | 
| 9 | 
            +
                @tree = Tree.new(FlexNode, 42)
         | 
| 9 10 | 
             
                @vals = Array.new(99) { rand 99 }
         | 
| 10 11 | 
             
              end
         | 
| 11 12 |  | 
| @@ -16,7 +17,7 @@ describe Tree do | |
| 16 17 |  | 
| 17 18 | 
             
              it "does depth_first search" do
         | 
| 18 19 | 
             
                vals = (0..30).to_a
         | 
| 19 | 
            -
                tree = Tree.new( | 
| 20 | 
            +
                tree = Tree.new(FlexNode, vals.shift)
         | 
| 20 21 | 
             
                tree.root.new_child vals.shift
         | 
| 21 22 | 
             
                tree.root.new_child vals.shift
         | 
| 22 23 | 
             
                tree.root.children.each { |c|
         | 
| @@ -40,7 +41,7 @@ describe Tree do | |
| 40 41 |  | 
| 41 42 | 
             
              it "does breadth_first search" do
         | 
| 42 43 | 
             
                vals = (0..30).to_a
         | 
| 43 | 
            -
                tree = Tree.new( | 
| 44 | 
            +
                tree = Tree.new(FlexNode, vals.shift)
         | 
| 44 45 | 
             
                tree.root.new_child vals.shift
         | 
| 45 46 | 
             
                tree.root.new_child vals.shift
         | 
| 46 47 | 
             
                tree.root.children.each { |c|
         | 
| @@ -64,9 +65,32 @@ describe Tree do | |
| 64 65 | 
             
            end
         | 
| 65 66 |  | 
| 66 67 | 
             
            describe NaryTree do
         | 
| 67 | 
            -
               | 
| 68 | 
            +
              it "must power_of?" do
         | 
| 69 | 
            +
                powers = {}
         | 
| 70 | 
            +
                basemax = 12
         | 
| 71 | 
            +
                expmax = 10
         | 
| 72 | 
            +
                2.upto(basemax) { |base|
         | 
| 73 | 
            +
                  0.upto(expmax) { |exp|
         | 
| 74 | 
            +
                    powers[base] ||= []
         | 
| 75 | 
            +
                    powers[base] << base**exp
         | 
| 76 | 
            +
                  }
         | 
| 77 | 
            +
                }
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                # 12k assertions below!
         | 
| 80 | 
            +
                2.upto(basemax) { |base|
         | 
| 81 | 
            +
                  1.upto(2**expmax) { |num|
         | 
| 82 | 
            +
                    if powers[base].include?(num)
         | 
| 83 | 
            +
                      NaryTree.power_of?(num, base).must_equal true
         | 
| 84 | 
            +
                    else
         | 
| 85 | 
            +
                      NaryTree.power_of?(num, base).must_equal false
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                  }
         | 
| 88 | 
            +
                }
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              describe "with FlexNode" do
         | 
| 68 92 | 
             
                before do
         | 
| 69 | 
            -
                  @tree = NaryTree.new( | 
| 93 | 
            +
                  @tree = NaryTree.new(FlexNode, 42, child_slots: 3)
         | 
| 70 94 | 
             
                end
         | 
| 71 95 |  | 
| 72 96 | 
             
                it "must have an open parent" do
         | 
| @@ -82,9 +106,9 @@ describe NaryTree do | |
| 82 106 | 
             
                end
         | 
| 83 107 | 
             
              end
         | 
| 84 108 |  | 
| 85 | 
            -
              describe "with  | 
| 109 | 
            +
              describe "with ChildFlexNode" do
         | 
| 86 110 | 
             
                before do
         | 
| 87 | 
            -
                  @tree = NaryTree.new( | 
| 111 | 
            +
                  @tree = NaryTree.new(ChildFlexNode, 42, child_slots: 4)
         | 
| 88 112 | 
             
                end
         | 
| 89 113 |  | 
| 90 114 | 
             
                it "must have an open parent" do
         | 
| @@ -103,7 +127,7 @@ end | |
| 103 127 |  | 
| 104 128 | 
             
            describe "BinaryTree" do
         | 
| 105 129 | 
             
              before do
         | 
| 106 | 
            -
                @tree = BinaryTree.new( | 
| 130 | 
            +
                @tree = BinaryTree.new(FlexNode, 42)
         | 
| 107 131 | 
             
              end
         | 
| 108 132 |  | 
| 109 133 | 
             
              it "must have 2 child_slots" do
         | 
| @@ -121,7 +145,7 @@ describe "BinaryTree" do | |
| 121 145 |  | 
| 122 146 | 
             
              describe "searching" do
         | 
| 123 147 | 
             
                before do
         | 
| 124 | 
            -
                  @tree = NaryTree.new( | 
| 148 | 
            +
                  @tree = NaryTree.new(FlexNode, 42, child_slots: 2)
         | 
| 125 149 | 
             
                  99.times { |i| @tree.push i }
         | 
| 126 150 | 
             
                end
         | 
| 127 151 |  |