0

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!

3
  • If '.' == 0 and /[^.]/ == 1, your example of an or function is wrong. Commented Nov 20, 2009 at 4:39
  • So, outside of the actual answer I'm curious about what you're doing with this? Sounds interesting! Commented Nov 20, 2009 at 5:40
  • If you change the problem statement, you waste the time of all those who tried to answer your question before you change it. Commented Nov 20, 2009 at 14:35

2 Answers 2

6

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?".

Sign up to request clarification or add additional context in comments.

3 Comments

I was trying to understand this and I'm not getting the same result as specified above. I'm getting ['xx', 'x.']. Even if you had transposed . and x it should look like ['xx', '.x']. Am I wrong about this?
Me too. It should actually look like ['..', 'x.']
glenn deserves a double bump then for finding the right answer and the right question :P
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.