You may remember these drawings from when you were a child, but now it's time to let the computer draw them (in full ascii splendour). Have fun!
Description:
The input are multiple lines (terminated by a newline) which describe a 'field'. There are 'numbers' scattered across this field (seperated by whitespace). All lines can be considered to be the same length (you can pad spaces to the end).
- the numbers always start at 1
- they follow the ordering of the natural numbers: every 'next number' is incremented with 1
- every number is surrounded by (at least) one whitespace on its left and right
Task:
Draw lines between these numbers in their natural order
(1 -> 2 -> 3 -> ...N)
(assume N <= 99) with the following characteristics:
- replace a number with a '
+
' character - for horizontal lines: use '
-
' - for vertical lines: use '
|
' - going left and down or right and up:
/
- going left and up or right and down:
\
Important notes:
When drawing lines of type 4 and 5 you can assume (given the points to connect with coordinates x1, y1 and x2, y2) that
distance(x1,x2) == distance(y1,y2)
. Or in other words (as user jball commented): "consecutive elements that are not horizontally or vertically aligned always align to the slope of the slash or backslash".It is important to follow the order in which the dots are connected (newer lines can strike out older lines).
-- Sample input 1 --
8 7 6 10 9 5 3 4 11 12 13 1 2
-- Sample output 1 --
+ /| / +--+ +--------+ \ / \ / + / | / +--+ + | \ | +------------------------+ +--------------------------+
-- Sample input 2 --
64 63 62 61 1 65 66 57 58 2 56 59 45 67 55 46 3 44 54 60 47 53 52 49 48 4 51 50 43 5 42 41 6 23 22 25 26 40 20 21 24 34 7 13 12 33 19 27 32 14 35 8 15 16 39 17 18 28 31 36 9 38 10 11 29 30 37
-- Sample output 2 -- (unicorn reference)
+ /+ // // // /+--+ + + \ | + +-\+ + \ + \ + / + + \ +\ + \ \ | + | + + +/ | +--+ +-------+/ + +--+ + / \ + + | + + + / \ +\ +---+ + \ +--+ + \ /+ + +--+ / \ /+| / | |+ + /+ | / + || / // + + + || / // / \ + || / // / \ | || / +/ / \ +---+ + +\ + + | | | +| +--+ +---+ +
Winner:
Shortest solution (by code character count). Input can be read via standard input.
Perl, 222 char (211)
Perl,
384365276273253225222218211 chars (222 when contest ended). Newlines are for "readability" only and are not included in the character count.Last edit: no longer overwriting
$"
, and printing@S
directlyExplanation:
This task will be easier if all the lines are the same length (say, 97 characters). This statement takes each line of input, replaces the end-of-line character with 96 spaces, then pushes the first 96 characters plus a newline into the array
@S
. Note we are also setting$n=1
, as 1 is the first number we'll look for in the input. Thejoin
statement creates a single string from the array@S
. It is more convenient to use the scalar variable$_
for pattern matching, and more convenient to use the array@S
for making updates to the picture.Search for the number
$n
in the variable$_
. Evaluating regular expressions in Perl has several side-effects. One is to set the special variable$-[0]
with the position of the start of the matched pattern within the matched string. This gives us the position of the number$n
in the string$_
and also the array@S
.Of course, the loop will end when
$n
is high enough that we can't find it in the input.Let
$q
be the position of the number$n
in the string$_
and the array@S
, and assign the character '+' at that position.The first time through the loop, set
$p
to$q
. After the first time,$p
will hold the previous value of$q
(which will refer to the position in the input of the previous number). Assign$P
and$Q
such that$P
=min($p
,$q
),$Q
=max($p
,$q
)By construction, consecutive numbers are either
connected by a vertical line. Since the input is constructed to have 97 characters on each line, this case means that
$p-$q
is divisible by 97."aligned to the slope of a backslash", which would make
$p-$q
divisible by 98"aligned to the slope of a forward slash", which would make
$p-$q
divisible by 96on the same horizontal line
The elements of this list encode the possible number of positions between line segments, and the character to encode that segment.
Another trivial regex evaluation. As a side-effect, it sets the special variable
$&
(the MATCH variable) to the line segment character (\ | /
or-
) and$'
(the POSTMATCH variable) to the number (98 97 96 or 1) encoded in the list element.This statement draws the line segment between two numbers. If
$Q-$P
is divisible by$'
, then keep incrementing$P
by$'
and assigning the character$&
to$S[$P]
until$P
reaches$Q
. More concretely, for example if$Q-$P
is divisible by 97, then increment$P
by 97 and set$S[$P]='|'
. Repeat until$P>=$Q
.Prepare for the next iteration of the loop. Increment
$n
to the next number to search for in the input, and let$p
hold the position of the previous number.Output the array, converting any leftover digits (from double digit identifiers in the input where we only overwrote the first digit with a '+') to spaces as we go.