Escreva o programa mais curto para transformar qualquer peça de arte ASCII em uma cena de neve animada que comece a se formar a partir da neve que cai ( exemplo de JavaScript sem golfe ) atualizado pela última vez em 2011-12-19).
Especificação de entrada : Seu programa deve aceitar combinações arbitrárias de espaços, asteriscos e novas linhas. A entrada conterá no máximo 23 linhas e 80 caracteres por linha. Não haverá linhas vazias, mas as linhas podem consistir apenas em espaço em branco. Uma única nova linha à direita será incluída e deve ser ignorada.
Saída : Saída de caracteres ASCII (espaços, asteriscos) e códigos de controle (retornos de carro, alimentações de linha, códigos de escape ANSI, etc.) para o console de texto do sistema operacional ou emulador de terminal até o usuário finalizar manualmente o programa. Você pode supor que a janela do terminal tenha 80x24 caracteres se o seu sistema operacional permitir essa configuração.
Regras :
- A animação deve ser suave e rápida (preferencialmente 15 qps).
- A densidade da neve deve estar entre 5% e 15%.
- Não mais do que uma tela de neve pode rolar por segundo. (Isso significa que não é possível adicionar mais de 24 linhas de neve nova em um segundo período de tempo.)
- A neve não deve exibir nenhum padrão óbvio quando entra na parte superior da tela; deve parecer aleatório.
- O programa deve preencher todas as linhas da tela com neve o mais rápido possível quando for iniciado; o preenchimento inicial das linhas individuais da tela não deve ser óbvio para o visualizador.
- O canto inferior esquerdo da arte ASCII de entrada deve estar no canto inferior esquerdo da tela (Figura 1 para maiores esclarecimentos).
- A área dentro ou sob a arte ASCII não deve ser permanentemente preenchida com asteriscos. No entanto, os asteriscos podem (mas não precisam) rolar por essa área.
- A neve não deve acumular-se na parte inferior da tela ou em cima da neve existente, exceto conforme mostrado na entrada.
- Os espaços inferiores devem ser preenchidos antes dos superiores, pois o preenchimento de espaços na ordem oposta faz com que a animação da árvore de Natal pareça muito diferente da saída do meu código original. (adicionado 20-12-2011)
Boas festas!
Figura 1: áreas rotuladas de uma tela 80x24
---------------------------New snow added on this line--------------------------
|
|
----------------------------------------------------------+ |
**** | |
Snow MUST fall Snow MAY fall ----------------> **** | |
through this through these **** **** | Snow MUST fall |
area. areas of a **** **** | through this |
completed \---------> **** ****| area. |
ASCII art scene. \ *** **** ****| |
area \ \ ******* **** ****| |
\ \ ******** *** ***| (ALL CAPS terms |
(located in \ \--> ********* *** | have standard |
lower left \ ******* ****** MAY | RFC 2119 |
corner of \ ************* ** fall | meanings.) |
screen) \ *********** here | |
*** +---> **** *** | |
*** | **************** *** | |
| Snow MUST fall *** | **************** *** | |
| through this *** +---> *** | |
| area. *** | **************** *** | |
--+---------------------+*** +---> ***+----+------------------+--
| Snow MUST NOT |****************************| Snow MUST NOT |
V accumulate here. |****************************| accumulate here. V
Entradas de Exemplo
Código Golf Banner
****** ******* ******** ******** ****** ******* ** ********
** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ****** ** **** ** ** ** ******
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** ** **
****** ******* ******** ******** ****** ******* ******** **
Logotipo do estouro de pilha
****
****
**** ****
**** ****
**** ****
*** **** ****
******* **** ****
******** *** ***
********* ***
******* ******
************* **
***********
*** **** ***
*** **************** ***
*** **************** ***
*** ***
*** **************** ***
*** ***
****************************
****************************
Árvores de Natal
*
*** *
* ***** ***
*** ******* * *****
***** ********* *** *
* *********** *****
* ************* *******
* *** *************** * *
*** ***** ***************** ***
***** ******* ******************* *****
******* * ********************* *******
********* * *********
* *
Respostas:
Perl, 196/23 caracteres
Essa solução difere do seu exemplo de JS, pois o padrão é preenchido de cima para baixo em vez de de baixo para cima, mas presumo que não há problema, pois você não disse nada sobre isso nas regras.
Uma redução trivial de 1 caractere pode ser obtida substituindo-se
\e
por um caractere ESC literal, mas isso torna o código muito mais difícil de ler e editar.Update: Eu fiz gerir para chegar a uma versão que enche o padrão de até inferior, e não permite que a neve a cair através das partes cheias do padrão, como no exemplo de implementação JS, ao custo de 43 caracteres extras:
Substituir
($s[$_]&=~$f[$_])
por apenas$s[$_]
economizaria 11 caracteres, deixando a neve cair passar pelas partes preenchidas do padrão (que corresponde à especificação, mas não à implementação de exemplo).OK, como ainda continuo liderando a corrida depois de uma semana, acho que devo explicar como minha solução funciona para incentivar mais concorrência. (Nota: Esta explicação é para a versão de preenchimento de cima para baixo de 196 caracteres. Eu posso alterá-la para incluir a outra versão posteriormente.)
Primeiro de tudo, o grande truque em que minha solução se baseia é que, devido à maneira como os códigos de caracteres ASCII são organizados, os 1 bits no código ASCII de um espaço são um subconjunto daqueles no código de um asterisco.
Assim, as seguintes expressões são verdadeiras:
" " & "*" eq " "
e" " | "*" eq "*"
. É isso que me permite usar operações de string bit a bit para combinar as partes estáticas e móveis da cena sem ter que passar por caracteres individuais.Então, com isso fora do caminho, vamos revisar o código. Aqui está uma versão descodificada:
A primeira linha configura as matrizes
@f
(para "fixo") e@p
(para "padrão").@f
formará a parte fixa da tela e começará a conter nada além de espaços, enquanto@p
, que não é mostrado diretamente, contém o padrão de entrada; À medida que a animação prosseguir, adicionaremos mais e mais asteriscos@f
até que eventualmente pareça@p
.Especificamente,
@f = ($" x 80) x 23
define@f
para 24 strings de 80 espaços cada. ($"
é uma variável Perl especial cujo valor padrão é apenas um espaço.) Em seguida, pegamos essa lista, anexamos as linhas de entrada usando o operador readline<>
, pegamos as últimas 24 linhas dessa lista combinada e atribuímos a@p
: this is uma maneira compacta de preencher@p
linhas em branco para que o padrão apareça onde deveria. Por fim, inserimoschomp
as linhas de entrada@p
para remover as novas linhas finais, para que não causem problemas mais tarde.Agora, vamos olhar para o loop principal. Acontece que
{...;redo}
é uma maneira mais curta de escrever um loop infinito do quewhile(1){...}
ou mesmofor(;;){...}
, especialmente se conseguirmos omitir o ponto-e-vírgula antesredo
porque ele segue imediatamente umif
bloco.A primeira linha do loop principal apresenta a matriz
@s
(para "neve", é claro), à qual ela precede uma sequência aleatória de 80 caracteres com 90% de espaços e 10% de asteriscos em todas as iterações. (Para salvar alguns caracteres, eu nunca retiro linhas extras no final da@s
matriz, por isso ela fica cada vez mais longa. Eventualmente, isso fará com que o programa pare, pois a matriz fica muito longa para caber na memória, mas isso demorará muito mais tempo do que a maioria das pessoas assistiria a essa animação. Adicionar umapop@s;
declaração antes deselect
consertar isso ao custo de sete caracteres.)O restante do loop principal é agrupado em um
if
bloco, para que seja executado apenas quando a@s
matriz contiver pelo menos 24 linhas. Essa é uma maneira simples de cumprir as especificações, que exige que toda a tela seja preenchida com neve caindo desde o início e também simplifica um pouco as operações bit a bit.Em seguida, vem um
foreach
loop, que na versão golfed é na verdade uma única declaração com umfor 0..23
modificador. Como o conteúdo do loop provavelmente precisa de explicações, vou descompactá-lo um pouco mais abaixo:Primeiro,
$_
é a variável do contador de loop padrão no Perl, a menos que outra variável seja especificada. Aqui, ele varia de 0 a 23, ou seja, ao longo das 24 linhas no quadro de exibição.$foo[$_]
denota o elemento indexado por$_
na matriz@foo
.Na primeira linha do loop descolado, imprimimos uma nova linha (convenientemente obtida da
$/
variável especial) ou, quando$_
igual a 0, a string"\e[H"
, onde\e
denota um caractere ESC. Este é um código de controle de terminal ANSI que move o cursor para o canto superior esquerdo da tela. Tecnicamente, poderíamos omitir isso se assumirmos um tamanho de tela específico, mas eu o mantive nesta versão, pois significa que não preciso redimensionar meu terminal para executar a animação.Na
$t = $f[$_]
linha, apenas salvamos o valor atual de$f[$_]
uma variável "temporária" (daí$t
) antes de potencialmente alterá-lo na próxima linha, onde$s[$_] & $p[$_]
fornece a interseção (AND bit a bit) da neve que cai e o padrão de entrada e os|=
ORs do operador isso na linha de saída fixa$f[$_]
.Na linha abaixo disso,
$t ^ $f[$_]
fornece o XOR bit a bit dos valores anteriores e atuais de$f[$_]
, ou seja, uma lista dos bits que alteramos na linha anterior, se houver, e negar uma das seqüências de entrada~
nega a saída. Portanto, o que obtemos é uma máscara de bits com todos os bits definidos como 1, exceto aqueles que acabamos de adicionar$f[$_]
na linha anterior. ANDing nesse bitmask$s[$_]
remove esses bits dele; de fato, isso significa que, quando um floco de neve caindo preenche um buraco no padrão fixo, ele é removido da matriz de neve que cai.Finalmente,
print $f[$_] | $s[$_]
(que na versão golfed é implementada apenas ORing as duas linhas anteriores juntas) apenas imprime a união (OR bit a bit) dos flocos de neve fixos e móveis na linha atual.Mais uma coisa a explicar é a parte
select '', '', '', 0.1
inferior do loop interno. Esta é apenas uma maneira klugy de dormir 0,1 segundos no Perl; por alguma razão histórica bobo, o padrão Perlsleep
comando tem uma segunda resolução, e importar um melhorsleep
doTime::HiRes
módulo leva mais caracteres do que abusar de 4-argselect
.fonte
say
), ao custo de 2 caracteres extras. Eu acho que não posso alterar a ordem de preenchimento com muita facilidade; minha implementação está fundamentalmente ligada a ela.HTML e JavaScript, 436 caracteres
Anexe-o à entrada:
Veja executar para cada exemplo: código de golfe , logotipo Stack Overflow , árvores de Natal . Os usuários do Internet Explorer precisam executar a versão 9 e definir o "Modo de Documento" como "IE9 standards" (usando as ferramentas de desenvolvedor F12) para que esse envio funcione corretamente.
fonte
Python, 299 caracteres
Isso deve estar de acordo com as regras, assumindo que a nova linha esteja incluída no limite de 80 caracteres.
fonte
a
e, portanto, atrapalha a indexação. Eu apenas tentei isso, e parece que a substituição%e
com%e.rstrip()
na linha 6 corrige o problema. (Claro, pode muito bem haver uma correção mais curto, eu não sou bom em Python golfe.)Java, 625 caracteres
Uma solução simples em Java.
fonte
"\033[H"
deve fazê-lo).