12
\$\begingroup\$

You're sick of other players smugly announcing "BINGO" and walking triumphantly past you to claim their prize. This time it will be different. You bribed the caller to give you the BINGO calls ahead of time, in the order they will be called. Now you just need to create a BINGO board that will win as early as possible for those calls, guaranteeing you a win (or an unlikely tie).

Given a delimited string or list of the calls in order, in typical BINGO format (letters included, e.g. B9 or G68, see the rules for more info), output a matrix or 2D list representing an optimal BINGO board for those calls. Assume input will always be valid.

BINGO Rules:

  • 5x5 board
  • A "BINGO" is when your card has 5 numbers in a row from the numbers that have been called so far.
  • The center square is free (automatically counted towards a BINGO), and may be represented by whitespace, an empty list, -1, or 0.
  • The 5 columns are represented by the letters B,I,N,G,O, respectively.
  • The first column may contain the numbers 1-15, the second 16-30, ..., and the fifth 61-75.
  • The letters and numbers taken for input may optionally be delimited (by something that makes sense, like a , or space) or taken as a tuple of a character and a number.
  • Output requires only numbers in each place in the matrix.
  • Squares that will not contribute to your early BINGO must be valid, but do not have to be optimal.
  • This is code-golf, shortest code wins

Examples:

I'm using this input format for the examples, because it's shorter. See the section above for acceptable input/output formats.

O61 B2 N36 G47 I16 N35 I21 O64 G48 O73 I30 N33 I17 N43 G46 O72 I19 O71 B14 B7 G50 B1 I22 B8 N40 B13 B6 N37 O70 G55 G58 G52 B3 B4 N34 I28 I29 O65 B11 G51 I23 G56 G59 I27 I25 G54 O66 N45 O67 O75 N42 O62 N31 N38 N41 G57 N39 B9 G60 I20 N32 B15 O63 N44 B10 I26 O68 G53 I18 B12 O69 G49 B5 O74 I24

Possible Output (this has a horizontal BINGO in 3rd row. A diagonal is also possible.): 
[[11,25,42,53,68], 
 [ 6,22,32,57,62],
 [ 2,16, 0,47,61],
 [ 3,17,37,59,75],
 [ 9,19,41,46,70]]

N42 N34 O66 N40 B6 O65 O63 N41 B3 G54 N45 I16 O67 N31 I28 B2 B14 G51 N36 N33 I23 B11 I17 I27 N44 I24 O75 N38 G50 G58 B12 O62 I18 B5 O74 G60 I26 B8 I22 N35 B1 B4 G53 O73 G52 O68 B10 O70 I30 G59 N43 N39 B9 G46 G55 O64 O61 I29 G56 G48 G49 I19 G57 N37 O72 I25 N32 B13 B7 B15 O71 I21 I20 O69 G47

