ASCII Doodling: Laser in a Box
Pyth, 43 41 39 bytes
K*\#+2QKVvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K
Try it online: Pyth Compiler/Executor. Input the numbers in the following order: height first line, width second line.
Thanks to isaacg, who helped saving two bytes.
Explanation:
My solution doesn't trace the laser, it uses a simple pattern that includes the gcd. If m, n
are the dimensions of the box, let d = gcd(m, n)
. The size of the pattern is exactly 2*d x 2*d
.
E.g. the repeating pattern for 7 5
#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########
is
\/
/\
(gcd(7, 5) = 1
, size of pattern is 2 x 2
)
And the repeating pattern for 22 6
########################
#\ /\ /\ /\ /\ /\ #
# \/ \/ \/ \/ \/ \#
# /\ /\ /\ /\ /\ /#
#/ \/ \/ \/ \/ \/ #
#\ /\ /\ /\ /\ /\ #
# \/ \/ \/ \/ \/ \#
########################
is
\ /
\/
/\
/ \
(gcd(22, 6) = 2
, size of pattern is 4 x 4
)
My solution does the following thing for each of the lines: it simply generates one line of the pattern, repeats it a few times and cut's it at the end so that it fit's into the box.
K*\#+2QK implicit: Q is the second input number (=width)
K K =
*\#+2Q "#" * (2 + Q)
K print K (first line)
Vvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K implicit: vz is the first input number (=height)
VQ for N in [0, 1, ..., vz-1]:
ivzQ gcd(vz,Q)
y 2*gcd(vz,Q)
*d string with 2*gcd(vz,Q) space chars
X N\\ replace the Nth char with \
X _hN\/ replace the -(N+1)th char with /
*Q repeat Q times
< Q only use the first Q chars
p \#\# print "#" + ... + "#"
) end for
K print K
C, 256 bytes
f(w,h){int i,j,x=1,y=1,v=1,u=1;char b[h+2][w+3];for(i=0;i<w+3;i++)for(j=0;j<h+2;j++)b[j][i]=!i||!j||i>w||j>h?i>w+1?0:35:32;while((x||y)&&(x<=w||y<=h))v=x&&w+1-x?v:(x-=v,-v),u=y&&h+1-y?u:(y-=u,-u),b[y][x]=v/u<0?47:92,x+=v,y+=u;for(i=0;i<h+2;i++)puts(b[i]);}
I can probably get this under 200, and I'll add an explanation later, but I might have a paper due in a few hours I should be doing instead.
J, 85 bytes
Let g = gcd(w,h)
. The function fills the elements of a w/g by h/g
matrix with g by g
tiles, having /
's and \
's in their diagonal and anti-diagonal. The resulting 4D array is raveled into a 2D one (the inside of the box) then surrounded with #
's. (The numbers 0 1 2 3
are used instead of [space] / \ #
and the numbers are changed to characters at the end.)
A direct position based computation of inside coordinate could maybe yield a bit shorter solution.
' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.
Usage:
6 (' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.) 22
########################
#\ /\ /\ /\ /\ /\ #
# \/ \/ \/ \/ \/ \#
# /\ /\ /\ /\ /\ /#
#/ \/ \/ \/ \/ \/ #
#\ /\ /\ /\ /\ /\ #
# \/ \/ \/ \/ \/ \#
########################
Try it online here.