Дом Деда Мороза


16

Дом Деда Мороза

Примечание. Это первая задача, которую я попытался задать. Это было через Песочницу, однако, если вы обнаружите, что с ней что-то не так, пожалуйста, не просто понижайте голос, а оставляйте комментарий, чтобы я мог улучшить его.

Фон

Существует старая детская головоломка, в которой задача состоит в том, чтобы нарисовать коробку с крышей и крестиком через середину, не поднимая ручку из бумаги и не пересекая любую линию дважды.

В Германии это известно как "дас Haus Des Nikolaus" или "Дом Санта-Клауса". Я, честно говоря, не могу вспомнить, как мы это называли. Для тех, кто не знаком с загадкой, полная информация доступна здесь .

Вот ASCII художественное представление дома.

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

Вызов

Напишите программу или функцию, чтобы нарисовать дом Санта-Клауса на любом языке по вашему выбору.

Звучит слишком просто? Ну вот и подвох. Также необходимо вывести каждый этап розыгрыша и соответствовать правилам головоломки. Ваша программа не обязана принимать какие-либо данные. Готовый дом должен выглядеть точно так, как показано выше.

Согласно вышеуказанному сайту существует 44 возможных решения. Вы можете использовать любой из них. Это художественная задача ASCII, поэтому вам не нужно вычислять решение, а только рисовать его.

Выход

Пример требуемого вывода из одного из 44 решений показан ниже:

---- 

 \
  \
----

 __
 \
  \
----

  \
 __\
 \
  \
----

 /\
/__\
 \
  \
----

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

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

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

правила

  • Я добавил 1 дополнительный символ новой строки между каждым ожидаемым выводом, чтобы попытаться прояснить требования. Это необязательно. Допускается любое количество пустых строк между каждым выводом.
  • Ваш вывод должен состоять только из символов /, \, -, _ и пробела, как показано выше. Промежуточные пробелы разрешены.
  • Каждая линия на вашем чертеже должна продолжаться с конца предыдущей строки, и вы не можете повторять какую-либо линию.
  • Стандартные лазейки запрещены.
  • Вы не обязаны выводить рифму, упомянутую в приведенной выше ссылке.
  • Это код гольф, поэтому самый короткий ответ в байтах будет победителем.

Результат

Некоторые отличные ответы и спасибо и уважение всем, кто написал. Я сказал наименьшее количество байтов, но я отметил как лучший ответ не только за это, но и за отличное объяснение кода. Хороший один @ Деннис.


Это могло бы провести некоторое время в песочнице . Попробуйте добавить параметр для размера дома - или количество связанных домов (или оба). Я нахожу это слишком легким, как это. Вы также можете добавить рифму к своему примеру вывода или вообще не упоминать ее. Я нахожу этот подарок хорошим, или этот .
Тит


4
@Titus Спасибо за отзыв. Мое намерение состояло не в том, чтобы создать особенно сложную задачу, а в том, чтобы создать такую ​​задачу, которую довольно легко выполнимо, и поэтому побуждаю как можно больше людей предлагать решения. Я приму ваши предложения на борт для моей следующей попытки.
ElPedro

1
Моя вина; Я ожидал слишком сложных вещей для ascii art. :) Но я все еще люблю картинки.
Тит

GIF-файлы крутые, и мне также нравится идея включить рифму также в выборе языка :)
ElPedro

Ответы:


10

Желе , 40 39 36 байт

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

Попробуйте онлайн!

Как это устроено

“ḥ%DtƊVḍI’

является биективным основанием-буквал 250; каждый символ соответствует своей кодовой точке на кодовой странице желе . Результатом является целое число 13192938935880491074 .

          ḃ9

преобразует сгенерированное целое число в биективное основание 9, получая массив целых чисел
[9, 6, 7, 9, 6, 2, 2, 7, 1, 5, 3, 8, 1, 3, 5, 8, 4, 4, 4, 4] . Целые числа соответствуют порядку штриха, за исключением 9 , которое указывает пробел.

            W

заключает сгенерированный массив в одноэлементный массив, который потребуется для добавления его к массиву, который мы сейчас сгенерируем.

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

работает следующим образом. ¤объединяет две ссылки слева в ниладическую цепочку. Первый, “|_/-\/\|‘дает кодовые точки указанных символов, приводя к [124, 95, 47, 45, 92, 47, 92, 124] . Затем Ėперечисляет кодовые точки, получая
[[1, 124], [2, 95], [3, 47], [4, 45], [5, 92], [6, 47], [7, 92] , [8, 124]] . Пара [n, c] означает, что n- й штрих будет символом ASCII с кодовой точкой c .

             ;