Must be a vertical BINGO in 3rd (N) column (because 4 N's came before one of each B,I,G,O):
[[11,25,42,53,63], 
 [ 2,22,34,57,65],
 [ 6,16, 0,47,66],
 [ 3,17,41,54,75],
 [ 9,19,40,46,70]]
\$\endgroup\$
  • \$\begingroup\$ You say that the letters are included. What do they mean? \$\endgroup\$ – Blue Dec 28 '16 at 22:04
  • 1
    \$\begingroup\$ @muddyfish Under BINGO rules: The 5 columns are represented by the letters B,I,N,G,O, respectively. \$\endgroup\$ – JungHwan Min Dec 28 '16 at 22:05
4
\$\begingroup\$

Mathematica, 302 bytes

(b=Prepend;i=1;n=15#&@@#-15+Range@5&;g=#~b~{N,0};o={#2,#3,#,##4}&@@#&;While[(l=Length@Union[t=(k=Take)[#&@@@g,i]])<5&&Max[#2&@@@Tally@t]<5,i++];If[l<5,m=#&@@Commonest@t;If[m===#,o[g~k~i/.{m,x_}->x/.{_,_}->Nothing],n@#2]&,o@DeleteDuplicates@b[n@#2,<|#->#2&@@@Reverse@g|>@#]~k~5&]~MapIndexed~{B,I,N,G,O})&

Unnamed function taking as its argument a list of ordered pairs, such as {{N,42},{N,34},{O,66},{N,40},...} (note that the first element in each ordered pair is not a string but rather a naked symbol), and returning a 2D list of integers, where the sublists represent columns (not rows) of the bingo board.

Output for the first test case:

{{1,3,2,4,5},{17,18,16,19,20},{31,32,0,33,34},{46,48,47,49,50},{62,63,61,64,65}}

In general, when the earliest possible bingo occurs because of a number called in each of the B/I/G/O rows, then those numbers will be in the center row; each column will otherwise contain the four smallest possible numbers (taking the already used number into account). For example, if the first test case is changed so that the second number called is B12 rather than B2, then the first column of the output board will be {1,2,12,3,4}.

Output for the second test case:

{{1,2,3,4,5},{16,17,18,19,20},{42,34,0,40,41},{46,47,48,49,50},{61,62,63,64,65}}

In general, when the earliest possible bingo occurs because of five numbers called in a single column (or four called in the N column), then the remaining four columns contain their five smallest possible numbers in order.

If the second test case is changed from {{N,42},{N,34},{O,66},{N,40},...} to {{O,72},{O,74},{O,66},{N,40},...} (only the first two entries changed), then the output is:

{{1,2,3,4,5},{16,17,18,19,20},{31,32,33,34,35},{46,47,48,49,50},{74,66,72,65,63}}

Somewhat ungolfed version:

(b=Prepend;i=1;n=15First[#]-15+Range[5]&;g=b[#,{N,0}];o={#2,#3,#,##4}&@@#&;
While[
    (l=Length[Union[t=(k=Take)[Apply[#&,g,{1}],i]]])<5
  &&
    Max[Apply[#2&,Tally[t],{1}]]<5,
  i++];
MapIndexed[
  If[l<5,
    m=First[Commonest[t]];If[m===#,o[k[g,i]/.{m,x_}->x/.{_,_}->Nothing],n[#2]]&,
    k[
      o[DeleteDuplicates[b[n[#2],Association[Apply[#->#2&,Reverse[g],{1}]][#]]]]
    ,5]&
  ],{B,I,N,G,O}
])&

The first line is mostly definitions to shorten the code, although g prepends the center square {N,0} to the input to simplify the bingo-finding. (The n function gives the smallest five legal bingo numbers in the #th column, 1-indexed. The o function takes a 5-tuple and moves the first element so that it's third.)

The While loop in lines 2-6 finds the smallest initial segment of the input that contains a bingo. (The third line tests for one-in-each-column bingos, while the fifth line tests for single-column bingos).

For any function F, the operator MapIndexed[F,{B,I,N,G,O}] (starting in line 7) produces the 5-tuple {F{B,1},F{I,2},F{N,3},F{G,4},F{O,5}} (well, technically it's {F{B,{1}},...}); we apply a function F that creates a bingo-board column out of its two arguments. That function, however, depends on which type of bingo was found: line 8 is true when we have a single-column bingo, in which case the function (line 9) uses the relevant input numbers in the bingo column and default numbers in the other columns. In the other case, the function (lines 10-12) uses the relevant input numbers in the center of each column and default numbers elsewhere.

\$\endgroup\$
  • 2
    \$\begingroup\$ What, no built-in Bingo function? \$\endgroup\$ – mbomb007 Dec 29 '16 at 17:08
  • \$\begingroup\$ —wait, built-in Bingo isn't disallowed? <runs to change answer> \$\endgroup\$ – Greg Martin Dec 29 '16 at 19:45
3
\$\begingroup\$

JavaScript (ES6) 372 Bytes

Can probably still be golfed a bit, but I don't see how. Suggestions are much appreciated ;)

A=a=>[1,2,3,4,5].map(x=>x+15*a),F=a=>{b=[[],[],[i=0],[],[]],a.replace(/[^0-9 ]/g,"").split` `.some(x=>{b[--x/15|(c=0)].push(++x);return b.some((x,i)=>(d=x.length)>4||d==1&i-2&&++c>3)});for(e=[A(0),A(1),A(2),A(3),A(4)];i<5;a=b[i][0],b[i][0]=b[i][2],b[i++][2]=a)for(j=0;j<5&b[i].length<5;j++)b[i][j]<i*15+5?e[i].splice(e[i].indexOf(b[i][j]),1):b[i][j]=e[i].shift();return b}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.