# Draw a timeline

Given an input of a list of integers representing dates, output an ASCII art timeline like the following:

<----------------------------->
A     B  C           D    E


The above timeline is the output for input [1990, 1996, 1999, 2011, 2016]. Note several things about the timeline:

• The first line of output is a less than sign (<), a number of dashes equal to dateOfLastEvent - dateOfFirstEvent + 3 (because one must be added to include the last date, and then two more for padding), and then a greater than sign (>).

• In the second line of output, each event is placed at position dateOfEvent - dateOfFirstEvent + 2 (assuming zero-indexing). Hence, the first event is placed at position 2, two characters to the right of the <, and the last event is similarly two characters to the left of the >.

• Each event is represented by a letter. Event 1 is A, event 2 is B, etc. There will never be more than 26 events. You may use lowercase letters if you would like.

• There is no trailing whitespace. The only extra whitespace allowed is a trailing newline at the end of the program.

Furthermore,

• The events are not necessarily given in order. Dates are still labelled according to their position in the array, though. For example, an input of [2, 3, 1, 5, 4] must output

<------->
CABED

• You may be given one or more events as input. For example, an input of [12345] must output

<--->
A

• You may assume that the input will never contain duplicate dates.

Input may be given as either an array/list of integers/strings or a single string separated by any non-numerical character. The allowable range of dates that will be provided as input is 1 ≤ x ≤ 32767.

Since this is , the shortest code in bytes will win.

Test cases:

32767 32715 32716 32750 32730 32729 32722 32766 32740 32762
<------------------------------------------------------->
BC     G      FE         I         D           J   HA
2015 2014
<---->
BA
1990 1996 1999 2011 2016
<----------------------------->
A     B  C           D    E
2 3 1 5 4
<------->
CABED
12345
<--->
A


## Pyth, 373635 34 bytes

:*dlp++\<*\-+3-eJSQhJ">
"mhh-dhJQG


Explanation: (for this the newline will be replaced by \n for simplicity)

:*dlp++\<*\-+3-eJSQhJ">\n"mhh-dhJQG

- autoassign Q = eval(input())
- G = "abcdefghijklmnopqrstuvwxyz"

p++\<*\-+3-eJSQhJ">\n"          -    print out the first line

+3-eJSQhJ               -        Get the number of dashes
SQ                 -            sorted(Q)
J                   -           autoassign J = ^
e                    -          ^[-1]
-                     -         ^-V
hJ               -          J[0]
+3                      -        ^+3

*\-                        -       ^*"-"
+\<                           -      "<"+^
+               ">\n"          -     ^+"-->\n"
p                               -    print(^)

*dl                                -  work out the number of spaces to print
l                                -   len(^)
*d                                 -  ^*" "
:                                 G - For i in V: ^[i] = G[i]
mhh-dhJQ  -  Work out the positions of the characters
m      Q  -  [V for d in Q]
hJ   -     J[0]
-d     -    d-^
hh       -   ^+2


Try it here!

## PowerShell, 120 108 bytes

param($a)$n,$m=($a|sort)[0,-1];"<$('-'*($b=$m-$n+3))>";$o=,' '*$b;$i=97;$a|%{$o[$_-$n+2]=[char]$i++};-join$o  Takes input $a then sets $n and $m to the minimal and maximal values, respectively. We output the timeline with the next section, by executing a code block $(...) inside the string to generate the appropriate number of - characters. We then generate an array of the same length containing only spaces, and set our output character to $i.

Then, we loop through the input $a with |%{...}. Each loop we set the appropriate $o value. Finally, we -join $o together to form a string. Since that is left on the pipeline, output is implicit. Edited to remove the .TrimEnd() command, as the last character of $o is always guaranteed to be a letter.

### Example

PS C:\Tools\Scripts\golfing> .\draw-a-timeline.ps1 2015,2014,2000
<------------------>
c             ba


# C - 294287220191184178 174 bytes

