Считайте ASCII hamantaschen!

18

Сегодня Пурим, по которому принято выдавать печенье в форме треугольника с начинкой, называемой hamantaschen (единственное число: hamantasch ). Другой обычай - много пить.

Я не самый лучший пекарь .... У меня так много хаманташен нестандартного размера, которые нужно раздавать, и так много друзей, которым они могут дать! Если я отправил вам фотографию моего печенья, вы можете сказать мне, сколько у меня какого размера и начинки? Но поскольку это Пурим, и я слишком пьян, чтобы читать много кода, он должен быть настолько маленьким, насколько вы можете сделать.

Определения

Размер

Хаманташ может быть любого размера . Самый маленький хаманташ имеет размер 1 и выглядит так:

/\  --
--  \/

Иногда, несколько hamantaschen могут перекрываться . Форма ниже считается двумя hamantaschen (один размер 1, один размер 2):

 /\
/\ \
----

Некоторые hamantaschen имеют наполнение . Это будет указано заполнением пробела внутри символа. Обратите внимание, что размер 1 hamantaschen не может иметь начинки.

Мы будем называть hamantaschen на основе заполнения и размера. Давайте использовать формат <filling> <size>и, если он не заполнен - <size>(вы можете использовать пробел вместо a -, но уценке это не нравится).

Вот . 2, а . 4, а - 3:

          /\
         /./\
 ----   /./  \
 \../  /./    \
  \/   --------

Это a @ 3, a . 2и a - 4:

          /\
         / /\
  /\    / /@@\
 /..\  / /@@@@\
 ----  --------

Вот что-то более сложное. Видите, как & 2заполнение меньше, чем вы ожидаете из-за наклона перекрытия - 3? Он имеет a - 1, & 2a - 3и a & 4:

--------
\   \/&/
 \  /\/
  \/&/
   \/

вход

Вам будет предоставлен текстовый файл или единственная строка hamantaschen (необязательный конечный перевод строки и необязательный дополненный пробел для четности).

рамки

  • Вы можете ожидать, что строка будет действительной - то есть каждый непробельный символ вносит свой вклад в восхитительно сладкий хаманташ (зачем тратить тесто?).
  • Можно также ожидать , что она будет правильно заполнена или нет , - то есть, каждый hamantasch будет полностью наполненным последовательным ASCII символ - ASCII 32 для незаполненного, или что - нибудь 32..127 для заполнения ( за исключение /, \и -).
  • Эти hamantaschen не сложены в 3-х пространствах. Все так /и \будет видно. Все, -что не заблокировано /и \будет видно. Заполнение идет очень последним.
  • У всех хаманташен будет видна как минимум половина их горизонтальной линии (округление вверх).
  • Любой непрерывный блок заполнения заполняет только самый маленький хаманташ, который его окружает.

Выход

Вернуть список «имен» всех hamantaschen, которые могут быть найдены в соответствии с вышеуказанными критериями. Вывод может быть в любой форме (строка, хеш, стандартный вывод и т. Д.).

Контрольные примеры

Тестовый пример № 1

