O videogame Minecraft é sobre colocar e remover diferentes tipos de blocos na rede inteira 3D que compõe o mundo virtual. Cada ponto de rede pode conter exatamente um bloco ou estar vazio (um bloco " aéreo " oficialmente). Neste desafio, nos preocuparemos apenas com um plano 2D vertical do mundo 3D e um tipo de bloco: obsidiana .
Quando a obsidiana forma o contorno de um retângulo vazio em um plano vertical, um portal inferior pode ser criado. O retângulo vazio pode ter qualquer tamanho, de 2 unidades de largura por 3 unidades de altura a 22 unidades de largura por 22 unidades de altura. Os cantos do retângulo não precisam ser delimitados em obsidiana, apenas os lados.
Por exemplo, suponha que X
seja obsidiana e .
vazia: (os números são apenas para fins de identificação e também estão vazios.)
...................................
..XXXX....XXXX....XXXXXXXXX........
..X..X...X....X..X.........X..XXXX.
..X.1X...X.2..X..X...3...X.X..X....
..X..X...X....XXXX.........X..X.6X.
..XXXX....XXXX...XXXXXXXXXXX..X..X.
.............X.4.X....X.5.X...XXXX.
.............X...X....X...X........
..............XXX......XXX.........
...................................
Esta grade contém 3 portais válidos:
- O Portal 1 é de 2 por 3 unidades, totalmente vazio e delimitado em obsidiana. Portanto, é válido.
- O Portal 2 é 4 por 3, totalmente vazio e delimitado em obsidiana. Portanto, é válido.
- O Portal 3 não está totalmente vazio. Portanto, é inválido.
- O portal 4 é 3 por 3, totalmente vazio e delimitado em obsidiana. Portanto, é válido.
- O Portal 5 é de 3 por 2 unidades, o que é muito pequeno. Portanto, é inválido.
- O portal 6 está faltando uma parte da borda. Portanto, é inválido.
Desafio
Escreva um programa ou função que capte essas representações de cadeias de grades de obsidiana e de vazio e imprima ou retorne o número de portais inferiores válidos presentes.
- A entrada pode ser de stdin ou arquivo ou argumento de função.
Você pode assumir que a entrada está sempre bem formada - ou seja, uma grade perfeitamente retangular de texto, com pelo menos 1 caractere de largura e altura, contendo apenas
X
e.
. Opcionalmente, você pode assumir que há uma nova linha à direita após a última linha.Se desejar, você pode usar dois caracteres ASCII imprimíveis distintos no lugar de
X
e.
.Obsidiana pode estar nas bordas da grade. Qualquer coisa além das fronteiras é considerada vazia.
Exemplo de entrada - a saída deve ser 4
:
................................................................
...................................XXXXXXXXXXXXXXXXXXXXXXXXX....
..XXXX....XXXX....XXXXXXXXX........X.......................X....
..X..X...X....X..X.........X..XXXX.X.......................X....
..X..X...X....X..X.......X.X..X....X.......................X....
..X..X...X....XXXX.........X..X..X..XXXXXXXXXXXXXXXXXXXXXXXX....
..XXXX....XXXX...XXXXXXXXXXX..X..X.X......................X..XXX
.............X...X....X...X...XXXX.X......................X..X..
.............X...X....X...X........X......................X..X..
..............XXX......XXX........XXXXXXXXXXXXXXXXXXXXXXXX...X..
..................................XX.........................XXX
Pontuação
O envio com o menor número de bytes vence.
Respostas:
Perl, 81
86Usando mais de um regexp.
A regexp para uma largura específica de um portal é muito mais simples que uma genérica:
X{$m}..{$n}(X\.{$m}X.{$n}){3,22}.X{$m}
ondem
está a largura do portal en
estátotal width - 1 - m
. A regexp deve ser colocada em uma declaração de largura zero,(?=...)
porque as correspondências podem se sobrepor. Então eu itero 21 vezes sobre essa configuração de regexp$n
e$.
."@-"
avalia a posição inicial da última correspondência (/.\n/
) que é a largura total - 1.$.
é usada como a outra variável conforme inicializada1
quando usada com-p0
.fonte
.
das células vazias (para não precisar escapar).Regex (sabor .NET),
182181145132126114104100989796 bytesReconhecimento de padrões de arte ASCII 2D? Parece um trabalho para regex! (Não.)
Sei que isso vai desencadear discussões intermináveis novamente sobre se os envios de regex são programas válidos ou não, mas duvido que isso possa superar o APL ou o CJam de qualquer maneira, para que não haja nenhum dano. (Dito isto, eles fazem passar o nosso teste die-hard para "O que é uma linguagem de programação?" .)
Isso leva a entrada como a sequência a ser correspondida e o resultado é o número de correspondências encontradas. Ele usa
_
no lugar de.
, porque eu teria que escapar do último. Também requer uma nova linha à direita.Você pode testá-lo ao vivo no RegexHero ou RegexStorm ). As correspondências serão as principais linhas de obsidiana dos portais. Se você encontrar um caso de teste em que ele falhe, entre em contato!
O que é essa feitiçaria?
A explicação a seguir pressupõe um entendimento básico dos grupos de balanceamento do .NET . A essência é que as capturas são pilhas no regex .NET - toda nova captura com o mesmo nome é inserida na pilha, mas também há sintaxe para capturar capturas dessas pilhas novamente, bem como sintaxe para capturar capturas de uma pilha e capturar push para outro ao mesmo tempo. Para uma imagem mais completa, você pode dar uma olhada na minha resposta no Stack Overflow, que deve cobrir todos os detalhes.
A ideia básica é combinar um padrão como:
Onde
n
está entre 2 e 22 (inclusive). O difícil é conseguir que todosn
e todosm
sejam iguais. Como os personagens reais não serão os mesmos, não podemos simplesmente usar uma referência anterior.Observe que o regex precisa incorporar novas linhas, que escreverei como
\n
a seguir.C #, 185 bytes
Aqui está uma função C # completa, apenas para tornar essa entrada válida. Está na hora de escrever um "intérprete" de linha de comando para expressões regulares do .NET ...
fonte
^
(ou qualquer caractere não utilizado) para(?!)
.Python, 219 bytes
Melhor do que Java, mas, menino, os quíntuplos loops aninhados doem. O
for/in
pode ser um pouco compressível usando%s
substituição, mas não iria economizar muito.Expandido:
fonte
Java, 304 bytes
Isso é muito mais longo do que uma expressão regular. Ele simplesmente itera sobre todos os quadrados possíveis na entrada. Se for um portal válido, ele incrementa um contador em 1. Em seguida, retorna o contador. Provavelmente isso pode ser jogado muito mais longe. Todas as sugestões são bem-vindas.
Recuado:
Programa completo:
fonte