| Bytes | Lang | Time | Link |
|---|---|---|---|
| 578 | Elisp | 240716T135823Z | Samuel J |
| 325 | JavaScript Node.js | 240715T014809Z | Andrew B |
| 176 | JavaScript ES6 | 240710T124848Z | Arnauld |
| 183 | Python 3.8 prerelease | 240710T191252Z | squarero |
| 150 | Ruby | 240710T194631Z | Level Ri |
| 079 | K ngn/k | 240710T125605Z | ovs |
| 318 | Regenerate | 240711T000011Z | DLosc |
| 572 | sed 4.2.2 | 240710T061928Z | guest430 |
| 041 | Charcoal | 240710T073253Z | Neil |
Elisp, 578 bytes
(setq s (+(*(- n 1)2)1))(defun o (s)(save-excursion(cl-loop for x below 5 do(if (not (= (or (char-after) ?\C-j) ?\C-j))(delete-char 1)))(insert s))(next-line))(defun d (x y)(goto-char (+ (* y (+ (* s 6)1)) x))(o " / \\ ")(o "|\\ /|")(o "| | |")(o " \\|/ "))(with-temp-buffer(newline (* s 3))(string-insert-rectangle 0 (point-max) (make-string (* s 6) ? ))(cl-loop for c to (1- s) do(let ((x (1+ (*(abs(-(/ s 2)c))2)))(y (* c 3)))(d x y)(d (+(1- (-(* s 3)x)) (1- s)) y)))(cl-loop for c to (- n 3) do(let ((x (+ s (* (1+ c) 4))))(d x 0)(d x (* (1- s) 3))))(princ (buffer-string)))
Had some fun drawing each cube one at a time instead of a "top down" approach. Huge respect to those that where able to do it that way
#!/usr/bin/emacs --script
(require 'cl-lib)
(setq next-line-add-newlines t)
(setq n (string-to-number (pop argv)))
(setq square-count (+(*(- n 1)2)1))
(defun overwrite (s)
(save-excursion
(cl-loop for x below 5 do
(if (not (= (or (char-after) ?\C-j) ?\C-j))
(delete-char 1)
)
)
(insert s)
)
(next-line)
)
(defun cube (x y)
(message "drawing cube at %s %s" x y)
(goto-char (+ (* y (+ (* square-count 6)1)) x))
(overwrite " / \\ ")
(overwrite "|\\ /|")
(overwrite "| | |")
(overwrite " \\|/ ")
)
(with-temp-buffer
(newline (* square-count 3))
(string-insert-rectangle 0 (point-max) (make-string (* square-count 6) ? ))
(cl-loop for c to (1- square-count) do
(let ((x (1+ (*(abs(-(/ square-count 2)c))2)))
(y (* c 3)))
(cube x y)
(cube (+(1- (-(* square-count 3)x)) (1- square-count)) y)
))
;; top and bot row
(cl-loop for c to (- n 3) do
(let ((x (+ square-count (* (1+ c) 4))))
(cube x 0)
(cube x (* (1- square-count) 3))
)
)
(princ (buffer-string))
)
JavaScript (Node.js), 325 bytes
n=>{w=8*n-3
h=n*6-2
o=Array(h).fill(0).map(x=>Array(w).fill(' '))
q=(x,y)=>' / \\-|\\ /|-| | |- \\|/'.split`-`.map(j=>j.split``).map((f,g)=>f.map((l,m)=>o[y+g][x+m]=l))
for(e=0;e<n;e++){r=n*2-2+e*4
t=(n-e)*3
u=w-5-2*e
q(r,0)
q(r,6*n-6)
q(2*e,t-3)
q(2*(n-e)-2,h-3*e-4)
q(u,t-3)
q(u,h-t-1)}return o.map(z=>z.join``).join`\n`}
JavaScript (ES6), 176 bytes
Builds the output character by character.
n=>(y=h=n*6-2,n+=n-1,g=x=>y?`| /\\
`[X=w-x-n,s=y>h/2,c=x-n>4&X>4,~x?x--<n|X<0|y>4&y<h-3&c||`03123${y/h|y==4*c}210101`[y%3*4|X-y%3*s*2&3]:(n+=y--%3&&-s|1,x=w,4)]+g(x):"")(w=n*4)
Variables
Below are the most important variables used in the code:
- \$x\$ : current column, initialized to the width \$w=8n-4\$
- \$y\$ : current row, initialized to the height \$h=6n-2\$
- \$y \bmod 3\$ : cube row (1 = top, 0 = middle, 2 = bottom)
- \$s\$ : side (1 = top half / 0 = bottom half)
- \$p\$ : left/right padding, initialized to \$2n-1\$ (the name \$p\$ is used here for clarity; in the code, we actually re-use the input variable \$n\$)
- \$c\$ : a flag set when we are located in the center part
For \$n=3\$, this leads to the following diagram:
x=20 x=-1
| | | y | y%3 | s | p
-v--------------------v--+----+-----+---+---
...../.\./.\./.\.....\n | 16 | 1 | 1 | 5
....|\./|\./|\./|....\n | 15 | 0 | 1 | 4
....|.|.|.|.|.|.|....\n | 14 | 2 | 1 | 4
.../.\|/.\|/.\|/.\...\n | 13 | 1 | 1 | 3
..|\./|ccccccc|\./|..\n | 12 | 0 | 1 | 2
..|.|.|ccccccc|.|.|..\n | 11 | 2 | 1 | 2
./.\|/ccccccccc\|/.\.\n | 10 | 1 | 1 | 1
|\./|ccccccccccc|\./|\n | 9 | 0 | 1 | 0
|.|.|ccccccccccc|.|.|\n | 8 | 2 | 0 | 0
.\|/.\ccccccccc/.\|/.\n | 7 | 1 | 0 | 1
..|\./|ccccccc|\./|..\n | 6 | 0 | 0 | 2
..|.|.|ccccccc|.|.|..\n | 5 | 2 | 0 | 2
...\|/.\./.\./.\|/...\n | 4 | 1 | 0 | 3
....|\./|\./|\./|....\n | 3 | 0 | 0 | 4
....|.|.|.|.|.|.|....\n | 2 | 2 | 0 | 4
.....\|/.\|/.\|/.....\n | 1 | 1 | 0 | 5
Commented
n => ( // n = input
y = h = n * 6 - 2, // initialize y and h to 6n - 2
n += n - 1, // turn n into the padding, initialized to 2n - 1
g = x => // g = recursive function taking x
y ? // if y is not 0:
`| /\\\n`[ // lookup string of possible characters
X = w - x - n, // set X = w - x - n
s = y > h / 2, // set s = 1 for top half / 0 for bottom half
c = x - n > 4 & // set c if we're in the center of the row,
X > 4, // i.e. x - n > 4 and X > 4
~x ? // if x is not equal to -1:
x-- < n | X < 0 | // append a space if we're too far to the left,
y > 4 & // too far to the right, or in the center of
y < h - 3 & c // the pattern
|| ( // otherwise, use a cube pattern:
`0312` + // "|\ /" for the middle row
`3${y / h | // either "\|/ " or "\ / " for the top row
y == 4 * c // (depending on y and c)
}21` + //
`0101` // or "| | " for the bottom row
)[ y % 3 * 4 | // get the position of the pattern
X - // get the position of the character in the
y % 3 * s * 2 // pattern
& 3 ] //
: // else (end of row):
( n += y-- % 3 // add -1, 0 or 1 to the padding
&& -s | 1, //
x = w, // reset x to w
4 ) // append a line-feed
] + g(x) // append the result of a recursive call
: // else (end of recursion):
"" // stop
)(w = n * 4) // initial call to g with x = w = 4n
Python 3.8 (pre-release), 314 259 239 233 229 197 189 183 bytes
-55 bytes by encoding the character positions as a list.
-20 bytes by cheating returning a 2D list, thanks to noodle person.
-6 bytes by using unprintables.
-4 bytes by using [0]*n instead of range(n).
-40 bytes by Jonathan Allan.
-6 bytes by xnor.
No, I don't know how it works either.
def f(n):
x=2*n;l=[7*x*[s]for s in' '*5*x];y=N=0
for v in b'cV6#0P':
for _ in[0]*n:
for t in b'\12 ':l[y+t//5][x+t%5]='\/||'[N%4];N+=1
x+=v//8-8;y+=v%8-3
return l
First example is inputted as 1.
The \12 in the unprintable string is literal.
Ruby, 166 150 bytes
->n{w=6*v=n*4
s=(?.*w+$/)*w
w.times{|i|j=i%4
j<1&&v+=[4,w*3+5,w*3+1][i/4/n%3]*(1-i/n/12*2)
s[v-j*~w-~k=j%-3/2,l=3-k*2]='/ \ |\ /|| | |\|/'[j*5,l]}
s}
Function that returns a newline separated string.
Starts with a blank newline separated string, then adds one cube at a time, each cube built from 4 lines.
K (ngn/k), 79 bytes
{`0:"\\/|"(3|=8*x).[;;&;+5 4#4\3947690525]/(x+x+!'4 5)+\+-4+9\,/1_'x#'",EA$"}
Inserts one cube at a time in clockwise order: "animation"
Regenerate, 318 bytes
( {2*$~1-2}) ( / \\){$~1}
($1 (\|\\ /){$~1}\|
)($1( \|){#1+3}
)$1/( \\\|/){$~1} \\(
( {#9-2}! {#1-2})( $4\|)( {8*$~1-14-2*#9})$10
$9($6{3})$11$12
$9/$7 $11 $7 \\){$~1-2}
$4\|( {8*$~1-14}) $4\|
$6{3}$13$6{3}(
($15 ! )$7 \\ ( {#16-4}!$11) /$7
$15 $10$16$10
$15 $12$16$12){$~1-2}
$1\\\|/( \\ /){$~1-1}$7
$3$5 $1$7{$~1}
Generates the figure line by line. With reference to the N = 3 diagram, the output always contains one copy of the first four lines, then N-2 copies of the next three, then one copy of the next two, then N-2 copies of the next three, and finally one copy of the last four. These roughly correspond to the lines of the program, except that the last line of the program generates the last three lines of the output.
This could probably be a bit shorter, but right now I'm tired of counting backreferences. :P
sed 4.2.2, 573 572 bytes
h;s!.! / \\!g;x;s/.//;s/./ /g;G;s/\n//p
s! /!|/!g;y|\\/|/\\|;s/$/|/p;h
s!\\ /! | !gp
x;s! /|!|/ !g;:a;s!$!\\!;s! |!/ !p
s/ \\/ /;s!/ ! !;y!/\\!\\/!;:e
s!|\\ /|!| |!;s/ | / /;te;s! \\!|\\!;s/$/|/p
s!\\ /! | !gp
s!| | |!|\\|/ !;s!! \\|/ !
/^ * |/ta;:b;s/\n.*//
s!/ !/ \\!
s/^|/ /;s! \? \\|!/ \\|!2p
y|\\/|/\\|;s!/! !;s!\\ $!!;s!/ !/|!;s! \\!|\\!;p
s!\\ /! | !gp
s!| | |! \\|/ !g;T;s! | |!\\|/!;t
G;s/ *| | / /g;s/ |/\\/
T;s/^\( *\\\).*\n\1/&/;Tb
s/\n.*//;:z;s!/ !/ \\ /!;tz;p
y!/\\!\\/!;s!/! !;s!\\ $!!;s!/ \\!/|\\!gp
s!\\ /! | !gp
s!| | ! \\|/!g;s/|$//;:
takes input as any unary character. works for inputs of 2 or more. basically it just outputs each line after it makes it. the little 'humps' between outputs in the test cases is the output for an input of 0; you can remove the extra newlines in the input if you want to see the output without them.
here's with trying to output three lines at a time:
sed 4.2.2, 566 bytes
h;s!.! / \\!g;x;s/.//;s/./ /g;G;s/\n//p
s! /!|/!g;y|\\/|/\\|;s/$/|/p;h
s!\\ /! | !gp
x;s! /|!|/ !g;:a;s!$!\\!;s! |!/ !p
s!/ \\|! !g;x;s/|.*//;G;s!..\(.*\)\n\1!\1|\\ /|!
s! / \\!|\\ /|!
s/.*/&\n&\n&/
s!|\\ /|!| | |!3g
T;s! | | |!/ \\|/ !3;Tr
s!| | |! \\|/ \\!3;bh
:a;p;s/^ //mg;s!/ \|| !& !mg;:h;/^ /ta
:r;s/ |\n.*/ |/
s!| | | \( *\) | | |!&\n \\|/ \\\1/ \\|/!;be
:k;s/^/ /gm;s!\\ !\\!;s!| !|!g
:e;s!\n[^\n]*$!&&!;G;s![^ \n]! !23g
T;s!\n\( *\)\n\1!!;t;s/\n *\n *//p;tk
:;s!\\ !\\ / \\!;t;p;s/^/ /gm;s/| .*//gm;s!/ \\.*$!/!
:q;s/....$/&&/mg
this one doesn't work yet (the last line of cubes is proving particularly hard to measure) but doing it this way might make it easier to golf.
Charcoal, 41 bytes
NθF²F³Fθ«F³M∨μ¹✳⁺×⁴ι×μ⁻¹κP↑”{⊟∨÷IDR▶#⟲⁹⁰e
Try it online! Link is to verbose version of code. Uses the alternative input scheme where the input is a sixth of the number of cubes. Explanation:
Nθ
Input the integer.
F²F³
Repeat for each of six directions, represented as two major directions (right and left) and three minor directions (-60, 0 and +60 degrees).
Fθ«
Repeat the given integer times.
F³M∨μ¹✳⁺×⁴ι×μ⁻¹κ
Move to the next cube.
P↑”{⊟∨÷IDR▶#⟲⁹⁰e
Output the cube. The cube is output in an upwards direction to avoid accidentally overwriting a cube above. Given that there are 12 characters to output, a 14-byte compressed string seems as if it will be more efficient than trying to use drawing commands.
The directions moved in each inner loop are respectively:
- N, N, NE, E (in reverse order)
- E, E, E, E
- E, SE, S, S
- S, S, SW, W (in reverse order)
- W, W, W, W
- W, NW, N, N