16
\$\begingroup\$

The House of Santa Claus

Note: This is the first challenge that I have attempted to set. It has been through the Sandbox however if you find something wrong with it please do not just downvote but leave a comment so that I can improve it.

Background

There is a old childrens puzzle where the challenge is to draw a box with a roof and a cross through the middle without lifting your pen from the paper or going over any line twice.

In Germany it is known as "das Haus des Nikolaus" or "The House of Santa Claus". I honestly can't remember what we used to call it. For anyone who is not familiar with the puzzle, full details are available here.

Here is an ASCII art representation of the house.

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

Challenge

Write a program or function to draw the House of Santa Claus in any language of your choice.

Sounds too easy? Well here's the catch. It must also output each stage of the drawing and comply with the rules of the puzzle. Your program is not required to take any input. The finished house must look exactly as shown above.

According to the site above there are 44 possible solutions. You may use any one of them. This is an ASCII art challenge so you are not required to calculate the solution but only to draw it.

Output

An example of the required output from one of the 44 solutions is shown below:

---- 

 \
  \
----

 __
 \
  \
----

  \
 __\
 \
  \
----

 /\
/__\
 \
  \
----

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

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

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

Rules

  • I have added 1 extra newline between each expected output to try to make the requirements clearer. This is optional. Any number of blank lines between each output is allowed.
  • Your output must consist only of the characters /,\,-,_, and space as shown above. Trailing spaces are allowed.
  • Each line in your drawing must continue from the end of the previous line and you may not repeat any line.
  • Standard loopholes prohibited.
  • You are not required to output the rhyme mentioned in the above link.
  • This is code golf so the shortest answer in bytes will be the winner.

Result

Some great answers and thanks and respect to all who posted. I did say lowest byte count but I have marked as top answer not just for that but also for the great explanation of the code. Nice one @Dennis.

\$\endgroup\$
  • \$\begingroup\$ This could have spent some time in the sandbox. Try adding a parameter for the size of the house - or number of concatenated houses (or both). I find it too easy as it is. You may also want to add the rhyme to your example output - or not mention it at all. I find this gif nice, or this one. \$\endgroup\$ – Titus Sep 17 '16 at 10:21
  • 5
    \$\begingroup\$ @Titus This has been in the sandbox? \$\endgroup\$ – Adnan Sep 17 '16 at 10:37
  • 4
    \$\begingroup\$ @Titus Thanks for the feedback. My intention was not to create a particularly difficult challenge but to create one which is fairly easily doable and so encourage as many people as possible to propose solutions. I'll take your suggestions on board for my next attempt. \$\endgroup\$ – ElPedro Sep 17 '16 at 10:47
  • 1
    \$\begingroup\$ My fault; I was expecting too complex things for ascii art. :) But I still like the gifs. \$\endgroup\$ – Titus Sep 17 '16 at 12:09
  • \$\begingroup\$ The gifs are cool and I also like the idea of including the rhyme also in a choice of language :) \$\endgroup\$ – ElPedro Sep 17 '16 at 12:46
10
\$\begingroup\$

Jelly, 40 39 36 bytes

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

Try it online!

How it works

“ḥ%DtƊVḍI’

is a bijective base-250 literal; each character corresponds to its code point in Jelly's code page. The result is the integer 13192938935880491074.

          ḃ9

converts the generated integer to bijective base 9, yielding the integer array
[9, 6, 7, 9, 6, 2, 2, 7, 1, 5, 3, 8, 1, 3, 5, 8, 4, 4, 4, 4]. The integers correspond to the order of the stroke, with the exception of 9, which indicates a space.

            W

wraps the generated array into a singleton array, which will be required to prepend it to the array we'll generate now.

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

works as follows. ¤ combines the two links to the left into a niladic chain. The first one, “|_/-\/\|‘ yields the code points of the specified characters, yielding [124, 95, 47, 45, 92, 47, 92, 124]. Then, Ė enumerates the code points, yielding
[[1, 124], [2, 95], [3, 47], [4, 45], [5, 92], [6, 47], [7, 92], [8, 124]]. The pair [n, c] means that the nth stroke will be the ASCII character with code point c.

             ;

