From: martinahansen Date: Mon, 17 Oct 2011 19:34:22 +0000 (+0000) Subject: added more methods to bitarray.rb X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=990d0af5b6ffd27c9cb81dc7811dfbf077bebb26;p=biopieces.git added more methods to bitarray.rb git-svn-id: http://biopieces.googlecode.com/svn/trunk@1583 74ccb610-7750-0410-82ae-013aeee3265d --- diff --git a/code_ruby/lib/maasha/bitarray.rb b/code_ruby/lib/maasha/bitarray.rb index e65ab3c..1b2bc9e 100644 --- a/code_ruby/lib/maasha/bitarray.rb +++ b/code_ruby/lib/maasha/bitarray.rb @@ -155,6 +155,63 @@ class BitArray alias :to_string :to_s + # Method to set the bits to "on" in an interval in a bit array. + # Returns the number of bits set. + def interval_set(start, stop) + raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0 + raise BitArrayError, "interval stop > bit array size (#{stop} > #{self.size})" if stop > self.size + raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start + + (start ... stop).each do |pos| + self.bit_set(pos) + end + + stop - start + end + + # Method to set the bits to "off" in an interval in a bit array. + # Returns the number of bits unset. + def interval_unset(start, stop) + raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0 + raise BitArrayError, "interval stop > bit array size (#{stop} > #{self.size})" if stop > self.size + raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start + + (start ... stop).each do |pos| + self.bit_unset(pos) + end + + stop - start + end + + # Method to locate intervals of bits set to "on" in a bit array. + # BitArray.each_interval -> Array + # BitArray.each_interval { |start, stop| } -> Fixnum + def each_interval + intervals = [] + start = 0 + stop = 0 + + while start < self.size + if self.bit_set?(start) + stop = start + + while stop < self.size and self.bit_set?(stop) + stop += 1 + end + + if block_given? + yield start, stop + else + intervals << [start, stop] + end + end + + stop > start ? start = stop : start += 1 + end + + return intervals unless block_given? + end + private # Method to initialize the byte array (string) that constitutes the bit array. diff --git a/code_ruby/test/maasha/test_bitarray.rb b/code_ruby/test/maasha/test_bitarray.rb index 182ec27..6c410be 100755 --- a/code_ruby/test/maasha/test_bitarray.rb +++ b/code_ruby/test/maasha/test_bitarray.rb @@ -123,7 +123,7 @@ class TestBitArray < Test::Unit::TestCase @ba.bit_set(5) ba.bit_set(5) ba.bit_set(6) - assert_equal( "0000010000", (@ba & ba).to_s) + assert_equal("0000010000", (@ba & ba).to_s) end def test_BitArray_OR_with_uneven_sizes_raises @@ -137,7 +137,7 @@ class TestBitArray < Test::Unit::TestCase @ba.bit_set(5) ba.bit_set(5) ba.bit_set(6) - assert_equal( "0000111000", (@ba | ba).to_s) + assert_equal("0000111000", (@ba | ba).to_s) end def test_BitArray_XOR_with_uneven_sizes_raises @@ -151,14 +151,46 @@ class TestBitArray < Test::Unit::TestCase @ba.bit_set(5) ba.bit_set(5) ba.bit_set(6) - assert_equal( "0000101000", (@ba ^ ba).to_s) + assert_equal("0000101000", (@ba ^ ba).to_s) end def test_BitArray_FLIP_returns_correctly @ba.bit_set(0) @ba.bit_set(9) - assert_equal( "0111111110", (~@ba).to_s) + assert_equal("0111111110", (~@ba).to_s) + end + + def test_interval_set_with_bad_interval_raises + assert_raise(BitArrayError) { @ba.interval_set(-1, 4) } + assert_raise(BitArrayError) { @ba.interval_set(1, 14) } + assert_raise(BitArrayError) { @ba.interval_set(4, 2) } + end + + def test_interval_set_returns_correctly + @ba.interval_set(1, 9) + + assert_equal("0111111110", @ba.to_s) + end + + def test_interval_unset_with_bad_interval_raises + assert_raise(BitArrayError) { @ba.interval_unset(-1, 4) } + assert_raise(BitArrayError) { @ba.interval_unset(1, 14) } + assert_raise(BitArrayError) { @ba.interval_unset(4, 2) } + end + + def test_interval_unset_returns_correctly + ~@ba + @ba.interval_unset(1, 9) + + assert_equal("1000000001", @ba.to_s) + end + + def test_each_interval_returns_correctly + @ba.fill! + @ba.bit_unset(4) + + assert_equal([[0, 4], [5, 10]], @ba.each_interval.to_a) end end