After staring out with a somewhat insane code I at least have gotten it down a bit ...

Note: First loop has the requirement that the execution of the binary gives 0 as result from atoi() on argv[0]. If not, this would result in the binary (name) being included as an event. Examples that invalidates:

$42/program 1 2 3 # 42/program gives 42 from argv[0], fail.$ 1program 3 2 9
# 1program gives 1 from argv[0], fail.

$842 3 2 9 # 842 gives 842 from argv[0], fail.  Not sure if this is a valid requirement. char y[32769];n,m;main(i,a)char**a;{for(;n=atoi(a[--i]);y[n>m?m=n:n]=64+i);for(;!y[++i];);printf("<");for(n=i;i<=m;i+=printf("-"))!y[i]?y[i]=' ':0;printf("-->\n %s\n",y+n);}  Run: ./cabed 32767 32715 32716 32750 32730 32729 32722 32766 32740 32762 <-------------------------------------------------------> BC G FE I D J HA ./cabed 2 1 3 5 4 <-------> BACED ./cabed 2016 <---> A ./cabed 130 155 133 142 139 149 148 121 124 127 136 <-------------------------------------> H I J A C K E D GF B  Ungolfed: #include <stdio.h> #include <stdlib.h> char y[32769]; /* Zero filled as it is in global scope. */ int n, m; int main(i, a) char**a; { /* Loop argv and set y[argv[i] as int] = Letter, (Event name). * Set m = Max value and thus last data element in y. */ for ( ; n = atoi(a[--i]); y[n > m ? m = n : n] = 64 + i) ; /* i = 0. Find first element in y that has a value. (Min value.) */ for (; !y[++i]; ) ; printf("<"); /* Save min value / y-index where data starts to n. * Print dashes until y-index = max * Build rest of event string by filling in spaces where no letters.*/ for (n = i; i <= m; i += printf("-")) !y[i] ? y[i] = ' ' : 0; printf("-->\n %s\n", y + n); return 0; }  # MATL, 40 41 bytes 0lY2in:)GtX<-I+(t~32w(ctn45lbX"60hP62hcw  Try it online! 0 % array initiallized to 0 lY2 % string 'ABC...Z' in:) % input array. Take as many letters as its length GtX<-I+ % push input again. Duplicate, subtract minimum and add 3 ( % assign selected letter to those positions. Rest entries are 0 t~32w( % replace 0 by 32 (space) c % convert to char tn45lbX" % duplicate, get length. Generate array of 45 ('-') repeated that many times 60hP62h % prepend 60 ('<'), postpend 62 ('>') c % convert to char w % swap. Implicit display  # Ruby, 83 characters ->a{n,m=a.minmax s=' '*(d=m-n+3) l=?@ a.map{|i|s[i-n+2]=l.next!} puts ?<+?-*d+?>,s}  Sample run: irb(main):001:0> ->a{n,m=a.minmax;s=' '*(d=m-n+3);l=?@;a.map{|i|s[i-n+2]=l.next!};puts ?<+?-*d+?>,s}[[32767,32715,32716,32750,32730,32729,32722,32766,32740,32762]] <-------------------------------------------------------> BC G FE I D J HA  # JavaScript (ES6), 124 l=>(l.map(v=>r[v-Math.min(...l)]=(++i).toString(36),r=[],i=9),<-${'-'.repeat(r.length)}->
+[...r].map(x=>x||' ').join)


TEST

F=
l=>(l.map(v=>r[v-Math.min(...l)]=(++i).toString(36),r=[],i=9),<-${'-'.repeat(r.length)}-> +[...r].map(x=>x||' ').join) console.log=x=>O.textContent+=x+'\n' test= [[32767,32715,32716,32750,32730,32729,32722,32766,32740,32762], [2015,2014],[1990,1996,1999,2011,2016],[2,3,1,5,4],[12345]] test.forEach(x=>console.log(x+'\n'+F(x)+'\n')) <pre id=O></pre> # PHP, 129126125121117 115 bytes Uses ISO 8859-1 encoding. $l=min([$h=max($z=$argv)]+$z)-3;echo~str_pad(Ã,$h-$l,Ò).~ÒÁõ;for(;$l<$h;)echo chr((array_search(++$l,$z)-1^32)+65);


