1 # Copyright (C) 2007-2011 Martin A. Hansen.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # http://www.gnu.org/copyleft/gpl.html
19 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
21 # This software is part of the Biopieces framework (www.biopieces.org).
23 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
25 # Error class for all exceptions to do with String.
26 class StringError < StandardError; end
28 # Monkey patching Class String to add bitwise operators.
29 # Behaviour matching Perl's:
30 # http://perldoc.perl.org/perlop.html#Bitwise-String-Operators
32 # Method to that returns the case senstive Hamming Distance between two strings.
33 # http://en.wikipedia.org/wiki/Hamming_distance
34 def self.hamming_dist(str1, str2)
35 raise StringError, "Uneven string lengths: #{str1.length} != #{str2.length}" if str1.length != str2.length
36 (str1 ^ str2 ).count("\x01-\xff")
39 # Method that performs bitwise AND operation where bits
40 # are copied if they exists in BOTH operands. If the operand
41 # sizes are different, the & operator methods acts as though
42 # the longer operand were truncated to the length of the shorter.
46 (0 ... [self.length, str.length].min).each do |i|
47 new << (self[i].ord & str[i].ord)
53 # Method that performs bitwise OR operation where bits
54 # are copied if they exists in EITHER operands. If the operand
55 # sizes differ, the shorter operand is extended with the terminal
56 # part of the longer operand.
60 min = [self.length, str.length].min
62 (0 ... min).each do |i|
63 new << (self[i].ord | str[i].ord)
66 if self.length > str.length
67 new << self[min ... self.length]
68 elsif self.length < str.length
69 new << str[min ... str.length]
75 # Method that performs bitwise XOR operation where bits
76 # are copied if they exists in ONE BUT NOT BOTH operands.
80 (0 ... [self.length, str.length].min).each do |i|
81 new << (self[i].ord ^ str[i].ord)