Вход № 1:

          /\
         / /\
  /\    / /@@\
 /..\  / /@@@@\
 ----  --------
    /\
   /**\
  /*/\*\
 /*/..\*\
 --------

Выход № 1:

. 2
. 2
- 4
@ 3
* 4

Тестовый пример № 2

Вход № 2:

  /\----
 /\/\*\/
/ /\d\/
------

Выход № 2:

- 3
- 2
d 2
- 1    
* 2
- 1

Тест № 3

Вход № 3:

----
\/\/
/\/\  /\
---- /::\
     ----

Выход № 3:

- 1
- 1
- 2
- 1
- 1
- 2
: 2

Тест № 4

Вход № 4:

 /\/\
/ /\$\
-/--/\\
 --/--\
  /xxx/\
 /xxx/##\
 ---/----\
   /      \
   -------- 

Выход № 4:

$ 2
x 4
- 3
- 2
- 4
- 1
- 1
# 2

Неверный контрольный пример № 5

Входные данные:

/\
\/

Выход:

Вам не нужно справляться с этим.

Не тот Чарльз
источник
Как насчет теста, в котором hamentaschen перекрываются, но не имеют одинаковую горизонтальную линию? Один может даже заблокировать горизонтальную линию другого.
гордый haskeller
@proudhaskeller Хорошо, готово. Тем не менее, и я просто поместил это в тексте, это 2 пробела. Мы будем всегда видеть все /и \ , и -всегда будет начинка козырь.
Не то, чтобы Чарльз
2
@EasterlyIrk Есть и другие важные моменты - чтение Книги Эстер (и издевательство над плохими парнями), раздача бедным - и менее основополагающие вещи, такие как одевание в костюмы.
Не то, чтобы Чарльз
1
снова сделал актуальным!
downrep_nation
1
Исходя из нулевого начального столбца, все ваши столбцы вершин, кроме (1,0), отключены +1. Тем не менее, я знаю, что вы имеете в виду, и я не согласен. Что указывает на то, что (2, 2)это верхний центр a, - 2а не только верхний правый и левый из двух верхних - 1s? Ничего такого, что я вижу. И та же логика применима к (3, 2). Если только вы не хотите добавить правило, предполагающее максимально возможный хаманташен ...
Майкл Плотке

Ответы:

4

C #, 496 452 байта

Редактировать: обнаружил ошибку с проверкой границ ... но также с разгрузкой байтов, которые были вынуждены понимать мой собственный код. Развертывание локальной функции помогло немного и удалило специфический код C # 7. Этот вопрос был очень веселым.

using C=System.Console;class P{static void Main(){string D="",L;int W=0,H=0,z=0,d,q,c,j,b;for(;(L=C.ReadLine())!=null;H+=W=L.Length)D+=L;var B=new int[H];for(d=W;(d=-d)>0||++z<H*H;)for(c=1,q=z%H;c<=z/H&q%W+c<W&q>=d&q<H+d&&D[q]==(d>0?92:47)&D[j=q+c]==(d<0?92:47);q-=d+1,c+=2){for(b=0;j>q;)b+=D[--j-d]==45?2:0;for(char h='-',e;c==z/H&b>c;C.WriteLine(h+" "+c/2))for(b=c++;b>1;j=q+=d+1,b-=2)for(;j<q+b;)B[j]=h=B[j]<1&h==45&(e=D[j++])!=47&e!=92&e>32?e:h;}}}

Попробуйте онлайн

Завершите программу, ожидайте, что ввод с пробелом будет стандартным, выходы - стандартным. Выходные данные - одна запись на строку с завершающим переводом строки. Файлы cookie выводятся в порядке увеличения размера, в первую очередь слева вверху. Мне потребовалось много времени, чтобы понять правила, но я думаю, что он прошел все приведенные примеры.

Он работает путем многократного поиска по всей сетке правильного Hamantaschen, увеличивая «разрешенный» размер. Для каждой ячейки она проверяет вверх и вниз, следуя \и /с обеих сторон, насколько это возможно. Если он замечает, что в следующей строке много записей -, а текущий размер равен «разрешенному», то он определяет заполнение и печатает запись.

Начинка определяется путем изучения всего пространства файла cookie и поиска «неиспользуемой» ячейки. При обнаружении неиспользуемой ячейки она помечается как использованная (так как мы увеличиваем допустимый размер, мы знаем, что мы являемся самым маленьким файлом cookie, в котором она содержится), и записываем заполнение.

Отформатированный и закомментированный код:

using C=System.Console;

class P
{
    static void Main()
    {
        //   32
        // - 45
        // / 47
        // \ 92
        // range 32..127 (no mod for you)

        string D="", // the whole map
            L; // initally each line of the map, later each line of output

        int W=0, // width
            H=0, // length (width * height)
            z=0, // search tracker
            d, // check direction (this is backwards (1 byte saving!))
            q, // check tracker
            c, // counter (truely, this is the distance from the right to the left)
            //M, // c max (now inlined as z/H)
            j, // horiontal tracker
            b; // - count, and reverse counter

        // read map and width
        for(;(L=C.ReadLine())!=null; // read a line, while we can
                H+=W=L.Length) // record the width, and increment height
            D+=L; // add the line to the map

        var B=new int[H]; // whether this filling has been used already (0 -> false, >0 -> true)

        for(d=W; // init direction
            (d=-d)>0|| // swap direction, else increment z (this allows us to run the check for the same z twice with opposite direction)
            ++z<H*H; // for all M, for all q (z<H -> M=z/H=0 -> no valid cookies, so we can safetly skip them)
            )
            for(//M=z/H, // c allow (now inlined)
                c=1, // reset counter
                q=z%H; // note position
                c<=z/H& // counter check
                // no need for a left check: if we run off the left end, then the right check will necessarily fail
                q%W+c<W& // right check
                q>=d& // high check
                q<H+d&& // low check (short-circuit lookups)
                D[q]==(d>0?92:47)&D[j=q+c]==(d<0?92:47); // /\ or \/ check, and set j=q+c
                    q-=d+1, // move left tracker
                    c+=2) // increase counter (move right tracker)
            {
                // count the number of '-' into b
                for(b=0; // zero b
                    j>q; // for each element in the row below
                        ) // empty
                    b+=D[--j-d]==45?2:0; // add 2 to b if we tap a '-'

                // j = q

                // check valid before looking up cHaracter (so we don't mark unused stuff as taken)
                // if we are at the current max count, and we have enough -, then we are valid and should be commited
                for( // this runs either one or zero times, we only have a for here (rather than an if) so we can ditch a pair of braces
                    char h='-', // default filling
                         e; // filling we are considering
                    c==z/H&b>c;
                        C.WriteLine(h+" "+c/2)) // print filling and count
                    // continuously compute character
                    for(b=c++; // count b backwards, starting from c (add 1 to c so we can /2 in print)
                        b>1;j=q+=d+1,b-=2) // count q backwards toward z%H (where q came from), and b backwards toward 1 (for each row)
                        for(;j<q+b;) // for each cell in row
                            B[j]= // mark cell as taken (h,e > 0)
                            h= // record filling
                                B[j]<1& // check cell not already used
                                h==45& // '-'
                                (e=D[j++])!=47& // '/'
                                e!=92& // '\'
                                e>32 // ' '
                                ?e:h; // take first filling we can
                    // c runs out after this (exists both loops), so no need to action
            }
    }
}

Выходы для 4 тестовых случаев:

testcase #1
. 2
. 2
@ 3
- 4
* 4

testcase #2
- 1
- 1
- 2
d 2
* 2
- 3

testcase #3
- 1
- 1
- 1
- 1
- 2
- 2
: 2

testcase #4
- 1
- 1
- 2
$ 2
# 2
- 3
x 4
- 4
VisualMelon
источник
Я поражен тем, насколько компактно это в C #! Отлично сработано!
Не то чтобы Чарльз
Единственный правильный ответ! У меня есть то , что это почти функциональна, но имеет несколько ошибок (но я бы не ставил перед собой в качестве победителя в любом случае)
Не то,