Stephen Duncan Jr
4/15/2007 11:29:00 PM
Thanks for the tips. I did originally have all the string stuff in
to_s, but had decided to do it in the constructor to avoid
recalculating everything, since the formula wasn't modifiable. I've
implemented a compromise for now. Especially thanks for the mask tip,
I was troubling coming up with a clean way to generate the values.
-Stephen
On 4/15/07, james.d.masters@gmail.com <james.d.masters@gmail.com> wrote:
> On Apr 15, 9:21 am, "Stephen Duncan" <stephen.dun...@gmail.com> wrote:
> > I'd like to say I just whipped this up, but I'm still a Ruby-newbie,
> > so this took me a few days. I'd love to get some feedback on the
> > code...
>
> After looking at the code, it looks like the @string instance variable
> and the methods generate_values and get_next are used only once and
> are used for building a string representation of the truth table. I'd
> recommend doing away with these and do the calculation in to_s (this
> could open the possibility of changing the formula after object
> creation if you wanted to enhance this class to allow dynamic
> formulas). In any case, I would recommend counting through
> possibilities and using a bitwise mask to figure out the permutations
> instead of using the generate_values method:
>
> class TruthTable
> def initialize(formula, &expression)
> @formula = formula
> @expression = expression
> @variables = @formula.gsub(/[^[:alpha:]\s]/, " ").split.uniq
> @expression ||= eval("Proc.new {|#{@variables.join(',')}|
> #{formula} }")
> end
>
> def to_s
> # create a mask for each of the variables
> var_masks = (0..@variables.length-1).to_a.reverse.map {|i| 2**i}
>
> # create header
> str = @variables.join("\t") + "\t#{@formula}\n"
>
> # Go through all permutations of variables
> 0.upto(2**@variables.length-1) do |cnt_mask|
> # compare the count mask versus each variable mask - map as
> values
> values = var_masks.map {|var_mask| (var_mask & cnt_mask) ==
> var_mask}
> str += values.join("\t") + "\t#{@expression.call(*values)}" +
> "\n"
> end
>
> str
> end
> end
>
> As for the overall concept of this class, I did something similar a
> while back and used the same technique that you did - accept a string
> to allow a visual representation and then eval the formula within a
> Proc.new.
>
>
>
--
Stephen Duncan Jr
www.stephenduncanjr.com