Leser: 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#!/usr/bin/perl use strict; use warnings; my @begriffe = qw(eins zwei drei vier fuenf sechs sieben acht neun zehn); my $anzahlKaertchen = 10; for (1..$anzahlKaertchen) { print "Kaertchen Nr. " . $_ . ":\n"; my @vals = (0..9); for my $i (0..5) { my $rand = int(rand()*@vals); print "\t" . $begriffe[$vals[$rand]] . "\n"; splice(@vals,$rand,1); } }
Quotesein soll, habe ich das hier jetzt nicht eigens überwacht. Je höher die Anzahl der Kärtchen, desto gleichmäßiger wird nach dem Gesetz der großen Zahl die Verteilung der Begriffe sein.wenn möglich jeder Begriff in der Anzahl auf den Spielkärtchen gleich gewichtet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#!/usr/bin/perl use strict; use warnings; my @begriffe = qw(eins zwei drei vier fuenf sechs sieben acht neun zehn); my $anzahlKaertchen = 200; # <-- max. 200 bitte! my %alleKaertchen; my $i = 1; while ($i <= $anzahlKaertchen) { my @vals = (0..9); my @kaertchen; for my $j (0..5) { my $rand = int(rand()*@vals); $kaertchen[$j] = $vals[$rand]; splice(@vals,$rand,1); } my $kaertchenID = join ("", sort @kaertchen); next if $alleKaertchen{$kaertchenID}; $alleKaertchen{$kaertchenID} = 1; print "Kaertchen Nr. " . $i . ":\n"; print "\t" . $begriffe[$_] . "\n" for @kaertchen; $i++; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
use List::Util qw(shuffle); my @begriffe = qw(eins zwei drei vier fuenf sechs sieben acht neun zehn); my $anzahlKaertchen = 200; my %karten = (); # Hash mit den erzeugten Karten while (keys(%karten) < $anzahlKaertchen) { # Liste mit 6 zufällig ausgewählten Begriffen anlegen my @karte = (shuffle(@begriffe))[0..5]; # eindeutigen Hash-Key für die ausgewählte Kombination erzeugen my $key = join('|',sort @karte); # falls es die Kombination noch nicht gab, # wird die Karte im Hash gespeichert unless ($karten{$key}) { $karten{$key} = \@karte; print int(keys %karten) ,". Karte : ",join(" · ",@karte),"\n"; } }
2010-09-28T22:45:17 clmsMit shuffle() aus List::Util kann man eine Liste in eine zufällige Reihenfolge bringen.
2010-09-28T22:45:17 clmsUnd bei der Erzeugung des Keys würde ich die einzelnen Begriffe sicherheitshalber durch ein Zeichen trennen, das garantiert in keinem der Begriffe vorkommt, z.B. '|' oder ' '.
2010-09-28T22:45:17 clmsNoch was - die Anzahl der gewünschten Kärtchen sollte deutlich kleiner als die Zahl möglicher Kombinationen sein, sonst wird die while-Schleife ineffizient.
2010-09-29T10:17:26 payx2010-09-28T22:45:17 clmsUnd bei der Erzeugung des Keys würde ich die einzelnen Begriffe sicherheitshalber durch ein Zeichen trennen, das garantiert in keinem der Begriffe vorkommt, z.B. '|' oder ' '.
Da ich den Key aus den Arrayindices erzeuge
2010-09-29T10:17:26 payxund das Array lt. Vorgabe genau 10 Stellen hat, macht mein Key keine Probleme.
2010-09-29T10:17:26 payxIm Ergebnis macht Dein (schlankerer) Code ja nichts anderes als meiner, d.h. frankes' Wunsch, dass durch das Programm eine gleichmäßige Verteilung (Häufigkeit) der zehn Elemente sichergestellt werde, ist auch bei Dir nicht erfüllt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
#!/usr/bin/perl use strict; use warnings; use Math::Combinatorics; my $cardNo = 20; # No. of cards to create my $cardFields = 6; # fields at one card my @terms = qw( term1 term2 term3 term4 term5 term6 term7 term8 term9 term10 ); # check if order possible if ( $cardFields > scalar @terms ) { die 'There are not enough terms (' ,scalar @terms ,") for $cardFields fields per card\n" ,$!; } # Edit 1: folgende Fehlerabfrage wurde nachträglich eingefügt elsif ( $cardNo*$cardFields < scalar @terms ) { die "$cardNo cards with $cardFields fields haven`t " ,'enought place for ',scalar @terms,' terms.',$!; } my @termNo = (0..scalar @terms-1); # just a help for keynames # Terms counter for a uniform distribution # %countTerms wird als Referenz genutzt, # um die Häufigkeit der verwendeten Begriffe # zu zählen my %countTerms = (); @countTerms{@termNo} = split ',',('0,' x scalar @termNo); # get all combinations as referenz my %allCombi = (); my $combinat = Math::Combinatorics->new( 'count' => $cardFields, 'data' => [@termNo], ); while(my @combo = $combinat->next_combination){ my $combo = join '-',sort{$a <=> $b}@combo; $allCombi{$combo} = 0; } # check if order possible my $possibleCards = scalar( keys %allCombi ); if ( $possibleCards < $cardNo) { die 'There are only ' ,$possibleCards ," combinations possible.\n" ,'but you ordered ' ,$cardNo, " cards.\n" ,$!; } # just a info print "There are $possibleCards combinations possible.\n\n"; # if all possible combinations in use # eine Abkürzung, wenn wirklich alle Kombinationen benötigt werden if ( $cardNo == $possibleCards ) { giveOut(\%allCombi); exit 0; } # Eine erste Karte zu erstellen wäre wahrscheinlich nicht nötig # kam mir aber als gute Idee vor # get a random first card my $firstCard = (keys %allCombi)[ int( rand()*$possibleCards ) ]; my %myCards = ($firstCard => 1); delete $allCombi{$firstCard}; # setup referenz map{ $countTerms{$_}++ }(split '-',$firstCard); # setup term counting referenz # creating cards my $card = 1; while ( $card < $cardNo) { # setting up a lookup for rare terms my @rareTerms = sort{ $countTerms{$a} <=> $countTerms{$b} } keys %countTerms; my @newFields = @rareTerms[0..$cardFields-1]; my $newCard = join '-',sort{$a <=> $b}@newFields; my @searchCards = (); # if combination in use, look up a similar combination unless ( exists $allCombi{$newCard} ) { $newCard = ''; while ( scalar @newFields > 0 ) { # spätestens wenn alle Begriffe entfernt wurden, # sollte es eigentlich # irgendeine Kombination finden. - so werden dann hoffentlich # die Bedingungen für die seltensten Kombinationen im Notfall # neu gemischt. # trotzdem habe ich irgendwie Sorgen wegen einer Endlosschleife pop @newFields; my $searchCard = join '-',sort{$a <=> $b}@newFields; @searchCards = grep{/^$searchCard/} keys %allCombi; if ( scalar @searchCards ) { $newCard = $searchCards[0]; last; } } } # found a unused card if ( $newCard ) { $myCards{$newCard} = 1; delete $allCombi{$newCard}; # setup referenz map{ $countTerms{$_}++ }(split '-',$newCard); # setup term counting referenz $card++; } } giveOut(\%myCards); exit 0; #################################### # give out # separiert, da es später ein Modul werden soll sub giveOut { my $myCards = shift; my %usedTerms = (); print '='x40,"\n"; print 'These ',$cardNo,' combinations are selected:',"\n"; foreach my $c ( keys %{$myCards} ) { my @t = map{$terms[$_]}(split '-',$c); print join ',',@t,"\n"; map{ $usedTerms{$_}++ }@t; # count used terms } print "\n",'='x40,"\n"; print 'These terms are in use:',"\n"; foreach my $t ( sort keys %usedTerms ) { print $t,': ',$usedTerms{$t},"x\n" } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
frank@Hugin:~/Dokumente/perl/bingo$ ./bingo_math.pl
There are 210 combinations possible.
========================================
These 20 combinations are selected:
term1,term2,term3,term5,term6,term8,
term1,term2,term3,term7,term8,term9,
term3,term4,term7,term8,term9,term10,
term2,term3,term5,term6,term7,term10,
term4,term6,term7,term8,term9,term10,
term2,term3,term4,term6,term8,term9,
term1,term4,term6,term7,term8,term10,
term1,term4,term6,term7,term9,term10,
term1,term4,term5,term7,term8,term10,
term1,term4,term6,term7,term8,term9,
term1,term2,term3,term5,term6,term9,
term1,term2,term4,term5,term6,term7,
term2,term3,term5,term8,term9,term10,
term1,term2,term3,term4,term5,term7,
term2,term3,term5,term7,term9,term10,
term2,term3,term4,term5,term9,term10,
term1,term3,term4,term8,term9,term10,
term1,term2,term5,term6,term8,term9,
term1,term2,term3,term5,term6,term10,
term4,term5,term6,term7,term8,term10,
========================================
These terms are in use:
term1: 12x
term10: 12x
term2: 12x
term3: 12x
term4: 12x
term5: 12x
term6: 12x
term7: 12x
term8: 12x
term9: 12x