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\$
5
  • \$\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, 2016 at 10:21
  • 5
    \$\begingroup\$ @Titus This has been in the sandbox? \$\endgroup\$
    – Adnan
    Sep 17, 2016 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, 2016 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, 2016 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, 2016 at 12:46

7 Answers 7

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\$
5
  • \$\begingroup\$ Nice answer. I had a feeling that Javascript would be there or thereabouts :-) \$\endgroup\$
    – ElPedro
    Sep 17, 2016 at 10:51
  • \$\begingroup\$ Sorry for the multiple edits. I should not post before the 2nd coffee. \$\endgroup\$
    – Arnauld
    Sep 17, 2016 at 11:03
  • \$\begingroup\$ Multiple edits are good. Nice to see the byte count going down. \$\endgroup\$
    – ElPedro
    Sep 17, 2016 at 11:07
  • \$\begingroup\$ Is there any point in having two identical copies of the code in your answer? \$\endgroup\$
    – Neil
    Sep 17, 2016 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, 2016 at 12:09
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\$
5
  • 2
    \$\begingroup\$ Wow. Simply just wow. +1 \$\endgroup\$
    – ElPedro
    Sep 17, 2016 at 20:53
  • \$\begingroup\$ But wait, those are bytes? \$\endgroup\$ Sep 17, 2016 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, 2016 at 20:58
  • \$\begingroup\$ Sorry then for not figuring out to click that link :D \$\endgroup\$ Sep 17, 2016 at 21:12
  • \$\begingroup\$ It wins as much for the explanation as anything. Respect. \$\endgroup\$
    – ElPedro
    Sep 21, 2016 at 18:45
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\$
8
  • 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, 2016 at 12:50
  • \$\begingroup\$ echo: is more standard but echo( looks like you're abusing a language feature, so +1. \$\endgroup\$
    – wizzwizz4
    Sep 18, 2016 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, 2016 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, 2016 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, 2016 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\$
3
  • \$\begingroup\$ Impressive! Nice first answer, and welcome to the site! \$\endgroup\$
    – DJMcMayhem
    Sep 17, 2016 at 16:52
  • 1
    \$\begingroup\$ To save 3 bytes: char*p (no space) and change 'B' and 'J' to their ASCII codes. \$\endgroup\$ Sep 17, 2016 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, 2016 at 22:39
6
\$\begingroup\$

///, 112 bytes

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

Try it online!

\$\endgroup\$
3
  • \$\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, 2016 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\$ Sep 17, 2016 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, 2016 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\$
2
  • \$\begingroup\$ Nice one @Titus. Trailing spaces are allowed. \$\endgroup\$
    – ElPedro
    Sep 17, 2016 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, 2016 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\$
1
  • \$\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, 2016 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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