Conte o hamantaschen ASCII!

18

Hoje é Purim, cujo costume é distribuir biscoitos em forma de triângulo com recheio chamado hamantaschen (singular: hamantasch ). Outro costume é beber muito.

Eu não sou o padeiro mais perfeito ... Eu tenho tantos hamantaschen de tamanho irregular para dar e tantos amigos para dar! Se eu lhe enviar uma foto dos meus cookies, você pode me dizer quantos eu tenho de que tamanho e tamanho? Mas como é Purim e eu estou bêbado demais para ler muito código, ele precisa ser o menor possível.

Definições

Tamanho

Um hamantasch pode ser de qualquer tamanho . O menor hamantasch é do tamanho 1 e se parece com o seguinte:

/\  --
--  \/

Às vezes, vários hamantaschen podem se sobrepor . A forma abaixo conta como dois hamantaschen (um tamanho 1, um tamanho 2):

 /\
/\ \
----

Alguns hamantaschen têm recheio . Isso será indicado preenchendo todo o espaço em branco interno com um caractere. Observe que o tamanho 1 hamantaschen não pode ter enchimento.

Vamos nomear hamantaschen com base no tamanho e preenchimento. Vamos usar o formato <filling> <size>e, se não estiver preenchido, - <size>(você pode usar um espaço em vez de a -, mas a margem não é a mesma).

Aqui estão a . 2, a . 4e a - 3:

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

Estes são a @ 3, a . 2e a - 4:

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

Aqui está algo mais difícil. Veja como o & 2recheio tem menos do que você esperava devido à inclinação da sobreposição - 3? Possui a - 1, & 2a - 3e a & 4:

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

Entrada

Você receberá um arquivo de texto ou uma única sequência de hamantaschen (nova linha à direita opcional e espaço em branco à direita opcional para ser par).

Limites

  • Você pode esperar que a string seja válida - ou seja, todo caractere que não seja um espaço em branco contribui para um hamantasch deliciosamente doce (por que desperdiçar massa?).
  • Você também pode esperar que ele seja devidamente preenchido ou não - ou seja, cada homentasch será totalmente preenchido com um carácter ASCII consistente - ASCII 32 para preencher, ou qualquer coisa 32..127 para cheia (excluindo /, \e- ).
  • Estes hamantaschen não são empilhados em 3 espaços. Tudo /e \será visível. Tudo o -que não é bloqueado por /e\ será visível. O preenchimento vem muito por último.
  • Todos os hamantaschen terão pelo menos metade da sua linha horizontal (arredondamento para cima) visível.
  • Qualquer bloco contíguo de preenchimento preenche apenas o menor hamantasch que o rodeia.

Resultado

Retorne uma lista de "nomes" de todas as hamantaschen que podem ser encontradas atendendo aos critérios acima. A saída pode estar na forma que você desejar (uma string, um hash, stdout, etc).

Casos de teste

Caso de teste nº 1

Entrada nº 1:

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

Saída 1:

. 2
. 2
- 4
@ 3
* 4

Caso de teste nº 2

Entrada nº 2:

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

Saída # 2:

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

Teste # 3

Entrada nº 3:

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

Saída # 3:

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

Teste # 4

Entrada nº 4:

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

Saída 4:

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

Caso de teste inválido nº 5

Entrada:

/\
\/

Resultado:

Você não precisa lidar com isso.

Não que Charles
fonte
Que tal um caso de teste no qual hamentaschen estão sobrepostas, mas não têm a mesma linha horizontal? Um pode até bloquear a linha horizontal do outro.
haskeller orgulhoso
@proudhaskeller Ok, pronto. No entanto, e acabei de colocar isso no texto, este é 2 espaços. Nós vamos sempre ver tudo /e \ , e -será sempre trunfo enchimento.
Não que Charles
2
@EasterlyIrk Também há outras coisas importantes - ler o Livro de Ester (e vaiar os bandidos), dar aos pobres - e coisas menos fundamentais, como vestir fantasias.
Não que Charles
1
tornou relevante novamente!
downrep_nation
1
Com base em uma coluna inicial de zero, todas as suas colunas de vértice, exceto (1,0), estão desativadas por +1. Ainda assim, eu sei o que você quer dizer e discordo. Que indicação existe (2, 2)no centro superior de um - 2e não apenas no canto superior direito e esquerdo dos dois lados superiores - 1? Nada que eu possa ver. E a mesma lógica se aplica a (3, 2). A menos que você deseja adicionar uma regra para assumir máxima hamantaschen possível ...
Michael Plotke

Respostas:

4

C #, 496 452 bytes

Edit: encontrou um bug com verificação de limites ... mas também distribuiu uma carga de bytes que foi forçada a entender meu próprio código. Desenrolar a função local ajudou um pouco e removeu o código específico do C # 7. Esta pergunta foi muito divertida.

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

Experimente Online

Programa completo, espera entrada preenchida com espaço para entrada padrão, saídas para saída padrão. A saída é uma entrada por linha, com avanço de linha à direita. Os cookies são gerados em ordem crescente de tamanho, primeiro no canto superior esquerdo. Levei um bom tempo para entender as regras, mas acho que passa em todos os exemplos fornecidos.

Ele funciona pesquisando repetidamente em toda a grade por Hamantaschen válido, aumentando o tamanho 'permitido'. Para cada célula, ele verifica para cima e para baixo, seguindo o \e /em ambos os lados o máximo possível. Se perceber que a próxima linha tem muitas- , e o tamanho atual é o tamanho 'permitido', determina o preenchimento e imprime a entrada.

O preenchimento é encontrado explorando todo o espaço do cookie, procurando uma célula 'não utilizada'. Quando uma célula não utilizada é encontrada, ela é marcada como usada (já que aumentamos o tamanho permitido, sabemos que somos o menor cookie que o contém) e registramos o preenchimento.

Código formatado e comentado:

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

Saídas para os 4 casos de teste:

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
fonte
Estou surpreso com o quão compacto isso é em C #! Bem feito!
Não que Charles
A única resposta válida! Eu tenho algo que é quase funcional, mas tem alguns erros (mas eu não iria definir-me como vencedor de qualquer maneira)
Não que Charles