Introdução
Esse desafio é inspirado no Grime , minha linguagem de correspondência de padrões 2D. Basicamente, você recebe uma "gramática" que descreve grades bidimensionais de caracteres e seu trabalho é gerar uma grade de acordo com a gramática. Além disso, a grade deve ser a menor possível em um certo sentido fraco.
Entrada
Sua entrada é uma sequência que contém caracteres ASCII em minúsculas e os símbolos |
e -
. Para simplificar, a entrada não contém caracteres minúsculos repetidos. A sequência é uma especificação para uma classe de grades retangulares de caracteres e é analisada da esquerda para a direita usando uma pilha da seguinte maneira.
- Dado um caractere minúsculo
c
, empurre para a pilha umam×n
grade do caracterec
, para qualquerm, n ≥ 1
. - Dado um cano
|
, coloque duas gradesA
eB
da pilha (B
estava no topo) e empurre a gradeAB
obtida concatenandoB
à direita deA
. Isso requer issoA
eB
tem altura igual. - Dado um hífen
-
, retire duas gradesA
eB
da pilha (B
estava no topo) e empurre a gradeA/B
obtida concatenandoB
para o final deA
. Isso requer issoA
eB
tem largura igual.
É garantido que, para algumas escolhas feitas m
e n
feitas durante o processo de análise (que podem ser diferentes para cada letra), a especificação de entrada descreva corretamente algum retângulo, que é deixado na pilha no final.
Resultado
Sua saída é uma grade retangular de caracteres especificada pela entrada. A grade deve ser mínima no sentido de que remover qualquer linha ou coluna a tornaria inválida. Você pode retornar uma string separada por nova linha (com ou sem uma nova linha à direita), uma matriz 2D de caracteres ou uma matriz de cadeias, o que for o formato mais conveniente.
Observe que você não é obrigado a processar a entrada exatamente como descrito acima; a única coisa importante é que sua saída esteja correta.
Exemplo
Considere a especificação
par-s||e-
Primeiro, escolhemos empurrar um 1×2
retângulo de p
, e 1×1
retângulos de a
e r
(a razão para isso ficará clara mais tarde). Então, nós estourar os a
e r
retângulos, e empurre a concatenação verticais
a
r
Em seguida, pressionamos um 1×2
retângulo de s
, pop e o retângulo acima, e pressionamos sua concatenação horizontal
as
rs
Em seguida, colocamos esse retângulo e o p
retângulo e pressionamos sua concatenação
pas
prs
Por fim, pressionamos um 3×1
retângulo de e
, pop e o retângulo acima, e pressionamos a concatenação vertical
pas
prs
eee
Esta é a saída do programa, ou pelo menos uma das possibilidades. Observe que, embora
ppas
ppas
pprs
eeee
também é gerado pela especificação, não é uma saída válida, pois muitas das linhas e colunas podem ser removidas.
Como um exemplo mais sutil, considere
co|m|p|il|e|r|-
Esta especificação gera o retângulo
comp
iler
que é uma saída válida. No entanto, também gera
commp
iiler
o que também é válido, pois nenhuma linha ou coluna pode ser removida sem a invalidação.
Regras
Você pode dar um programa completo ou uma função. A contagem de bytes mais baixa vence e as brechas padrão não são permitidas.
Casos de teste extras
Você pode usá-los para testar seu programa.
Input:
a
Output:
a
Input:
co|mp|l|-ex|i|f|-y|
Example output:
cccoy
mplly
exify
Input:
ja-r|g-o|ni-|ze|d-|
Example output:
jronze
arondd
ggoidd
Input:
un|co|p-yr|i|gh-t-ab|-|le-||-
Example output:
unnnnnnn
coyriggl
ppyrihhe
ppyritte
ppyriabe
fonte
n
em
são escolhidos de forma não determinística. É garantido que existam valores adequados para eles, mas é tarefa do seu programa encontrá-los.un|co|p-|yr|i|gh--t-ab|-|le-||-
é impossível ser válido. O último-
tem uma área de 2, enquanto há apenas 1 elemento na pilha.Respostas:
K,
123110 bytesEu usei uma abordagem semelhante à solução de cartão_box.
Este programa é uma série de definições auxiliares seguidas por uma função tácita que aceita uma string como argumento correto. Reformatação para facilitar a leitura e atribuir a função final como
f
:Use exemplo:
Testado usando Kona, mas também funcionará em OK se você substituir o
:
na definição def
por a$
- k5 alterou a sintaxe de "cond".Um ponto-chave é reconhecer que fazer um apêndice vertical é a transposição do apêndice horizontal da transposição de ambas as matrizes. (Veja a definição
v
.) Acho que ainda há espaço para espremer alguns caracteres aqui e ali. Se alguém estiver interessado em uma explicação mais detalhada, posso fornecer uma.editar:
Atualizado o programa na parte superior desta entrada. Versão não destruída:
As otimizações de tamanho notáveis incluem o uso de "aplicação de ponto"
a
, substituindo o "cond" pela indexação de lista emf
(menos eficiente, mas mais curta) e substituindo os termos do formulárioa[b;c]
paraa[b]c
onde permitido pelo agrupamento. Como não estou mais usando "cond" ou quaisquer primitivas diferentes entre k3 e k5, esta versão agora funciona em OK sem modificações.fonte
Prolog, 539 bytes
Explicação
Começamos com predicado
g
, que pega uma string, converte-a como uma lista de caracteres e chamamos op
predicado (analise) com uma pilha vazia como segundo argumento.O predicado se
p
chama recursivamente com uma pilha adequadamente modificada (procure[H|T]
padrões de desestruturação e construtor). Quando chamado no caso base, onde a lista de entrada está vazia,p
imprime o elemento exclusivo da pilha. Se a pilha tiver menos ou mais de um elemento neste momento, significa que temos uma sequência de entrada vazia, uma sequência de entrada incorreta ou um bug (com uma sequência vazia, o predicado falha (Prolog dizNo
), mas nada é impresso, o que é bom, já que não devemos imprimir nada para cadeias vazias).Resolução
A pilha contém uma descrição dos retângulos construídos, denotados
S:W:H
, ondeS
é uma representação simbólica do retângulo,W
sua largura eH
altura (note queA:B
é um açúcar sintático para a:(A,B)
tupla com um functor chamado:
; é mais curto para escrever do que ter uma tupla com notação de prefixo).Com
A
eB
especificações de sub-retângulo,S
pode ser:h(A,B)
: concat horizontal de A e Bv(A,B)
: concat vertical de A e Bf(C)
: preencha com C, onde C é um código de caractereAs larguras e alturas das grades são variáveis de programação de restrição: durante a concatenação vertical (resp. Horizontal), a largura (resp. Height) dos retângulos manipulados é unificada, enquanto a altura resultante (resp. Width) é restringida como a soma de a altura de cada sub-grade (resp. largura).
A etapa de rotulagem no final do processo instancia variáveis, respeitando as restrições, usando os valores mínimos possíveis (essa é uma propriedade da ordem pela qual as soluções são tentadas).
Eu poderia ter obtido uma resposta mais curta usando o mesmo raciocínio que é feito em outras respostas, sem restrições, mas agora é tarde demais.
Observe também que, como o domínio padrão das variáveis está definido como
1..100
, há uma limitação sobre os possíveis tamanhos de grades. O limite superior pode ser alterado se necessário. As implicações de desempenho disso são que pode levar muito tempo para determinar que uma solução específica não admite solução. Eu disse " poderia " porque é provável que as restrições afinem drasticamente a pesquisa exponencial. Se você encontrar uma string de entrada difícil / dispendiosa para rejeitar, compartilhe.Impressão
A parte de impressão é interessante porque existe um tipo de algoritmo de projeção de raios sobre a estrutura: eu itero sobre cada célula da grade resultante, de ponto
(1,1)
a ponto(W,H)
e chamo ow
predicado para imprimir o conteúdo da grade na árvore principal, em neste local (é claro, uma nova linha é impressa após o processamento de cada linha).Em
w
, as posições são relativas à grade atual (a grade raiz define coordenadas absolutas).Ao imprimir uma
h(A,B)
estrutura no ponto(X,Y)
, imprimo incondicionalmente nos dois ramos:A
no ponto(X,Y)
, eB
no ponto(H,Y)
, ondeH
éX
menos a largura deA
.Os galhos das folhas da árvore da grade
f(C)
, finalmente, imprimem o caractereC
, se a localização relativa estiver dentro da grade, ou não fazem nada. É assim que posso imprimir o conteúdo da grade no fluxo de saída, de cima para baixo, da esquerda para a direita. Nenhuma matriz real é produzida.Testes
Teste de corrida:
fonte
No actual arrays are produced.
é assim que deve ser feito. Exagero neste caso, como a gramática é muito simples e existem atalhos.Python 2.7, 259
g
é uma função que aceita uma especificação e fornece uma matriz 2D de caracteres. Se você deseja uma versão mais amigável, adicione esta linha para obter uma especificação do stdin e imprimir a grade:Casos de teste
Explicação
A estratégia é simples: se uma grade
G
é válida para uma especificaçãoS
, a repetição da coluna mais à direitaG
também fornece uma especificação válida paraS
, e o mesmo ocorre com a repetição da linha inferior (a prova disso é por indução estruturalS
). Portanto, quando queremos concatenar dois retângulos, podemos simplesmente acrescentar a última coluna / linha da menor até que correspondam ao tamanho (é isso que a função p faz).fonte
Haskell,
388367352 bytesUso:
f "par-s||e-"
->["pas","prs","eee"]
Teste executado com impressão bonita:
Como funciona: a função
#
analisa a string de entrada na estrutura da árvore,C
que é uma folhaL
contendo o caractere a ser impresso ou um nóN
.N
pode ser a) uma junção lado a lado (t==2
), b) uma junção de cima para baixo (t==1
) ou c) uma única letra quadrada (t==0
). Todos os nós têm um campo de largura e altura e um filho esquerdo e direito. Após a análise,p
imprime o nó raiz restante ajustando recursivamente o tamanho (largura x altura) dos nós filhos e unindo-os.Edit: output como uma lista de linhas em vez de uma bonita impressão
fonte
JavaScript (ES6), 283
295Editar Agora, esta solução JS (altamente concentrada) é pelo menos menor que a solução Python de referência (bastante adaptável).
Semelhante a cartão_papel, apenas repetindo a coluna mais à esquerda ou a linha mais alta.
Ungolfed Esta é a minha primeira solução, ungolfed.
Teste no console Firefox / FireBug
Resultado
fonte
Python 3, 251 bytes
Aqui está a resposta de referência que prometi, jogou um pouco mais.
Este é um programa completo que pega a string de STDIN e imprime em STDOUT. A abordagem é a mesma que a de paper_box: pressione uma matriz 1x1 para um caractere e duplique as linhas, se necessário, para concatenação.
Explicação detalhada
T
transpõe uma determinada lista de listas. A maior parte do trabalho é feitazip(*m)
trocando linhas por colunas; o restante é apenas convertendo o resultado em uma lista de listas, poiszip
retorna um gerador de tuplas.E(a,b)
retornaa
com seu primeiro elemento repetido vezes suficientes para corresponder ao comprimento deb
. Observe que multiplicar uma lista por um número negativo fornece a lista vazia; portanto, seb
for menor quea
, isso retornaráa
.H(a,b)
retorna a concatenação horizontal dea
eb
, a mais curta sendo prolongada,E
se necessário.s
é a pilha.for
loop, iteramos sobre a string de entrada e substituímoss
por um novo valor: se for|
(maior quez
), exibimos dois valores e pressionamos seusH
; se for-
(menor quea
), exibimos dois valores, transpor, alimentarH
, transponha novamente e empurre o resultado; caso contrário, empurre uma matriz 1x1 com a letra.s
.fonte