Code Golf Bingo!

14

Sie erhalten ein Bingoboard und eine Anrufliste. Sie müssen BINGO! sobald dein board das spiel gewinnt.

Bingoboards sehen so aus:

Bildbeschreibung hier eingeben

Sie werden wie folgt angegeben:

14 29 38 52 74
4 18 33 46 62
7 16 * 60 71
9 27 44 51 67
12 23 35 47 73

Unmittelbar im Anschluss an das Board werden Anrufe wie folgt getätigt:

B7
I29
G60
G51
O71
I23
I16
N38

Sie müssen die ausgegebenen Anrufe an die Standardausgabe weiterleiten, bis kurz nach dem Anruf, bei dem Sie gewinnen, eine Zeile, eine Spalte oder eine 5-fache Diagonale ausgefüllt ist, und dann drucken BINGO!.

Für das obige Beispiel drucken Sie:

B7
I29
G60
G51
O71
I23
I16
BINGO!

Regeln

Standardcode-Golfregeln, kürzester Code gewinnt.

Einzelheiten

Es wird immer genug Anrufe geben, um Ihnen ein Bingo zu garantieren. Es gibt keine doppelten Nummern auf der Karte und keine doppelten Anrufe. Boards haben immer korrekt zugeordnete Zahlen und Buchstaben (die BSpalte enthält nur 1 bis 15, die ISpalte enthält nur 16 bis 30 usw.), ebenso wie Calls. Der einzige freie Speicherplatz befindet sich immer in der Mitte und ist mit gekennzeichnet* statt mit einer Zahl gekennzeichnet. Das Konsumieren und Verwerfen von Anrufen aus der Standardeingabe nach dem erfolgreichen Anruf ist zulässig, aber nicht erforderlich.

Machen Sie Ihre eigenen Testfälle!

Keith Randall
quelle

Antworten:

3

Perl, 122 120 char

$b=join'. .
',map~~<>,0..4;while(<>){/(\d+)/;$b=~s/\b$1\b/*/;print;
$b=~/(\*\s(\S+\s){$_}){4}\*/&&die"BINGO!
"for 0..7}

Bauen Sie die Karte $bmit zwei zusätzlichen Junky-Spalten ein. Ersetzen Sie die auf der Karte angerufenen Nummern durch *und drucken Sie die angerufene Nummer aus. Dann wird der letzte reguläre Ausdruck als wahr ausgewertet, wenn 5 reguläre Abstände *auf dem Board vorhanden sind.

Mob
quelle
4

C # - 536

(OK, das ist wahrscheinlich nicht die am besten geeignete Sprache dafür, aber trotzdem ...)

using System;using System.Collections.Generic;using System.Linq;class C{static void Main(){var s=Enumerable.Range(1,12).Select(_=>new HashSet<string>()).ToList();var b=Enumerable.Range(1,5).Select(_=>Console.ReadLine().Split(' ')).ToList();int i;for(i=0;i<5;++i){for(int j=0;j<5;++j){s[i].Add(b[i][j]);s[i+5].Add(b[j][i]);}s[10].Add(b[i][i]);s[11].Add(b[4-i][i]);}while(i>0){var l=Console.ReadLine();Console.WriteLine(l);l=l.Substring(1);foreach(var x in s){x.Remove("*");x.Remove(l);if(x.Count==0){Console.WriteLine("BINGO!");i=0;}}}}}

Formatiert und kommentiert:

using System;
using System.Collections.Generic;
using System.Linq;

