A Casa do Papai Noel

16

A Casa do Papai Noel

Nota: Este é o primeiro desafio que tentei definir. Já passou pela Sandbox, no entanto, se você encontrar algo errado com ela, por favor, não diminua o voto, mas deixe um comentário para que eu possa melhorá-la.

fundo

Há um velho quebra-cabeça infantil, onde o desafio é desenhar uma caixa com um teto e uma cruz no meio, sem levantar a caneta do papel ou passar por cima de qualquer linha duas vezes.

Na Alemanha, é conhecida como "das Haus des Nikolaus" ou "A Casa do Papai Noel". Sinceramente, não me lembro como costumávamos chamá-lo. Para quem não está familiarizado com o quebra-cabeça, todos os detalhes estão disponíveis aqui .

Aqui está uma representação de arte ASCII da casa.

 /\
/__\
|\/|
|/\|
----

Desafio

Escreva um programa ou função para desenhar a Casa do Papai Noel em qualquer idioma de sua escolha.

Parece fácil demais? Bem, aqui está o problema. Ele também deve produzir cada estágio do desenho e cumprir as regras do quebra-cabeça. Seu programa não é obrigado a receber nenhuma entrada. A casa pronta deve ter exatamente a aparência mostrada acima.

De acordo com o site acima, existem 44 soluções possíveis. Você pode usar qualquer um deles. Este é um desafio de arte ASCII, portanto você não precisa calcular a solução, mas apenas desenhá-la.

Resultado

Um exemplo da saída necessária de uma das 44 soluções é mostrado abaixo:

---- 

 \
  \
----

 __
 \
  \
----

  \
 __\
 \
  \
----

 /\
/__\
 \
  \
----

 /\
/__\
|\
| \
----

 /\
/__\
|\/
|/\
----

 /\
/__\
|\/|
|/\|
----

Regras

  • Eu adicionei uma nova linha extra entre cada saída esperada para tentar tornar os requisitos mais claros. Isso é opcional. Qualquer número de linhas em branco entre cada saída é permitido.
  • Sua saída deve consistir apenas nos caracteres /, \, -, _ e espaço, como mostrado acima. Espaços à direita são permitidos.
  • Cada linha do seu desenho deve continuar do final da linha anterior e você não pode repetir nenhuma linha.
  • Falhas padrão proibidas.
  • Você não é obrigado a emitir a rima mencionada no link acima.
  • Este é um código de golfe, então a resposta mais curta em bytes será a vencedora.

Resultado

Algumas ótimas respostas, agradecimentos e respeito a todos que postaram. Eu disse a contagem de bytes mais baixa, mas marquei como resposta principal não apenas para isso, mas também para a grande explicação do código. Nice @Dennis.

ElPedro
fonte
Isso poderia ter passado algum tempo na caixa de areia . Tente adicionar um parâmetro para o tamanho da casa - ou o número de casas concatenadas (ou ambas). Acho muito fácil como é. Você também pode adicionar a rima ao seu exemplo de saída - ou não mencioná-lo. Acho esse gif legal ou esse .
Titus
4
@Titus Obrigado pelo feedback. Minha intenção não era criar um desafio particularmente difícil, mas criar um que fosse facilmente praticável e, assim, encorajar o maior número possível de pessoas a propor soluções. Aceito suas sugestões para minha próxima tentativa.
ElPedro 17/09/16
1
Minha culpa; Eu estava esperando coisas muito complexas para a arte ascii. :) Mas ainda gosto dos gifs.
Titus
Os gifs são arrefecer e eu também gosto da idéia de incluir a rima também em uma escolha de linguagem :)
ElPedro

Respostas:

10

Geléia , 40 39 36 bytes

“ḥ%DtƊVḍI’ḃ9W;“|_/-\/\|‘Ė¤y@\FỌ»⁶s4Y

Experimente online!

Como funciona

“ḥ%DtƊVḍI’

é um literal bijective base-250; cada caractere corresponde ao seu ponto de código na página de códigos de Jelly . O resultado é o número inteiro 13192938935880491074 .

          ḃ9

converte o número inteiro gerado em base bijetiva 9, produzindo a matriz inteira
[9, 6, 7, 9, 6, 2, 2, 7, 1, 5, 3, 8, 1, 3, 5, 8, 4, 4, 4, 4] . Os números inteiros correspondem à ordem do traçado, com exceção de 9 , que indica um espaço.

            W

agrupa a matriz gerada em uma matriz singleton, que será necessária para anexá-la à matriz que geraremos agora.

              “|_/-\/\|‘Ė¤

