From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2003-07-19T04:05:39+09:00 Subject: [SNIPPET] Binary counter I needed to test a class which had a certain number of 'binary' inputs (ie. each input takes either 0 or 1 (or false or true) ). In order to do this I needed to try out every possible combination of inputs - essentially a binary count, like: 0,0,0,0 0,0,0,1 .... 1,1,1,0 1,1,1,1 I figured I could just increment an integer and, then convert it to binary, but: 1) there doesn't seem to be a builtin to_bin method on FixNum. 2) I'd still have to deal with indexing, etc. (OK, it wouldn't be that hard to implement #1 and #2 is not that hard either, but I decided to go a different route for fun ;-) So I made a BinCounter class and I present it here in case anyone else has need for it: class BinaryCounter attr_reader :bin def initialize(num_bits, tv=1,fv=0) @trueval = tv @falseval = fv @bin = Array.new(num_bits,@falseval) end def bincount(array=@bin,&block) recurse(array,0,@falseval,&block) recurse(array,0,@trueval,&block) end private def recurse(array,idx,val,&block) if idx == array.length yield array if val == @falseval && block_given? return end array[idx] = val recurse(array,idx+1,@falseval,&block) recurse(array,idx+1,@trueval,&block) end end bc = BinaryCounter.new(4) bc.bincount { |array| p array } #end Which produces: [0, 0, 0, 0] [0, 0, 0, 1] .... [1, 1, 1, 0] [1, 1, 1, 1] ....it's also possible to change the values, like: bc = BinaryCounter.new(2,'cat','dog') bc.bincount { |array| p array } which produces: ["dog", "dog"] ["dog", "cat"] ["cat", "dog"] ["cat", "cat"] ....well, I suppose if you're a 'dog person' you'll want to swap it: ["cat", "cat"] ["cat", "dog"] ["dog", "cat"] ["dog", "dog"] Hmmm.... Crazy idea: One could use code generation to create N'ary counter classes where N is the number of values that each slot could take. Phil