Kode Golf Bingo!

14

Anda diberi papan Bingo dan daftar panggilan. Anda harus mencetak BINGO! segera setelah papan Anda memenangkan permainan.

Papan bingo terlihat seperti ini:

masukkan deskripsi gambar di sini

Mereka akan ditentukan seperti ini:

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

Segera setelah papan akan panggilan, seperti ini:

B7
I29
G60
G51
O71
I23
I16
N38

Anda harus menggema panggilan keluar ke output standar sampai tepat setelah panggilan yang membuat Anda menang (mendapatkan baris, kolom, atau diagonal 5-panjang semua terisi), lalu cetak BINGO!.

Untuk contoh di atas, cetak:

B7
I29
G60
G51
O71
I23
I16
BINGO!

Aturan

Aturan kode-golf standar, kode terpendek menang.

Detail

Akan selalu ada cukup panggilan untuk menjamin Anda Bingo. Tidak akan ada nomor rangkap di papan tulis, dan tidak ada panggilan rangkap. Papan akan selalu memiliki angka dan huruf yang cocok dengan benar ( Bkolom hanya berisi 1-15, Ikolom hanya berisi 16-30, dan seterusnya), demikian juga panggilan. Satu-satunya ruang kosong akan selalu berada di tengah, ditandai dengan *alih - alih angka. Mengkonsumsi dan membuang panggilan dari input standar setelah panggilan yang menang diizinkan, tetapi tidak diperlukan.

Buat kasus uji Anda sendiri!

Keith Randall
sumber

Jawaban:

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}

Bangun kartu $bdengan dua kolom sampah tambahan. Ganti nomor yang dipanggil dengan kartu *dan cetak nomor yang dipanggil. Kemudian ekspresi reguler terakhir akan mengevaluasi ke true ketika ada 5 spasi secara teratur *di papan tulis.

massa
sumber
4

C # - 536

(Oke, ini mungkin bukan bahasa yang paling cocok untuk itu, tapi toh ...)

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;}}}}}

Diformat dan dikomentari:

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
sumber
4

Ruby 1.9 (194, 130)

Ini mungkin bukan cara yang paling masuk akal untuk memeriksa kolom kosong, tapi itu adalah hal pertama yang saya coba coba! Secara khusus, itu #transposemembutuhkan banyak biaya.

Entah garis kosong antara papan dan angka atau bidang lebar tetap saat menyatakan papan akan menyimpan banyak karakter. Saya tidak bisa memikirkan cara yang sangat bagus untuk membaca persis 5 baris.

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 karakter solusi menggunakan teknik ekspresi reguler dari jawaban perl 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
sumber
4

Karena pengumuman yang lama, lama, dan lama ditunggu-tunggu tentang rilis Rebol yang akan datang sebagai perangkat lunak open source , saya kembali ke dialek peliharaan saya untuk menyelesaikan masalah Bingo ini . Saya mungkin akan segera dapat mendistribusikan Rebmu sebagai paket GPL kecilnya sendiri. :)


Rebmu 88 karakter

Dalam notasi kompak:

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

Dialek ini menggunakan trik yang saya sebut mushing yang dijelaskan di halaman Rebmu . Ini "sah" dalam arti bahwa itu tidak menipu pengurai; ini Rebol yang valid ... dan benar-benar dapat secara bebas berbaur dengan kode biasa serta (ahem) "long-form" Rebmu ... yang mana BTW akan terdiri dari 141 karakter:

