Reputation: 1779
I've got an array in Ruby that essentially represents a square boolean matrix. Dots represent zeroes, while any other character represents ones. Example:
irb(main):044:0> g
=> [".b", "m."] # This grid has two '1' values and two '0' values.
I'd like to perform a specified logical operation (say, OR) on this array with another similar array to get a third result. For example, if h
is ["q.", "r."]
, then something akin to g.perform_or(h)
should yield a new array ["qb", "r."]
. (The choice of r
to represent the result of 'm' || 'r'
is arbitrary and not relevant; any other non-'.' character can be there.)
How might I do this?
Edit: I made an error in my example. Apologies!
Upvotes: 0
Views: 513
Reputation: 369478
Man, this one has been gathering dust on my disk for a loong time:
class String
def to_bool; return chars.map {|c| if c == '.' then false else c end } end
def from_bool; return self end
end
class TrueClass; def from_bool; return 't' end end
class FalseClass; def from_bool; return '.' end end
class Array
def to_bool; map(&:to_bool) end
def from_bool; map {|row| row.map(&:from_bool).join} end
def |(other)
to_bool.zip(other.to_bool).inject([]) {|row, (l, r)|
row << l.zip(r).inject([]) {|col, (l, r)|
col << (l || r).from_bool
}
}
end
def &(other)
to_bool.zip(other.to_bool).inject([]) {|row, (l, r)|
row << l.zip(r).inject([]) {|col, (l, r)|
col << (l && r).from_bool
}
}
end
end
Here's a (rather incomplete) testsuite:
require 'test/unit'
class TestLogicMatrix < Test::Unit::TestCase
def test_to_bool
assert_equal [['a', false], [false, 'z']], ['a.', '.z'].to_bool
end
def test_from_bool
assert_equal ['a.', 'tz'], [['a', false], [true, 'z']].from_bool
end
def test_that_OR_works
assert_equal ['qb', 'm.'], (['.b', 'm.'] | ['q.', 'r.']).from_bool
end
def test_that_AND_works
assert_equal ['..', 'r.'], (['.b', 'm.'] & ['q.', 'r.']).from_bool
end
end
Upvotes: 0
Reputation: 15488
For OR:
g.zip(h).map {|gx,hx| (0...gx.size).map {|i| [gx[i..i],hx[i..i]].any? {|cell| cell != "."} ? "x" : "."}.join}
For AND just change the "any?" to "all?".
Upvotes: 6