concatenates the generated arrays. The result is the array
[[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@\

performs a cumulative (i. e., showing all intermediate steps) reduce, using transliteration (y) with swapped arguments (@). In the first step, e.g., we replace each 1 in the original array with 124, which is the code point of the character |.

                             FỌ

flattens the result and replaces all code points with the corresponding ASCII characters. In all steps, this will generate some unprintable characters with code points 1 to 9.

                               »⁶

takes the character-wise maximum with the space character, replacing all unprintable characters with spaces.

                                 s4Y

splits the generated string into chunks of length four and joins them with a linefeed as separator.

\$\endgroup\$
  • 2
    \$\begingroup\$ Wow. Simply just wow. +1 \$\endgroup\$ – ElPedro Sep 17 '16 at 20:53
  • \$\begingroup\$ But wait, those are bytes? \$\endgroup\$ – Leif Willerts Sep 17 '16 at 20:57
  • 1
    \$\begingroup\$ @LeifWillerts Yes. To avoid unprintable characters, Jelly uses a custom code page that encodes the 256 characters it understands as a single byte each. The bytes link in the header points to it. \$\endgroup\$ – Dennis Sep 17 '16 at 20:58
  • \$\begingroup\$ Sorry then for not figuring out to click that link :D \$\endgroup\$ – Leif Willerts Sep 17 '16 at 21:12
  • \$\begingroup\$ It wins as much for the explanation as anything. Respect. \$\endgroup\$ – ElPedro Sep 21 '16 at 18:45
13
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Nice answer. I had a feeling that Javascript would be there or thereabouts :-) \$\endgroup\$ – ElPedro Sep 17 '16 at 10:51
  • \$\begingroup\$ Sorry for the multiple edits. I should not post before the 2nd coffee. \$\endgroup\$ – Arnauld Sep 17 '16 at 11:03
  • \$\begingroup\$ Multiple edits are good. Nice to see the byte count going down. \$\endgroup\$ – ElPedro Sep 17 '16 at 11:07
  • \$\begingroup\$ Is there any point in having two identical copies of the code in your answer? \$\endgroup\$ – Neil Sep 17 '16 at 11:56
  • \$\begingroup\$ @Neil - I'll keep only one till I find a good reason to have two of them. ^^ \$\endgroup\$ – Arnauld Sep 17 '16 at 12:09
9
\$\begingroup\$

Batch, 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

Stupid Batch | quoting rules... if you want a | in a variable, you need to quote it with three ^s, so it's cheaper to use @ instead and substitute it on output, although to achieve this I have to start with the left wall. Line one has a trailing space. echo( is used because the r, c, and f variables could be empty and we don't want ECHO is off. printed.

Edit: Saved 12 bytes by using fallthrough for the last part. Saved 3 bytes by using a for loop to print each part, this means that I now use |s in my variables which makes the code slightly easier to read. Saved 4 bytes by using explicit @ characters instead of @echo off. I think starting with the left wall still requires the fewest bytes.

\$\endgroup\$
  • 2
    \$\begingroup\$ May not be the shortest but gets an upvote from me for actually managing to do it in Batch +1 \$\endgroup\$ – ElPedro Sep 17 '16 at 12:50
  • \$\begingroup\$ echo: is more standard but echo( looks like you're abusing a language feature, so +1. \$\endgroup\$ – wizzwizz4 Sep 18 '16 at 7:36
  • \$\begingroup\$ @wizzwizz4 echo: fails in some obscure edge cases, but I don't know of any failure cases for echo(. \$\endgroup\$ – Neil Sep 18 '16 at 8:51
  • \$\begingroup\$ @wizzwizz4 If you have a file foo.bat in the current directory, echo(\..\foo.bat echos \..\foo.bat but echo:\..\foo.bat executes foo.bat. \$\endgroup\$ – Neil Sep 18 '16 at 8:54
  • \$\begingroup\$ @Neil Do you know why that is? It seems like echo:.\foo.bat would have that effect instead. Is it because of a directory stack glitch, where the "UP" from the root directory is the current directory? \$\endgroup\$ – wizzwizz4 Sep 18 '16 at 9:50
7
\$\begingroup\$

C, 118 bytes

main(){char *p,n;for(n='B';n++<'J';)for(p="ZFEAFDDEAGCHIAGHCIABBBBAA";*p;p++)putchar(" \n-\\_\\/|/|"[(*p<n)**p&15]);}
\$\endgroup\$
  • \$\begingroup\$ Impressive! Nice first answer, and welcome to the site! \$\endgroup\$ – DJMcMayhem Sep 17 '16 at 16:52
  • 1
    \$\begingroup\$ To save 3 bytes: char*p (no space) and change 'B' and 'J' to their ASCII codes. \$\endgroup\$ – Level River St Sep 17 '16 at 19:21
  • \$\begingroup\$ Thanks for the answer. I didn't expect C to even compete. This is really impressive and well worth a +1 \$\endgroup\$ – ElPedro Sep 17 '16 at 22:39
6
\$\begingroup\$

///, 112 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I don't understand a single byte of the 112 but I tried it online and it does exactly what it says on the tin so +1 \$\endgroup\$ – ElPedro Sep 17 '16 at 14:40
  • 1
    \$\begingroup\$ @ElPedro Try clicking the link on the header, you might understand the concept, but, if not, then just get back to me. I want more and more people to be able to understand a language, and, if you don't, it's a sad fact. I know I can't just make everyone understand /// (some people just want food and water, /// and PPCG are far away from that, although not impossible). \$\endgroup\$ – Erik the Outgolfer Sep 17 '16 at 14:46
  • \$\begingroup\$ Thanks. There are so many languages to learn! I'll definitely take a look. I'm still golfing in Python and Lotus Formula but getting into it more. More languages is more fun. Thanks again for your contribution :) \$\endgroup\$ – ElPedro Sep 17 '16 at 14:48
2
\$\begingroup\$

PHP, 98 95 bytes

inspired by Arnauld´s solution

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

Note: The first code line has a trailing space.

\$\endgroup\$
  • \$\begingroup\$ Nice one @Titus. Trailing spaces are allowed. \$\endgroup\$ – ElPedro Sep 17 '16 at 22:28
  • \$\begingroup\$ @ElPedro: I just know some people who have configured there editors to automatically trim them; that´s why I mentioned it. \$\endgroup\$ – Titus Sep 17 '16 at 23:13
1
\$\begingroup\$

PHP with GD, 348 338 bytes (not competing)

not exactly what was being asked for, but ...

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

save to file, call in a browser

breakdown

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

To draw a larger house, change $w=9 to your desired width.

\$\endgroup\$
  • \$\begingroup\$ And I give this one a +1 as well. Even though it does not address the direct challenge it covers your suggested improvements and looks very cool :) \$\endgroup\$ – ElPedro Sep 17 '16 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.