[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!"]

(Mengingat bahwa saya mengklaim kompresi adalah trik yang dapat dilakukan tanpa bantuan otomatisasi atau kompilasi, saya benar-benar mengembangkan kode dalam bentuk bubur. Ini tidak sulit.)

Ini sebenarnya cukup sederhana, tidak ada yang istimewa - saya yakin programmer Rebol lainnya bisa mencukur habis. Beberapa sumber berkomentar ada di GitHub , tetapi trik utama yang saya gunakan adalah membangun semua solusi yang mungkin dalam seri panjang ("daftar", "array", apa-apa-apa). Saya membangun solusi diagonal selama loop input, karena dibutuhkan lima penyisipan di kepala dan lima menambahkan di ekor untuk membuat mereka ... dan sudah ada loop lima iterasi yang sedang berlangsung.

Semuanya mudah memetakan ke kode Rebol, dan saya belum melemparkan "perpustakaan matriks" ke Rebmu dengan transposisi atau tipuan lain yang sepertinya sering muncul. Suatu hari saya akan melakukan itu tetapi untuk saat ini saya hanya mencoba bekerja relatif dekat dengan media Rebol itu sendiri. Hal-hal yang tampak samar seperti:

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

... agak sederhana:

 [
     ; 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 '*
 ]

Catatan: Tanda kurung ditambahkan di atas untuk kejelasan. Tetapi programmer Rebol (seperti penutur bahasa Inggris) umumnya menghindari penerapan info struktural tambahan untuk menunjukkan tata bahasa dalam komunikasi ... alih-alih menyimpannya untuk aplikasi lain ...

Sama seperti bonus tambahan untuk menunjukkan betapa menariknya ini sebenarnya, saya akan memberikan beberapa campuran kode normal untuk menjumlahkan papan. Gaya pemrograman sebenarnya ... 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!"

Itu juga Rebmu yang valid, dan itu akan memberimu jumlah papan yang bagus sebelum bermain Bingo denganmu. Dalam contoh yang diberikan, katanya Hey grandma, the board sum is 912. Yang mana mungkin benar. Tapi Anda mengerti maksudnya. :)

HostileFork mengatakan jangan percaya pada SE
sumber
2

Mathematica 250

Pengungkapan: Saya berasumsi bahwa input diberikan dalam daftar yang jauh lebih alami untuk digunakan untuk Mathematica. Jadi, dengan bmewakili dewan dan cmewakili panggilan,

b//Grid
c//Column

memasukkan

Jika input berupa string, kode akan bertambah sekitar 30 karakter. (Nanti saya akan memasukkan variasi itu.)

Kode

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
sumber
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!'

Pemakaian:

$ ./bingo.py < bingo.txt
B7
I29
G60
G51
O71
I23
I16
BINGO!
Mat
sumber
Anda dapat mengganti rowdengan nama satu karakter. Belum teruji: coba i in'*'*5]dan ganti [x=='*']dengan [x==i].
Pasang kembali Monica
2

APL (82)

{(D≡(⍵∨⌽⍵)∧D←=/¨⍳⍴⍵)∨∨/(∧⌿⍵)∨∧/⍵:'BINGO!'⋄∇⍵∨B=⍎1↓⎕←⍞}0=B←↑{⍎(K,K)[⍞⍳⍨K←11↑⎕D]}¨⍳5
  • {... }¨⍳5: lakukan 5 kali:
  • ⍎(K,K)[⍞⍳⍨K←11↑⎕D]: baca baris ( ) dan petakan semua karakter yang bukan digit atau spasi 0, lalu evaluasi garis.
  • B←↑: ubah menjadi matriks (5x5 jika inputnya benar), dan simpan di B.
  • {... }0=B: papan awal memiliki 1 di ruang kosong (0) dan 0 di ruang lain.
  • (D≡(⍵∨⌽⍵)∧D←=/¨⍳⍴⍵)∨∨/(∧⌿⍵)∨∧/⍵: jika garis, kolom, atau diagonal diisi:
  • 'BINGO!': lalu output BINGO
  • ∇⍵∨B=⍎1↓⎕←⍞: jika tidak, baca baris ( ), gema itu ( ⎕←), letakkan karakter pertama ( 1↓), evaluasi untuk mendapatkan angka ( ), lihat di mana itu terjadi di papan tulis ( B=), tandai ( ⍵∨), dan coba lagi ( ) .
marinus
sumber
0

K, 114

Diberi papan bdan panggilanc

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
sumber