funciona da seguinte maneira. ¤combina os dois elos à esquerda em uma cadeia niládica. O primeiro, “|_/-\/\|‘produz os pontos de código dos caracteres especificados, produzindo [124, 95, 47, 45, 92, 47, 92, 124] . Em seguida, Ėenumera os pontos do código, produzindo
[[1, 124], [2, 95], [3, 47], [4, 45], [5, 92], [6, 47], [7, 92] [8, 124]] . A par [n, c] significa que o n th acidente vascular cerebral será o de caracteres ASCII com ponto de código c .

             ;

concatena as matrizes geradas. O resultado é a matriz
[[9,6,7,9,6,2,2,7,1,5,3,8,1,3,5,8,4,4,4,4], [1.124 ], [2,95], [3,47], [4,45], [5,92], [6,47], [7,92], [8,124]] .

                          y@\

executa uma redução cumulativa (ou seja, mostrando todas as etapas intermediárias), usando transliteration ( y) com argumentos trocados ( @). Na primeira etapa, por exemplo, substituímos 1 na matriz original por 124 , que é o ponto de código do caractere | .

                             FỌ

nivela o resultado e substitui todos os pontos de código pelos caracteres ASCII correspondentes. Em todas as etapas, isso gerará alguns caracteres não imprimíveis com os pontos de código 1 a 9 .

                               »⁶

leva o máximo de caracteres pelo caractere de espaço, substituindo todos os caracteres não imprimíveis por espaços.

                                 s4Y

divide a string gerada em pedaços de comprimento quatro e os une a um avanço de linha como separador.

Dennis
fonte
2
Uau. Simplesmente apenas uau. +1
ElPedro 17/09/16
Mas espere, esses são bytes?
Leif Willerts
1
@LeifWillerts Sim. Para evitar caracteres não imprimíveis, o Jelly usa uma página de código personalizada que codifica os 256 caracteres que entende como um único byte cada. O link de bytes no cabeçalho aponta para ele.
Dennis
Desculpe, então, por não descobrir o clique nesse link: D
Leif Willerts
Ganha tanto pela explicação quanto por qualquer coisa. Respeito.
ElPedro 21/09
13

Javascript (ES6), 119 116 96 92 91 bytes

for(i=8;i--;)console.log(`834
3554
2610
2160
7777`.replace(/./g,c=>'|/|/\\_\\- '[c<i?8:c]))

Arnauld
fonte
Boa resposta. Eu tinha a sensação de que o Javascript estaria lá ou por aí :-)
ElPedro
Desculpe pelas várias edições. Não devo postar antes do segundo café.
Arnauld
Várias edições são boas. É bom ver a contagem de bytes diminuindo.
ElPedro 17/09
Existe algum sentido em ter duas cópias idênticas do código em sua resposta?
Neil
@ Neil - vou manter apenas um até encontrar um bom motivo para ter dois deles. ^^
Arnauld
9

Lote, 356 344 341 337 bytes

