Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Bingo Challenge

by Matts (Deacon)
on May 19, 2002 at 15:34 UTC ( #167664=perlquestion: print w/ replies, xml ) Need Help??
Matts has asked for the wisdom of the Perl Monks concerning the following question:

OK, here's a challenge for a budding perl programmer...

Given a 4x4 grid (i.e. 16 squares) that represent a bingo card, and given that you can win with a row in any direction or diagonal, the 4 corners, or ultimately with "BINGO" - all 16 squares, what is the minimum number of numbers you need to guarantee the following things:

1. Each card can win

2. Each card is unique (discounting ordering)

For extra kudos, generate the cards (ascii art is fine).

(note this isn't a college question - I'm trying to do this myself too (and other monks can confirm I'm no a student) - I was just curious as to what other solutions people come up with)

Comment on Bingo Challenge
•Re: Bingo Challenge
by merlyn (Sage) on May 19, 2002 at 15:42 UTC
Re: Bingo Challenge
by Matts (Deacon) on May 19, 2002 at 15:53 UTC
    Duh!

    I just realised that of course every card can win! So the only challenge is how to produce a set of unique cards, and the only input needs to be the number of cards.

    Please delete the above node :-(

Re: Bingo Challenge
by Matts (Deacon) on May 19, 2002 at 16:29 UTC
    I feel so dumb. I thought this was a tough one to figure out. So anyway, I went ahead and wrote a script that generates nice PDF bingo cards:
    #!/usr/bin/perl -w use strict; use PDFLib; my @words = <DATA>; chomp @words; warn("got @words\n"); my $cards = shift @ARGV || die "Must supply number of cards\n"; print "Making $cards bingo cards\n"; my $pdf = PDFLib->new( filename => "bingo.pdf", papersize => "a4", creator => "Matt Sergeant", author => "Heather Sergeant", title => "Bingo!", ); foreach my $i (1..$cards) { my %seen; print "Card $i\n"; $pdf->start_page; $pdf->set_font(face => "Helvetica", size => 30, bold => 1); $pdf->print_boxed("Bingo!", mode => "center", x => 0, y => 740, w +=> 595, h => 50); $pdf->rect(x => 100, y => 200, w => 400, h => 400); $pdf->stroke; $pdf->set_font(face => "Helvetica", size => 20, bold => 0); for my $x (1..4) { for my $y (1..4) { my $word; while (1) { my $index = rand(@words); $word = $words[$index]; if (!$seen{$word}) { $seen{$word}++; last; } } $pdf->print_boxed($word, mode => "center", x => (100 + (($ +x - 1) * 100)), y => (160 + (($y - 1) * 100)), w => 100, h => 100); if ($y != 1) { $pdf->move_to( 100, (200 + (($y - 1) * 100)) ); $pdf->line_to( 500, (200 + (($y - 1) * 100)) ); $pdf->stroke; } } if ($x != 1) { $pdf->move_to( (100 + (($x - 1) * 100)), 200 ); $pdf->line_to( (100 + (($x - 1) * 100)), 600 ); $pdf->stroke; } } } $pdf->finish; 1; __DATA__ WORDS HERE
    Fill the DATA section with the things you want on the bingo card (maybe it's just numbers, in my case it was words). Remember to include at least 16 or you end up in an infinite loop ;-)

      You could speed things by shuffling @words right before the two inner loops.

      foreach my $i (1..$cards) { my %seen; . . . for my $x (1..4) { for my $y (1..4) { my $word; while (1) { my $index = rand(@words); $word = $words[$index]; if (!$seen{$word}) { $seen{$word}++; last; } } . . .
      becomes:
      use Algorithm::Numerical::Shuffle qw /shuffle/; . . . foreach my $i (1..$cards) { . . . @words = shuffle @words; for my $x (1..4) { for my $y (1..4) { my $word = shift @words; . . .

      HTH,
      Charles K. Clarkson
      Clarkson Energy Homes, Inc.
        Have you benchmarked that to see if it's faster?

        My suspicion would be that for large data sets it would be, but for smaller ones my naive rand() implementation would be quickest.

Bingo redux
by runrig (Abbot) on May 19, 2002 at 18:13 UTC
    I was thinking about something like this the other day (though the board is 5x5 and the middle space is a "free" space that everyone gets, well, for free). Except my question was, what is the largest number of cards that can be generated such that no two people can win at once? (The Rules in short: the "B" column contains 5 of the numbers 1-15 in any order, "I" contains 16-30, etc. (but the "N" column only has 4 numbers since the middle is a free space), numbers are called out one at a time, and you win when you get 5 in a row horizontally, vertically, or diagonally).

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://167664]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (13)
As of 2014-07-14 12:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (259 votes), past polls