# Re: Counting Cards (#152)

**URL:** <https://www.ruby-forum.com/t/re-counting-cards-152/125939>\
**Category:** Ruby\
**Created:** [January 14, 2008, 12:32am UTC](https://www.ruby-forum.com/t/re-counting-cards-152/125939 "2008-01-14T00:32:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jameskelly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jameskelly](https://www.ruby-forum.com/u/jameskelly)\
**Post date:** [January 14, 2008, 12:32am UTC](https://www.ruby-forum.com/t/re-counting-cards-152/125939/1 "2008-01-14T00:32:59Z")

</div>

I opted to take the lazy route this time, and just print out the names  
of the cards. However, I did leave in code for another counting system.

(Before anyone critiques the presence of cartesian\_product, I am well  
aware of Array#product; I just haven’t gotten around to upgrading to 1.9  
yet.)

####Usage: ruby cardcounting.rb

COUNT\_QUERY\_CHANCE = 0.2

CARDS = %w[Deuce Three Four Five Six Seven Eight Nine Ten  
Jack Queen King Ace]  
SUITS = %w[Hearts Clubs Spades Diamonds]

def cartesian\_product(first, \*rest)  
return first if rest == []  
rest = cartesian\_product(\*rest)  
combs = block\_given? ? nil : []  
first.each do |v1|  
rest.each do |v2|  
if block\_given?  
yield v1+v2  
else  
combs \<\< (v1 + v2)  
end  
end  
end  
combs  
end

class Array  
def sum  
self.inject(0){|s,n|s+n}  
end  
end

###Knock-out systen  
count\_cards = proc do |decks, seen|  
vals = {“Deuce”=\>1,“Three”=\>1,“Four”=\>1,“Five”=\>1,“Six”=\>1,  
“Seven”=\>1,“Eight”=\>0,“Nine”=\>0,“Ten”=\>-1,“Jack”=\>-1,  
“Queen”=\>-1,“King”=\>-1,“Ace”=\>-1}  
init\_val = 4-4\*decks  
init\_val + seen.map{|s|vals[s.split.first]}.sum  
end

###Hi-lo systen  
#~ count\_cards = proc do |decks, seen|  
#~ vals = {“Deuce”=\>1,“Three”=\>1,“Four”=\>1,“Five”=\>1,“Six”=\>1,  
#~ “Seven”=\>1,“Eight”=\>1,“Nine”=\>0,“Ten”=\>-1,“Jack”=\>-1,  
#~ “Queen”=\>-1,“King”=\>-1,“Ace”=\>-1}  
#~ init\_val = 0  
#~ init\_val + seen.map{|s|vals[s.split.first]}.sum  
#~ end

time, simul\_display, decks = ARGV.map{|el|el.to\_f}

deck =  
([nil]\*decks).map{cartesian\_product(CARDS.map{|el|[el]},SUITS.map{|el|[el]}).  
map{|(c,s)|“#{c} of #{s}”}}.flatten.sort\_by{rand}

seen = []  
delay = time/(deck.length.to\_f/simul\_display)

(deck.length.to\_f/simul\_display).ceil.times do  
puts “\n”\*100  
puts deck[0…simul\_display]  
seen += deck.slice!(0…simul\_display)  
sleep delay  
if rand \< COUNT\_QUERY\_CHANCE  
print “Current count=?”  
response = $stdin.gets.to\_i  
if response == (cnt=count\_cards.call(decks,seen))  
puts “Correct”  
else  
puts “Incorrect: Correct is #{cnt}”  
end  
sleep delay/2  
end  
end

```
  ____________________________________________________________________________________

```

Be a better friend, newshound, and  
know-it-all with Yahoo! Mobile. Try it now.  
[http://mobile.yahoo.com/;\_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ](http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ)

---

<div class="post-metadata">

**Author:** ![jameskelly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jameskelly](https://www.ruby-forum.com/u/jameskelly)\
**Post date:** [January 14, 2008, 1:07am UTC](https://www.ruby-forum.com/t/re-counting-cards-152/125939/2 "2008-01-14T01:07:20Z")

</div>

James K. wrote:

> I opted to take the lazy route this time, and just print out the names  
> of the cards. However, I did leave in code for another counting system.
> 
> (Before anyone critiques the presence of cartesian\_product, I am well  
> aware of Array#product; I just haven’t gotten around to upgrading to 1.9  
> yet.)

(…)

> def cartesian\_product(first, \*rest)  
> return first if rest == []  
> rest = cartesian\_product(\*rest)  
> combs = block\_given? ? nil : []  
> first.each do |v1|  
> rest.each do |v2|  
> if block\_given?  
> yield v1+v2  
> else  
> combs \<\< (v1 + v2)  
> end  
> end  
> end  
> combs  
> end

(…)  
Your code resulted in this error: “card\_count\_trainer1.rb:50:in `\*': no  
implicit conversion from nil to integer (TypeError)”

Cartesian products were discussed recently in  
[Cartesian product of arrays - Ruby - Ruby-Forum](http://www.ruby-forum.com/topic/95519) . William J. came up with the  
remarkable

def cart\_prod( \*args )  
args.inject([[]]){|old,lst|  
new = []  
lst.each{|e| new += old.map{|c| c.dup \<\< e }}  
new  
}  
end

wich is included in my personal “wow.rb”.

regards,

Siep
