Код Гольф Бинго!

14

Вам предоставляется доска для бинго и список звонков. Вы должны напечатать БИНГО! как только ваша доска выиграет игру.

Бинго доски выглядят так:

введите описание изображения здесь

Они будут указаны так:

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

Сразу после доски будут звонки, вот так:

B7
I29
G60
G51
O71
I23
I16
N38

Вы должны выводить вызовы на стандартный вывод до тех пор, пока сразу после вызова, который заставляет вас выиграть (получить заполненную строку, столбец или диагональ длиной 5,), а затем распечатать BINGO! .

Для приведенного выше примера выведите:

B7
I29
G60
G51
O71
I23
I16
BINGO!

правила

Стандартные правила игры в гольф, самый короткий код выигрывает.

Детали

Всегда будет достаточно звонков, чтобы гарантировать вам бинго. На доске не будет повторяющихся номеров и повторных звонков. Доски всегда будут иметь правильно сопоставленные цифры и буквы ( Bстолбец содержит только 1-15, Iстолбец содержит только 16-30 и т. Д.), Как и вызовы. Единственное свободное место всегда будет посередине, помеченное *вместо числа. Использование и отбрасывание вызовов со стандартного ввода после выигрышного вызова разрешено, но не обязательно.

Сделайте свои собственные тестовые случаи!

Кит Рэндалл
источник

Ответы:

3

Perl, 122 120 символов

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

Постройте карту $bс двумя дополнительными столбиками. Замените номера, которые вызываются на карточке, на *и напечатайте набранный номер. Тогда последнее регулярное выражение оценивается как истинное, если *на доске 5 регулярных интервалов .

чернь
источник
4

C # - 536

(Хорошо, это, вероятно, не самый подходящий язык для этого, но в любом случае ...)

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

Отформатировано и прокомментировано:

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
источник
4

Рубин 1,9 (194, 130)

Вероятно, это не самый разумный способ проверить наличие пустых столбцов, но это было первое, что я подумал попробовать! В частности, что#transpose стоит много.

Либо пустая строка между доской и полями чисел или фиксированной ширины при объявлении доски сохранит много символов. Я не мог придумать действительно хороший способ прочитать ровно 5 строк.

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

РЕДАКТИРОВАТЬ: решение из 130 символов с использованием техники регулярных выражений из ответа perl моба:

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}}
Пол Престиж
источник
4

Учитывая долгое, долгое и долгожданное объявление о предстоящем выпуске Rebol в качестве программного обеспечения с открытым исходным кодом , я вернулся к своему любимому диалекту, чтобы решить эту проблему Bingo . Возможно, скоро я смогу распространять Rebmu как собственный пакет GPL для подростков. :)


Ребму 88 персонажей

В компактной записи:

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

В диалекте используется трюк, который я называю грибованием, который объясняется на странице Ребму . Это «законно» в том смысле, что не обманывает парсер; это действительно Rebol ... и фактически может свободно смешиваться с обычным кодом, а также (ahem) "long-form" Rebmu ... который, кстати, будет 141 символом:

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

(Учитывая, что я утверждаю, что сжатие - это трюк, который можно сделать без помощи автоматизации или компиляции, я фактически разрабатываю код в запутанной форме. Это не сложно.)

Это на самом деле довольно просто, ничего особенного - я уверен, что другие программисты Rebol могли бы побриться. Некоторый прокомментированный источник находится на GitHub , но основной трюк, который я использую, состоит в том, чтобы собрать все возможные решения в длинной серии («список», «массив», «что у тебя»). Я строю диагональные решения во время цикла ввода, поскольку для их создания требуется пять вставок в начале и пять добавлений в хвосте ... и уже выполняется цикл из пяти итераций.

Все это легко сопоставляется с кодом Rebol, и я еще не бросил в Rebmu никаких «матричных библиотек» с транспозицией или другими уловками, которые, кажется, часто появляются. Когда-нибудь я это сделаю, но сейчас я просто пытаюсь работать относительно близко к самому Rebol. Загадочные вещи вроде:

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

... довольно просты:

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

Примечание: скобки добавлены выше для ясности. Но программисты Rebol (например, англоговорящие), как правило, избегают применения дополнительных структурных выносок для указания грамматики в общении ... скорее сохраните их для других приложений ...

Просто в качестве дополнительного бонуса, чтобы показать, насколько это интересно на самом деле, я добавлю некоторую смесь нормального кода для подведения итогов доски. Стили программирования на самом деле ... совместимы:

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

Это действительно Rebmu, и он даст вам хорошую сумму на доске, прежде чем играть в бинго с вами. В приведенном примере сказано Hey grandma, the board sum is 912. Что, вероятно, правильно. Но вы поняли. :)

HostileFork говорит, что не доверяйте SE
источник
2

Mathematica 250

Раскрытие информации: я предположил, что ввод был дан в списках, которые гораздо более естественны для использования в Mathematica. Итак, с bпредставлением доски и cпредставления вызовов,

b//Grid
c//Column

вход

Если бы ввод был в строках, код вырос бы примерно на 30 символов. (Я позже включу этот вариант.)

Код

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

БИНГО!

DavidC
источник
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!'

Использование:

$ ./bingo.py < bingo.txt
B7
I29
G60
G51
O71
I23
I16
BINGO!
Matt
источник
Вы можете заменить rowодно-символьным именем. Непроверенные: попробуйте i in'*'*5]и заменить [x=='*']с [x==i].
Восстановить Монику
2

APL (82)

{(D≡(⍵∨⌽⍵)∧D←=/¨⍳⍴⍵)∨∨/(∧⌿⍵)∨∧/⍵:'BINGO!'⋄∇⍵∨B=⍎1↓⎕←⍞}0=B←↑{⍎(K,K)[⍞⍳⍨K←11↑⎕D]}¨⍳5
  • {...}¨⍳5 : сделать 5 раз:
  • ⍎(K,K)[⍞⍳⍨K←11↑⎕D]: прочитать строку ( ) и отобразите все символы, которые не являются цифрами или пробелами 0, затем оцените строку.
  • B←↑: превратить его в матрицу (5x5, если введено правильно) и сохранить в B.
  • {...}0=B : стартовая доска имеет 1 в свободном пространстве (0) и 0 в других пространствах.
  • (D≡(⍵∨⌽⍵)∧D←=/¨⍳⍴⍵)∨∨/(∧⌿⍵)∨∧/⍵: если линия, столбец или диагональ заполнены:
  • 'BINGO!': затем вывод BINGO
  • ∇⍵∨B=⍎1↓⎕←⍞: в противном случае прочитайте строку ( ), выведите его ( ⎕←), удалите первый символ ( 1↓), оцените его, чтобы получить число ( ), посмотрите, где оно встречается на доске ( B=), отметьте его ( ⍵∨) и попробуйте снова ( ) ,
Мэринус
источник
0

К, 114

Учитывая доску bи звонкиc

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
источник