class C
{
    static void Main()
    {
        // all possible winnable five-item sets – any one of them need to be emptied to win
        var s = Enumerable.Range(1, 12).Select(_ => new HashSet<string>()).ToList();
        // read the board from input to a list of arrays of numbers
        var b = Enumerable.Range(1, 5).Select(_ => Console.ReadLine().Split(' ')).ToList();
        int i;
        // split the board into the winnable sets
        for (i = 0; i < 5; ++i)
        {
            for (int j = 0; j < 5; ++j)
            {
                // sets 0–4 represent rows
                s[i].Add(b[i][j]);
                // sets 5–9 represent columns
                s[i + 5].Add(b[j][i]);
            }
            // set 10 represent one diagonal
            s[10].Add(b[i][i]);
            // set 11 represent the other diagonal
            s[11].Add(b[4 - i][i]);
        }
        while (i > 0)
        {
            // read and echo another input
            var l = Console.ReadLine();
            Console.WriteLine(l);
            // ignore the initial letter – we are guaranteed it is correct, anyway
            l = l.Substring(1);
            // remove the number from all sets
            foreach (var x in s)
            {
                x.Remove(l);
                // also remove the center * (inside the loop just to shave off a few characters)
                x.Remove("*");
                // if any set became empty, we won!
                if (x.Count == 0)
                {
                    Console.WriteLine("BINGO!");
                    // ensure the loop will stop (might not be necessary per the rules, but anyway)
                    i = 0;
                }
            }
        }
    }
}
Mormegil
quelle
4

Ruby 1.9 (194, 130)

Dies ist wahrscheinlich nicht die sinnvollste Methode, um nach leeren Spalten zu suchen, aber ich dachte zuerst, es zu versuchen! Das #transposekostet vor allem viel.

Entweder eine leere Zeile zwischen der Tafel und den Zahlen oder Felder mit fester Breite, wenn die Tafel deklariert wird, würden viele Zeichen sparen. Ich konnte mir keine wirklich gute Möglichkeit vorstellen, genau 5 Zeilen zu lesen.

b=(R=0..4).map{gets}.join.scan /\d+|\*/
loop{gets
puts$_
~/\d+/
(e=b.index$&)&&b[e]=?*
R.map{|y|$><<:BINGO!&&exit if R.map{|x|[b[5*x+y],b[5*y+x],b[y<1?x*6:4*x+4]]}.transpose.any?{|a|a==[?*]*5}}}

EDIT: 130-Zeichen-Lösung mit der regulären Ausdruckstechnik aus der Perl-Antwort von Mob:

