The House of Santa Claus

16

1

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.

ElPedro

Posted 2016-09-17T09:07:16.667

Reputation: 5 301

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.

– Titus – 2016-09-17T10:21:35.263

5

@Titus This has been in the sandbox?

– Adnan – 2016-09-17T10:37:52.740

4@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. – ElPedro – 2016-09-17T10:47:58.333

1My fault; I was expecting too complex things for ascii art. :) But I still like the gifs. – Titus – 2016-09-17T12:09:02.173

The gifs are cool and I also like the idea of including the rhyme also in a choice of language :) – ElPedro – 2016-09-17T12:46:09.577

Answers

10

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.

Dennis

Posted 2016-09-17T09:07:16.667

Reputation: 196 637

2Wow. Simply just wow. +1 – ElPedro – 2016-09-17T20:53:07.973

But wait, those are bytes? – Leif Willerts – 2016-09-17T20:57:14.347

1@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. – Dennis – 2016-09-17T20:58:38.970

Sorry then for not figuring out to click that link :D – Leif Willerts – 2016-09-17T21:12:26.660

It wins as much for the explanation as anything. Respect. – ElPedro – 2016-09-21T18:45:56.667

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

Posted 2016-09-17T09:07:16.667

Reputation: 111 334

Nice answer. I had a feeling that Javascript would be there or thereabouts :-) – ElPedro – 2016-09-17T10:51:40.643

Sorry for the multiple edits. I should not post before the 2nd coffee. – Arnauld – 2016-09-17T11:03:51.210

Multiple edits are good. Nice to see the byte count going down. – ElPedro – 2016-09-17T11:07:15.697

Is there any point in having two identical copies of the code in your answer? – Neil – 2016-09-17T11:56:10.917

@Neil - I'll keep only one till I find a good reason to have two of them. ^^ – Arnauld – 2016-09-17T12:09:54.887

9

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.

Neil

Posted 2016-09-17T09:07:16.667

Reputation: 95 035

2May not be the shortest but gets an upvote from me for actually managing to do it in Batch +1 – ElPedro – 2016-09-17T12:50:31.577

echo: is more standard but echo( looks like you're abusing a language feature, so +1. – wizzwizz4 – 2016-09-18T07:36:53.317

@wizzwizz4 echo: fails in some obscure edge cases, but I don't know of any failure cases for echo(. – Neil – 2016-09-18T08:51:59.937

@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. – Neil – 2016-09-18T08:54:47.480

@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? – wizzwizz4 – 2016-09-18T09:50:37.187

@wizzwizz4 It occurs to me that cmd takes : as a legal file name character, and therefore decides that echo:\..\foo.bat is a path, but then removes the "redundant" echo:\..\ and executes foo.bat. – Neil – 2016-09-18T09:59:00.443

@wizzwizz4 You can add any legal file name characters after the : and you can of course have further path components, so echo:foo\.\..\bar.bat still executes bar.bat. – Neil – 2016-09-18T10:47:00.890

@Neil Ah. I understand now. It thinks that echo:foo is a folder name, but doesn't check because it's navigating UP immediately. I'll update the Batch documentation. – wizzwizz4 – 2016-09-18T10:51:03.937

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

Posted 2016-09-17T09:07:16.667

Reputation: 1 921

Impressive! Nice first answer, and welcome to the site! – James – 2016-09-17T16:52:49.773

1To save 3 bytes: char*p (no space) and change 'B' and 'J' to their ASCII codes. – Level River St – 2016-09-17T19:21:20.367

Thanks for the answer. I didn't expect C to even compete. This is really impressive and well worth a +1 – ElPedro – 2016-09-17T22:39:32.780

6

///, 112 bytes

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

Try it online!

Erik the Outgolfer

Posted 2016-09-17T09:07:16.667

Reputation: 38 134

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 – ElPedro – 2016-09-17T14:40:17.873

1@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). – Erik the Outgolfer – 2016-09-17T14:46:27.310

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 :) – ElPedro – 2016-09-17T14:48:50.690

2

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.

Titus

Posted 2016-09-17T09:07:16.667

Reputation: 13 814

Nice one @Titus. Trailing spaces are allowed. – ElPedro – 2016-09-17T22:28:00.230

@ElPedro: I just know some people who have configured there editors to automatically trim them; that´s why I mentioned it. – Titus – 2016-09-17T23:13:10.890

1

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.

Titus

Posted 2016-09-17T09:07:16.667

Reputation: 13 814

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 :) – ElPedro – 2016-09-17T22:30:09.090