@set s=@set "
%s%g=@goto 1
%s%r=
%s%c=
%s%u=|
%s%l=|
%s%f=
@for /l %%i in (1,1,7)do @call:%%i
%s%u=|\/|
%s%l=|/\|
%g%
:7
%s%u=|\/
%s%l=|/\
%g%
:6
%s%f=----
%g%
:5
%s%u=|\
%s%l=| \
%g%
:4
%s%c=/__\
%g%
:3
%s%r= /\
%s%c=/  \
%g%
:2
%s%r= /
%s%c=/
:1
@for %%l in ("%r%" "%c%" "%u%" "%l%" "%f%")do @echo(%%~l

|Regras estúpidas de cotação em lote ... se você quer um |em uma variável, precisa citá-lo com três ^s, por isso é mais barato usá- @lo e substituí-lo na saída, embora, para conseguir isso, tenha que começar pela parede esquerda. A linha um tem um espaço à direita. echo(é usada porque o r, ce fvariáveis poderiam estar vazio e não queremos ECHO is off.impresso.

Editar: salvou 12 bytes usando o avanço da última parte. Economizei 3 bytes usando um forloop para imprimir cada parte, isso significa que agora uso |s em minhas variáveis, o que torna o código um pouco mais fácil de ler. 4 bytes salvos usando explícito@ caracteres vez de @echo off. Eu acho que começar com a parede esquerda ainda requer o menor número de bytes.

Neil
fonte
2
Pode não ser o mais curto, mas recebe um voto positivo de mim por realmente conseguir fazer isso no Lote +1
ElPedro 17/16
echo:é mais padrão, mas echo(parece que você está abusando de um recurso de idioma, então marque com +1.
Wizzwizz4
@ wizzwizz4 echo:falha em alguns casos extremos obscuros, mas não conheço nenhum caso de falha echo(.
Neil
@ wizzwizz4 Se você possui um arquivo foo.batno diretório atual, faz echo(\..\foo.bateco , \..\foo.batmas é echo:\..\foo.batexecutado foo.bat.
Neil
@ Neil Você sabe por que é isso? Parece que echo:.\foo.batteria esse efeito. É por causa de uma falha na pilha de diretórios, onde o "UP" do diretório raiz é o diretório atual?
Wizzwizz4
7

C, 118 bytes

main(){char *p,n;for(n='B';n++<'J';)for(p="ZFEAFDDEAGCHIAGHCIABBBBAA";*p;p++)putchar(" \n-\\_\\/|/|"[(*p<n)**p&15]);}
Martin Rosenau
fonte
Impressionante! Ótima primeira resposta e bem-vindo ao site!
DJMcMayhem
1
Para economizar 3 bytes: char*p(sem espaço) e altere 'B'e 'J'para seus códigos ASCII.
Level River St
Obrigado pela resposta. Eu não esperava que C sequer competisse. Isso é realmente impressionante e vale um +1
ElPedro 17/09/16
6

/// , 112 bytes

/!/\/\///*/----
 !@/\\\\!$/ @@!^/
*@\/@@
@\/__@@
/*@
 $
*__
$
 $
*$
 __@
$
 $^$
 $^|@
|$^|@\/
|\/@^|@\/|
|\/@|
*

Experimente online!

Erik, o Outgolfer
fonte
Eu não entendo um único byte do 112, mas eu tentei online e ele faz exatamente o que está escrito na lata, então +1
ElPedro 17/16
1
@ElPedro Tente clicar no link no cabeçalho, você pode entender o conceito, mas, se não, volte para mim. Quero que mais e mais pessoas possam entender um idioma e, se não, é um fato triste. Eu sei que não posso simplesmente fazer com que todos entendam /// (algumas pessoas só querem comida e água, /// e PPCG estão longe disso, embora não sejam impossíveis).
Erik the Outgolfer
Obrigado. Existem tantas línguas para aprender! Definitivamente vou dar uma olhada. Ainda estou jogando golfe no Python e no Lotus Formula, mas me aprofundando mais nisso. Mais idiomas é mais divertido. Obrigado novamente por sua contribuição :)
ElPedro
2

PHP, 98 95 bytes

inspirado na solução da Arnauld

for($i=8;$i--;)for($p=24;$p--;)echo"|/|/\\_\\- 
"[($c="977779061290162945539438"[$p])<$i?8:$c];

Nota: A primeira linha de código possui um espaço à direita.

Titus
fonte
Nice one @Titus. Espaços à direita são permitidos.
ElPedro 17/09/16
@ElPedro: Eu apenas conheço algumas pessoas que configuraram os editores para cortá-los automaticamente; foi por isso que mencionei.
Titus
1

PHP com GD, 348 338 bytes (não competindo)

não exatamente o que estava sendo pedido, mas ...

function f($v,$w){global$x,$y,$i;imageline($i,$x,$y,$x=$v,$y=$w,1);ob_start();imagepng($i);$s=ob_get_clean();ob_end_clean();echo'<img src="data:image/png;base64,',base64_encode($s),'" > ';}$i=imagecreate($w=9,$h=$w+$z=$w/2);imagecolorallocate($i,255,255,255);f(--$w,$y=--$h);f(0,$z);f($w,$z);f($w/2,0);f(0,$z);f(0,$h);f($w,$z);f($w,$h);

salvar em arquivo, chamar em um navegador

demolir

function f($v,$w)
{
    global$x,$y,$i;
    imageline($i,$x,$y,$x=$v,$y=$w,1);      // draw line, set end coords as new start coords
    ob_start();imagepng($i);$s=ob_get_clean();ob_end_clean();           // get image output
    echo'<img src="data:image/png;base64,',base64_encode($s),'" > ';    // print <img> tag
}
// calculate dimensions, create image, allocate background color (foreground implicitly black)
$i=imagecreate($w=9,$h=$w+$z=$w/2);imagecolorallocate($i,255,255,255);
// paint lines: implicit `$x=0`
f(--$w,$y=--$h);f(0,$z);f($w,$z);f($w/2,0);f(0,$z);f(0,$h);f($w,$z);f($w,$h);

Para desenhar uma casa maior, altere $w=9para a largura desejada.

Titus
fonte
E eu dou a este um +1 também. Mesmo que ele não aborda o desafio direto que cobre suas melhorias sugeridas e parece muito legal :)
ElPedro