Run like this (-d added for aesthetics only):

php -r '$l=min([$h=max($z=$argv)]+$z)-3;echo~str_pad(Ã,$h-$l,Ò).~ÒÁõ;for(;$l<$h;)echo chr((array_search(++$l,$z)-1^32)+65);' 1990 1996 1999 2016 2011 2>/dev/null;echo  Ungolfed version: // Get the highest input value.$h = max($z =$argv);

// Get the lowest value, setting the first argument (script name) to the highest
// so it is ignored.
$l = min([$h] + $z); // Output the first line. echo "<".str_repeat("-",$h - $l + 3).">\n "; // Iterate from$l to $h. for(;$l <= $h;) // Find the index of the current iteration. If found, convert the numeric // index to a char. If not found, print a space. echo ($s = array_search($l++,$z)) ? chr($s+64) : " ";  • Saved 3 bytes by printing leading spaces from the loop and changing <= to <. • Saved a byte by using str_pad instead of str_repeat. • Saved 4 bytes by using bitwise logic to convert 0 (false) to 32, and everything above 0 to 97 onwards. Then convert that number to char. • Saved 4 bytes by using negated extended ASCII to yield <, -, > and newline • Saved 2 bytes by negating string after padding instead of before # Perl, 109 bytes includes +1 for -p $l=A;s/\d+/$h{$&}=$l++/ge;($a,$z)=(sort keys%h)[0,-1];$o.=$h{$_}//$"for$a..$z;$_='<'.'-'x($z-$a+3).">$/$o"


Expects input on stdin: space separated numbers. Example:

$echo 2016 2012 2013 | perl -p file.pl <-------> BC A  Somewhat readable: $l=A;                                   # Intialize $l with the letter A s/\d+/$h{$&}=$l++/ge;                   # construct %h hash with number->letter
($a,$z) = (sort keys %h)[0,-1];         # grab min/max numbers
$o .=$h{$_} //$" for $a..$z;          # construct 2nd line: letter or space
$_= '<' . '-' x ($z-$a+3) . ">$/  $o" # construct 1st line, merge both lines to$_ output


## Python 2, 173172 182 bytes

since Python is missing yet, here is my first post:

import sys
d=dict([(int(v),chr(65+i))for(i,v)in enumerate(sys.argv[1:])])
k=sorted(d.keys())
f=k[0]
s=k[-1]-f+3
o=list(" "*s)
for i in k:o[i-f+2]=d[i]
print "<"+"-"*s+">\n"+"".join(o)


the original looks following:

import sys

dates = dict([(int(v), chr(65+i)) for (i,v) in enumerate(sys.argv[1:])])
keys = sorted(dates.keys())
first = keys[0]
out_size = keys[-1] - first + 3
out = list(" " * out_size)
for date in keys: out[date - first + 2] = dates[date]
print "<" + "-" * out_size + ">\n" + "".join(out)

• You need import sys in your golfed version.
– user45941
Feb 22, 2016 at 9:17
• ok, I will, but I have never seen any imports in the golfed versions, so I just left it out Feb 23, 2016 at 9:34

# Groovy, 106 99 characters

{n=it.min()
o=[l="A"]
it.each{o[it-n]=l++}
"<${"-"*(it.max()-n+3)}>\n "+o.collect{it?:" "}.join()}  Sample run: groovy:000> print(({n=it.min();o=[l="A"];it.each{o[it-n]=l++};"<${"-"*(it.max()-n+3)}>\n  "+o.collect{it?:" "}.join()})([32767,32715,32716,32750,32730,32729,32722,32766,32740,32762]))
<------------------------------------------------------->
BC     G      FE         I         D           J   HA