объединяет сгенерированные массивы. Результатом является массив
[[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@\

выполняет кумулятивное (т. е. показывает все промежуточные шаги) уменьшение с использованием транслитерации ( y) с замененными аргументами ( @). На первом этапе, например, мы заменяем каждую 1 в исходном массиве на 124 , что является кодовой точкой символа | ,

                             FỌ

выравнивает результат и заменяет все кодовые точки соответствующими символами ASCII. На всех этапах это создаст некоторые непечатаемые символы с кодовыми точками от 1 до 9 .

                               »⁶

принимает символьный максимум с пробелом, заменяя все непечатаемые символы пробелами.

                                 s4Y

разбивает сгенерированную строку на куски длиной четыре и объединяет их с переводом строки в качестве разделителя.


2
Вау. Просто вау. +1
ElPedro

Но подождите, это байты?
Лейф Виллертс

1
@LeifWillerts Да. Чтобы избежать непечатных символов, Jelly использует пользовательскую кодовую страницу, которая кодирует 256 символов, которые она понимает как один байт каждый. В байтах ссылаются в точках заголовка к нему.
Деннис

Извините за то, что не решил нажать на эту ссылку: D
Лейф Виллертс

Он выигрывает столько же для объяснения, как и все остальное. Респект.
ElPedro

13

Javascript (ES6), 119 116 96 92 91 байт

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


Хороший ответ. У меня было ощущение, что Javascript будет там или около того :-)
ElPedro

Извините за множественные правки. Я не должен отправлять до 2-го кофе.
Арно

Многократные правки хороши. Приятно видеть, как уменьшается количество байтов.
ElPedro

Есть ли смысл иметь две одинаковые копии кода в вашем ответе?
Нил

@Neil - я оставлю только один, пока не найду вескую причину иметь два из них. ^^
Арно

9

Пакет, 356 344 341 337 байт

@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

Глупые |правила пакетного цитирования ... если вы хотите использовать a |в переменной, вам нужно заключить его в кавычки с тремя ^s, поэтому @вместо него дешевле использовать его и заменять при выводе, хотя для достижения этого я должен начать с левой стены. Первая строка имеет завершающий пробел. echo(используется потому r, что переменные c, и, fмогут быть пустыми, и мы не хотим ECHO is off.печатать.

Редактировать: Сохранено 12 байтов с использованием сквозного для последней части. Сохраняя 3 байта, используя forцикл для печати каждой части, это означает, что я теперь использую |s в своих переменных, что делает код немного легче для чтения. Сохранено 4 байта с использованием явных @символов вместо @echo off. Я думаю, что начиная с левой стены все еще требуется меньше байтов.


2
Может быть, не самое короткое, но получает от меня отклик за то, что мне действительно удалось сделать это в партии +1
ElPedro

echo:является более стандартным, но echo(похоже, что вы злоупотребляете языковой функцией, так что +1.
wizzwizz4

@ wizzwizz4 echo:терпит неудачу в некоторых неясных крайних случаях, но я не знаю ни одного случая отказа для echo(.
Нил

@ wizzwizz4 Если у вас есть файл foo.batв текущем каталоге, echo(\..\foo.batechos, \..\foo.batно echo:\..\foo.batвыполняется foo.bat.
Нил

@Neil Ты знаешь, почему это так? Кажется, что echo:.\foo.batбудет иметь такой эффект вместо этого. Это из-за сбоя в стеке каталогов, где «UP» из корневого каталога является текущим каталогом?
wizzwizz4

7

C 118 байт

main(){char *p,n;for(n='B';n++<'J';)for(p="ZFEAFDDEAGCHIAGHCIABBBBAA";*p;p++)putchar(" \n-\\_\\/|/|"[(*p<n)**p&15]);}

Впечатляет! Хороший первый ответ и добро пожаловать на сайт!
DJMcMayhem

1
Чтобы сохранить 3 байта: char*p(без пробела) и изменить 'B'и 'J'на их коды ASCII.
Уровень Река

Спасибо за ответ. Я не ожидал, что С даже будет конкурировать. Это действительно впечатляет и стоит +1
ElPedro

6

/// , 112 байт

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

Попробуйте онлайн!


Я не понимаю ни одного байта из 112, но я попробовал его онлайн, и он делает именно то, что говорит на жестяной банке, так что +1
ElPedro

1
@ElPedro Попробуйте нажать на ссылку в шапке, вы можете понять концепцию, но если нет, то просто вернитесь ко мне. Я хочу, чтобы все больше и больше людей понимали язык, а если нет, это печальный факт. Я знаю, что не могу просто заставить всех понять /// (некоторые люди просто хотят еды и воды, /// и PPCG очень далеки от этого, хотя и не невозможны).
Эрик Outgolfer

Благодарю. Есть так много языков для изучения! Я обязательно посмотрю. Я все еще играю в гольф на Python и Lotus Formula, но больше увлекаюсь этим. Больше языков веселее.
Еще

2

PHP, 98 95 байт

вдохновленный решением Арно

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

Примечание: первая строка кода имеет завершающий пробел.


Хороший один @Titus. Промежуточные пробелы разрешены.
ElPedro

@ElPedro: я просто знаю некоторых людей, которые настроили там редакторов, чтобы автоматически обрезать их; Вот почему я упомянул это.
Тит

1

PHP с GD, 348 338 байт (не конкурирует)

не совсем то, что просили, но ...

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

сохранить в файл, позвонить в браузер

сломать

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

Чтобы нарисовать больший дом, измените $w=9желаемую ширину.


И я даю этому +1 тоже. Несмотря на то, что он не решает прямую проблему, он охватывает ваши предложенные улучшения и выглядит очень круто :)
ElPedro
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.