b=(0..4).map{gets}*'~ ~ '
loop{gets
puts$_
~/\d+/
b[/\b#$&\b/]=?*
7.times{|i|$><<:BINGO!&&exit if b=~/(\*\s(\S+\s){#{i}}){4}\*/m}}
Paul Prestidge
quelle
4

Angesichts der langen, langen, überfälligen Ankündigung der bevorstehenden Veröffentlichung von Rebol als Open-Source-Software kehrte ich zu meinem Lieblingsdialekt zurück, um dieses Bingo-Problem zu lösen . Möglicherweise kann ich Rebmu bald als eigenes, teensy GPL-Paket vertreiben. :)


Rebmu 88 Zeichen

In der kompakten Notation:

rtZ5[GisGpcRaZisGaAPgPCaSB6zAPv'*]l5[AgL5[apGfAsk+A5]]hd+Gu[raGin-NTrM'*fisGv5]p"BINGO!"

Der Dialekt verwendet einen Trick, den ich Mushing nenne und der auf der Rebmu-Seite erklärt wird . Es ist "echt" in dem Sinne, dass es den Parser nicht betrügt; Dies ist ein gültiger Rebol ... und kann tatsächlich frei mit gewöhnlichem Code sowie (ahem) "Langform" -Rebmu ... gemischt werden, der übrigens 141 Zeichen umfassen würde:

[rt z 5 [g: is g pc r a z is g a ap g pc a sb 6 z ap v '*] l 5 [a: g l 5 [ap g f a sk+ a 5]] hd+ g u [ra g in- nt r m '* fis g v 5] p "BINGO!"]

(Da ich behaupte, dass die Komprimierung ein Trick ist, den man ohne die Hilfe von Automatisierung oder Kompilierung machen kann, entwickle ich den Code tatsächlich in muskulöser Form. Es ist nicht schwierig.)

Es ist eigentlich ganz einfach, nichts Besonderes - ich bin sicher, andere Rebol-Programmierer könnten die Dinge abschneiden. Einige kommentierte Quellen sind auf GitHub , aber der Haupttrick, den ich verwende, besteht darin, alle möglichen Lösungen in einer langen Reihe zu erstellen ("Liste", "Array", What-Have-You). Ich erstelle die diagonalen Lösungen während der Eingabeschleife, da fünf Einfügungen am Kopf und fünf Anhänge am Schwanz erforderlich sind, um sie zu erstellen ... und es wird bereits eine Schleife mit fünf Iterationen ausgeführt.

Das Ganze ist leicht zu Rebol-Code zuzuordnen, und ich habe noch keine "Matrix-Bibliotheken" in Rebmu mit Transposition oder anderen Gimmicks geworfen, die anscheinend häufig auftauchen. Eines Tages werde ich das tun, aber im Moment versuche ich nur, dem Medium Rebol selbst relativ nahe zu kommen. Kryptisch aussehende Dinge wie:

 [g: is g pc r a z is g a ap g pc a sb 6 z ap v '*]

... sind eher einfach:

 [
     ; assign the series pointer "g" to the result of inserting 
     ; the z'th element picked out of reading in some series
     ; from input that was stored in "a"...this pokes an element
     ; for the forward diagonal near the front of g
     g: insert g (pick (readin-mu a) z)

     ; insert the read-in series "a" from above into "g" as well,
     ; but *after* the forward diagonal elements we've added...
     insert g a

     ; for the reverse diagonal, subtract z from 6 and pick that
     ; (one-based) element out of the input that was stored in "a"
     ; so an element for the reverse diagonal is at the tail
     append g (pick a (subtract 6 z))

     ; so long as we are counting to 5 anyway, go ahead and add an
     ; asterisk to a series we will use called "v" to search for
     ; a fulfilled solution later
     append v '*
 ]

Hinweis: Die obigen Klammern dienen der Verdeutlichung. Aber Rebol-Programmierer (wie Englisch sprechende) verzichten im Allgemeinen auf zusätzliche strukturelle Beschriftungen, um die Grammatik in der Kommunikation anzuzeigen ... sondern speichern sie für andere Anwendungen ...

Nur als zusätzlichen Bonus, um zu zeigen, wie interessant dies tatsächlich ist, werde ich eine Mischung aus normalem Code einwerfen, um das Board zusammenzufassen. Die Programmierstile sind eigentlich ... kompatibel:

rtZ5[GisGpcRaZisGaAPgPCaSB6zAPv'*]
temp-series: g
sum: 0
loop 5 * 5 [
    square: first temp-series
    if integer! == type? square [
        sum: sum + square
    ]
    temp-series: next temp-series
]
print ["Hey grandma, the board sum is" sum]
l5[AgL5[apGfAsk+A5]]hd+Gu[raGin-NTrM'*fisGv5]p"BINGO!"

Das ist auch gültiger Rebmu, und er gibt dir eine nette Brettsumme, bevor du mit dir Bingo spielst. In dem gegebenen Beispiel heißt es Hey grandma, the board sum is 912. Welches ist wahrscheinlich richtig. Aber du verstehst den Punkt. :)

HostileFork sagt, traue SE nicht
quelle
2

Mathematica 250

Offenlegung: Ich ging davon aus, dass die Eingabe in Listen erfolgt, die für Mathematica weitaus natürlicher sind. Also, mit der bDarstellung der Tafel und der cDarstellung der Anrufe,

b//Grid
c//Column

Eingang

Wenn die Eingabe in Zeichenfolgen erfolgen würde, würde der Code um ca. 30 Zeichen wachsen. (Diese Variante werde ich später hinzufügen.)

Code

y = ReplacePart[ConstantArray[0, {5, 5}], {3, 3} -> 1]; d = Diagonal;
t := Tr[BitAnd @@@ Join[y, Transpose@y, {d@y}, {d[Reverse /@ y]}]] > 0;
r@i_ :=(y = ReplacePart[y, Position[x, ToExpression@StringDrop[i, 1]][[1]] -> 1]; 
Print@If[t, Column[{i, "BINGO!"}], i])
n = 1; While[! t, r@c[[n]]; n++]

B7

I29

G60

G51

O71

I23

I16

BINGO!

DavidC
quelle
2

Python 249

R=raw_input;F=B=[[[x,0][x=='*']for x in row]for row in[R().split()for i in'11111']];A=any
while all([all(map(A,B)),all(map(A,zip(*B))),A(F[::6]),A(F[4:24:4])]):c=R();print c;C=c[1:];B=[[[x,0][x==C]for x in row]for row in B];F=sum(B,[])
print'BINGO!'

Verwendung:

$ ./bingo.py < bingo.txt
B7
I29
G60
G51
O71
I23
I16
BINGO!
Matt
quelle
Sie könnten rowdurch einen Ein-Zeichen-Namen ersetzen . Ungetestet: versuchen i in'*'*5]und ersetzen [x=='*']durch [x==i].
Setzen Sie Monica
2

APL (82)

{(D≡(⍵∨⌽⍵)∧D←=/¨⍳⍴⍵)∨∨/(∧⌿⍵)∨∧/⍵:'BINGO!'⋄∇⍵∨B=⍎1↓⎕←⍞}0=B←↑{⍎(K,K)[⍞⍳⍨K←11↑⎕D]}¨⍳5
  • {... }¨⍳5: mache 5 mal:
  • ⍎(K,K)[⍞⍳⍨K←11↑⎕D]: Lies eine Zeile ( ) und ordne alle Zeichen zu, die keine Ziffern oder Leerzeichen sind0 , und bewerte dann die Zeile.
  • B←↑: verwandle es in eine Matrix (5x5 wenn die Eingabe korrekt war) und speichere es in B.
  • {... }0=B: Das Startbrett hat eine 1 im freien Feld (0) und 0 in den anderen Feldern.
  • (D≡(⍵∨⌽⍵)∧D←=/¨⍳⍴⍵)∨∨/(∧⌿⍵)∨∧/⍵: wenn eine Zeile, eine Spalte oder eine Diagonale gefüllt ist:
  • 'BINGO!': dann ausgeben BINGO
  • ∇⍵∨B=⍎1↓⎕←⍞: Lesen Sie andernfalls eine Zeile ( ), wiederholen Sie sie ( ⎕←) und lassen Sie das erste Zeichen fallen (1↓ ) fallen, bewerte sie, um eine Zahl zu erhalten ( ), sieh nach, wo sie auf der Tafel vorkommt ( B=), markiere sie ( ⍵∨) und versuche es erneut ( ) .
Marinus
quelle
0

K, 114

Angesichts der Tafel b und der Anrufec

b{-1@y;a:(5*!5)_@[,/x;&(,/x)~\:1_y;:;"*"];$[max{max@min'"*"=,/'x}@/:(a;a ./:/:+:'(r;)'(r;|:r:!5));'"BINGO!";];a}/c

.

k)b
"14" "29" "38" "52" "74"
,"4" "18" "33" "46" "62"
,"7" "16" ,"*" "60" "71"
,"9" "27" "44" "51" "67"
"12" "23" "35" "47" "73"
k)c
"B7"
"I29"
"G60"
"G51"
"O71"
"I23"
"I16"
"N38"
k)b{-1@y;a:(5*!5)_@[,/x;&(,/x)~\:1_y;:;"*"];$[max{max@min'"*"=,/'x}@/:(a;a ./:/:+:'(r;)'(r;|:r:!5));'"BINGO!";];a}/c
B7
I29
G60
G51
O71
I23
I16
'BINGO
tmartin
quelle