From: Stephen Duncan Date: 2007-04-16T08:28:42+09:00 Subject: Re: Ruby Truth Table Generator 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 wrote: > On Apr 15, 9:21 am, "Stephen Duncan" 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