33
\$\begingroup\$

This is a simple one: print an ASCII Gantt chart.

Given tasks' ranges (start-time - end-time Tuples), print a Gantt timeline in the form of - characters for each task duration - each task in a new line.

Example

Say my tasks ranges are 28->35, 34->40, 39->44, the Gantt will look like this:

                            -------
                                  ------
                                       -----

Specifications

  • You can write a full program, a named function or an anonymous function.
  • Your program/function should accept the tasks via STDIN or as arguments.
  • Each task should be represented as a string of start->end where start and end are Integers. Tasks are separated by spaces or commas. Alternatively, you may get it as a Tuple of Integers, or as an Array/Collection of 2 Integers. (For example, in JavaScript you can get it as [start,end] - this is allowed).
  • Any non-negative number of tasks (arguments) should be supported.
  • To make it clear, a single argument of tasks collection is not allowed. You can either parse a single string argument, or support zero-or-more tasks arguments. Where task is a tuple or a collection of size 2.
  • You can assume only valid input will be given. That means, each task has a positive duration.
  • Return value does not matter, your code must print the timeline on STDOUT.
  • Output: per task, start spaces followed by (end-start) dashes and a \n.
  • Needless to say, output lines should be ordered correspondingly with the input (tasks) order.
  • Trailing spaces before the \n are allowed, if that helps you.

Test cases

Input:
(empty)

Output:
(empty)


Input:
0->7,5->6,3->6

Output:
-------
     -
   ---


Input:
5->20,5->20,2->10,15->19

Output:
     ---------------
     ---------------
  --------
               ----

Winning

  • This is so the least code length (in bytes) wins.
  • Traditionally, tie breaker is earlier post.
  • "Standard loopholes are no longer funny".

-----

EDIT

As many of you understood that it is allowed to have a single tasks collection argument, and since there's no much different between that and the original varargs requirement, it is now allowed to have a single collection argument, if you don't want to use the varargs option, or in case your language does not support varargs.

\$\endgroup\$
18
  • 1
    \$\begingroup\$ Point 3 seems clear. But piint 5 (To make it clear...) is not clear at all. \$\endgroup\$
    – edc65
    Jun 29, 2015 at 14:37
  • \$\begingroup\$ Alright, let me rephrase that: You cannot write a function that accepts exactly one argument unless it's a string. If it's a bunch of tuples we're talking about, they may be sent to your function as arguments, not wrapped in a collection. For example, in JavaScript: You may iterate arguments within the function, but you may not assume that arguments[0] is an array of tasks. \$\endgroup\$
    – Jacob
    Jun 29, 2015 at 14:43
  • 8
    \$\begingroup\$ Why not simply allow input as an array / list / vector / etc. for all languages? Personal preference seems like a pretty weak reason. \$\endgroup\$
    – Doorknob
    Jun 29, 2015 at 14:58
  • 1
    \$\begingroup\$ Varargs versus an argument list is a purely syntactic distinction and leaves the rules of this question up to an unnecessary and arbitrary degree of interpretation, in my opinion. \$\endgroup\$
    – JohnE
    Jun 29, 2015 at 15:03
  • 2
    \$\begingroup\$ @Jacob Makes sense. For future challenges, I'd recommend as lax an input spec as possible: Mangling input shouldn't be part of the challenge. \$\endgroup\$
    – Adám
    Jan 29, 2018 at 12:28

42 Answers 42

20
\$\begingroup\$

Python 2, 39 Bytes

Straightforward solution using string multiplication :)

for x,y in input():print' '*x+'-'*(y-x)

Accepts input formatted like so:

((5,20),(5,20),(2,10),(15,19))

Check it out here.

\$\endgroup\$
0
14
\$\begingroup\$

CJam, 16 14 bytes

q~{S.*~'-e]N}/

This expects a list of lists as input. For example:

[[5 20] [5 20] [2 10] [5 19]]

gives:

     ---------------
     ---------------
  --------
     --------------

How it works

q~                      e# Read the input and parse it as a list of list
  {         }/          e# Go over each item in the list in a for loop
   S                    e# S is basically this string - " "
    .*                  e# Multiply each item of the first list with the corresponding index
                        e# item of the second list. This basically repeats the space
                        e# X times where X is the first number of the tuple. The second
                        e# number remains untouched as the second list was only 1 char long
      ~                 e# Unwrap the space string and second number containing list
       '-               e# Put character '-' on stack
         e]             e# Make sure that the space is filled with - to its right so as to
                        e# make the total length of the string equal to the second number
           N            e# Put a newline. After all iterations, the result is printed
                        e# automatically to STDOUT

Try it online here

\$\endgroup\$
0
12
\$\begingroup\$

Brainfuck, 120 115 111 bytes

At least it's shorter than Java :) The input is a list of bytes, where each pair is a single line in the gantt.

++++[->++++++++<]>[->+>+<<]++++++++++>>+++++++++++++>+[,[->+>+<<]>>[-<<+>>],<[->-<<<<.>>>]>[-<<<.>>>]<<<<<.>>>]

Try out

http://copy.sh/brainfuck/

Set end-of-input to char with value \0. Example input: \5\20\5\20\2\10\15\19.

Note that setting the end-of-input value to \0 will have the side effect that no more input will be read (and thus stopping the program) when the input contains the number zero. In BF there is no other way of knowing when the input is exhausted.

Explanation*

++++[->++++++++<]>  #Store <space> at index 1                   
[->+>+<<]           #Move index 1 to index 2 and 3
++++++++++          #Increment index 1 to <newline>
>>                  #Move to index 3
+++++++++++++       #Increment index 3 to <dash>    
>                   #Move to (empty) index 4
+                   #Increment to start the main loop
[                   #Main loop
,                   #Read first number to index 4
[->+>+<<]>>[-<<+>>] #Copy index 4 to index 5 (index 5 can now be altered)
,                   #Read second number (the number pair is now stored at index 5 and 6)
<                   #Move to first number (index 5)
[->-<<<<.>>>]       #Decrement index 5 and 6 and print <space> until index 5 equals zero
>                   #move to second input (index 6)
[-<<<.>>>]          #Decrement index 6 and print <dash> until index 6 equals zero
<<<<<.>>>           #Print <newline> and move to index 4 (original first number)
]                   #End of main loop

*(You won't be able to compile/run this due to the comments)

\$\endgroup\$
3
  • 6
    \$\begingroup\$ Brainfuck shorter than Java => world will soon end. \$\endgroup\$
    – Alex A.
    Jun 29, 2015 at 19:49
  • 1
    \$\begingroup\$ The explanation should actually run fine. The only bf commands in there are < and >, and they're perfectly balanced. \$\endgroup\$ Jul 5, 2015 at 20:04
  • \$\begingroup\$ @undergroundmonorail Nice catch, I did not even try to see if they were balanced ;) \$\endgroup\$
    – Rolf ツ
    Jul 5, 2015 at 21:32
8
\$\begingroup\$

Pyth, 36 22 19 14 bytes

This is my first Pyth program. Jakube helped golf out 5 bytes!

FNQ<s*V" -"NeN

It expects input in the form [[5,20], [5,20], [2,10], [15,19]].

You can try it online.

\$\endgroup\$
0
5
\$\begingroup\$

C++14, 69 bytes

[]{int a,b;for(;cin>>a>>b;){cout<<setw(b)<<string(b-a,'-')+'\n';}}();

First time golfing, this was a good problem to start with!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Don't you need std:: on cin and cout? \$\endgroup\$
    – Alex A.
    Jul 4, 2015 at 2:50
3
\$\begingroup\$

K, 18 bytes

`0:" -"@{&x,y-x}.'

Expects a list of pairs as input:

  `0:" -"@{&x,y-x}.'(0 7;5 6;3 6)
-------
     -
   ---
  `0:" -"@{&x,y-x}.'(5 20;5 20;2 10; 15 19)
     ---------------
     ---------------
  --------
               ----
  `0:" -"@{&x,y-x}.'()

I unpack each (') tuple using dot-apply (.) so that inside the lambda I have access to the start and end value as x and y, respectively. Then I reassemble these into a (start,length) tuple (x,y-x) and apply "where" (&). This gives me output like so:

  {&x,y-x}.'(0 7;5 6;3 6)
(1 1 1 1 1 1 1
 0 0 0 0 0 1
 0 0 0 1 1 1)

Then I simply have to index into a 2-character array using this ragged matrix (" -"@) and send it all to stdout (0:).

\$\endgroup\$
0
3
\$\begingroup\$

JavaScript (ES6), 63

Edit 3 byte saved thx @apsillers
63 bytes not counting the assignment to F as an anonymous function is allowed.

A function with a variable number of parameters, as requested.
A function with a list of tasks as a single parameter.

Test running the snippet below (being EcmaScript 6, Firefox only)

F=l=>l.map(t=>console.log(' '.repeat(l=t[0])+'-'.repeat(t[1]-l)))

// TEST

// for this test, redefine console.log to have output inside the snippet
console.log = (...x) => O.innerHTML += x + '\n';

console.log('* Empty'); F([]);
console.log('\n* [0,7],[5,6],[3,6]'); F([[0,7],[5,6],[3,6]])
console.log('\n* [5,20],[5,20],[2,10],[15,19]');F([[5,20],[5,20],[2,10],[15,19]]);
<pre id=O></pre>

\$\endgroup\$
2
  • \$\begingroup\$ Save one byte by assigning t[0] to a global (or you can safely assign it to l if you don't want to make a global). Also, the spec allows "a named function or an anonymous function" so I think you could omit the F= in your byte count. \$\endgroup\$
    – apsillers
    Jun 29, 2015 at 16:15
  • \$\begingroup\$ @apsillers I missed the anonymous think. Thanks \$\endgroup\$
    – edc65
    Jun 29, 2015 at 16:23
3
\$\begingroup\$

Scala, 67 63 59 bytes

(r:Seq[(Int,Int)])⇒for((s,e)←r)(println(" "*s+"-"*(e-s)))

Usage: res0() or res0(Seq(28->35, 34->40, 39->44)) etc.

Thanks gilad for shaving 4 bytes using a for expression!

\$\endgroup\$
2
\$\begingroup\$

Ruby: 35 characters

->*t{t.map{|s,e|puts' '*s+?-*(e-s)}

Sample run:

irb(main):001:0> ->*t{t.map{|s,e|puts' '*s+?-*(e-s)}}.call [0,7], [5,6], [3,6]
-------
     -
   ---

Updated to accept multiple two-element arrays, one for each task to display. (I think that is what the updated requirement expects.)

\$\endgroup\$
0
2
\$\begingroup\$

Javascript(ES6), 61/66 chars

My answer is almost similar to the one posted by @edc65 , but with some improvements. As tasks in single array are not allowed(so function would be called like this: a([3,4], [7,15], [0,14], [10, 15])), correct one would be this(66 chars without name assignment):

a=(...x)=>x.map(([c,d])=>console.log(' '.repeat(c)+'-'.repeat(d-c)))

And if one array argument is allowed(so fn call like this: a([[3,4], [7,15], [0,14], [10, 15]])), then it would be(61 char without assignment):

a=x=>x.map(([c,d])=>console.log(' '.repeat(c)+'-'.repeat(d-c)))
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Classic), 12 bytes

↑('-'\⍨≤∘⍳)/

Try it online!

APL has no varargs, so the arg here is a single Nx2 matrix.

\$\endgroup\$
2
  • \$\begingroup\$ If you can take two arguments (starts and ends) then ↑'-'\⍨¨≤∘⍳¨ \$\endgroup\$
    – Adám
    Jan 29, 2018 at 10:32
  • \$\begingroup\$ challenge author says no \$\endgroup\$
    – ngn
    Jan 29, 2018 at 15:26
1
\$\begingroup\$

SWI-Prolog, 55 bytes

a([[A,B]|C]):-tab(A),writef("%r",[-,B-A]),nl,C=[];a(C).

Example: a([[5,20],[5,20],[2,10],[15,19]]). outputs

     ---------------
     ---------------
  --------
               ----
\$\endgroup\$
2
  • \$\begingroup\$ I'm sorry but the input format in this answer does not meet specifications - each task should be represented in one argument, not in two. (Unless I missed something in SWI-Prolog syntax which I'm not familiar with...) \$\endgroup\$
    – Jacob
    Jun 29, 2015 at 14:13
  • \$\begingroup\$ @Jacob Yeah when rereading your post I figured that and already changed my code to account for it. \$\endgroup\$
    – Fatalize
    Jun 29, 2015 at 14:14
1
\$\begingroup\$

Haskell, 76 bytes

(#)=replicate
f i=putStr$g=<<(read$'[':i++"]")
g(s,e)=s#' '++(e-s)#'-'++"\n"

Input format is a string of comma separated tuples, e.g. "(1,2),(3,4)".

Usage examples:

*Main> f "(1,2),(3,4)" 
  -
    -

*Main> f "(0,7),(5,6),(3,6)" 
-------
     -
   ---

How it works: for input parsing I enclose the input string in [ and ] and use Haskell's native read function for lists of integer tuples. The rest is easy: for each tuple (s,e) take s spaces followed by e-s dashes followed by a newline and concatenate all into a single string. Print.

Haskell, 59 bytes

with relaxed input format:

(#)=replicate
f=putStr.(g=<<)
g(s,e)=s#' '++(e-s)#'-'++"\n"

Now it takes a list of tuples, e.g f [(0,7),(5,6),(3,6)].

Works as described above, but without input parsing.

\$\endgroup\$
1
\$\begingroup\$

Julia, 44 bytes

x->for t=x a,b=t;println(" "^a*"-"^(b-a))end

This creates an anonymous function that accepts an array of tuples as input and prints to STDOUT.

Ungolfed + explanation:

function f(x)
    # Loop over the tasks (tuples) in x
    for t in x
        # Assign a and b to the two elements of t
        a,b = t

        # Print a spaces followed by b-a dashes on a line
        println(" "^a * "-"^(b-a))
    end
end

Examples:

julia> f([(5,20), (5,20), (2,10), (15,19)])
     ---------------
     ---------------
  --------
               ----

julia> f([(0,7), (5,6), (3,6)])
-------
     -
   ---

julia> f([])
\$\endgroup\$
2
  • \$\begingroup\$ Sure. Sorry for the inconvenience. \$\endgroup\$
    – Jacob
    Jun 29, 2015 at 15:16
  • \$\begingroup\$ @Jacob: No inconvenience. Nice challenge. :) \$\endgroup\$
    – Alex A.
    Jun 29, 2015 at 15:17
1
\$\begingroup\$

JavaScript (ES6), 106 85 80 68 bytes

As per the updated requirements, a list of tasks is now acceptable

a=>a.reduce((p,v)=>p+=' '.repeat(z=v[0])+'-'.repeat(v[1]-z)+"\n",'')

Takes zero or more arguments: 80 bytes

(...a)=>{s='';a.map(v=>s+=' '[r='repeat'](z=v[0])+'-'[r](v[1]-z)+"\n");return s}

Original attempt, 106 bytes:

(...a)=>{for(i=-1,s='',r='repeat';a.length>++i;){s+=' '[r](a[i][0])+'-'[r](a[i][1]-a[i][0])+"\n"}return s}
\$\endgroup\$
5
  • \$\begingroup\$ If it's ES6, then why not String.repeat()? \$\endgroup\$
    – manatwork
    Jun 29, 2015 at 14:55
  • \$\begingroup\$ @manatwork Thanks for showing me something new!! Unfortunately for code golf it is actually longer to use that \$\endgroup\$ Jun 29, 2015 at 14:59
  • \$\begingroup\$ Indeed, that two dimensional a not really helps. I had in mind something like ()=>{for(i=0,s='';a=arguments[i++];)s+='_'.repeat(a[0])+'-'.repeat(a[1]-a[0])+"\n";return s}. \$\endgroup\$
    – manatwork
    Jun 29, 2015 at 15:11
  • \$\begingroup\$ r='repeat' ? ... for 2 times? nah! a=>a.reduce((p,v)=>p+=' '.repeat(z=v[0])+'-'.repeat(v[1]-z)+"\n",'') \$\endgroup\$
    – edc65
    Jun 29, 2015 at 16:01
  • 1
    \$\begingroup\$ There is no output. Return value does not matter, your code must print the timeline on STDOUT. (and would be shorter too) \$\endgroup\$
    – edc65
    Jun 29, 2015 at 16:03
1
\$\begingroup\$

C: 108 bytes

void g(int*l){for(int c=0;*l>=0;c=!c,l++){if(!c)l[1]-=*l;while(l[0]-->0)putchar(c?45:32);c?putchar(10):0;}}

Ungolfed:

void gantt(int*l) {
    for (int c = 0; *l >= 0; c = !c, l++) {
        if (!c) l[1] -= *l;
        while (l[0]-- > 0) putchar(c? 45 : 32);
        c? putchar(10) : 0;
    }
}

Takes as a parameter a list of integers terminated by -1. For example:

int list[] = {
    28, 35,
    34, 40,
    39, 44,
    -1
};
gantt(list);

It uses c to toggle between writing spaces and dashes.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Make c static - you can drop its type (it will be int) and initialization (it will be zero). *l>=0 is the same as *l+1 which is shorter. c&&putchar is shorter than ternary. If you replace c=!c with c^=13 (+1 byte) you can change c?45:32 to 32+c (-3 bytes). Move c flip from for to the end of loop: (c^=13)||putchar(10);. c;void g(int*l){for(;*l+1;l++){l[1]-=c?0:*l;while(l[0]--)putchar(32+c);(c^=13)||putchar(10);}} - 94 bytes. \$\endgroup\$
    – aragaer
    Jun 30, 2015 at 12:37
1
\$\begingroup\$

Perl: 42 41 characters

Just to have at least one solution with string parsing too.

s!(\d+)->(\d+),?!$"x$1."-"x($2-$1).$/!ge

Sample run:

bash-4.3$ perl -pe 's!(\d+)->(\d+),?!$"x$1."-"x($2-$1).$/!ge' <<< '0->7,5->6,3->6'
-------
     -
   ---
\$\endgroup\$
2
  • \$\begingroup\$ Actually we already have the straightforward Java answer that parse a string :) Anyway, thanks for this one as well! \$\endgroup\$
    – Jacob
    Jun 29, 2015 at 14:49
  • \$\begingroup\$ Yes, but as I understand that expects comma separated numbers, not the format specified in the question. \$\endgroup\$
    – manatwork
    Jun 29, 2015 at 14:53
1
\$\begingroup\$

Java 8, 280 275 246 204 195 185 180 bytes

void g(String t){for(String s:t.split(",")){String[]a=s.split("->");s="";Integer i;for(i=0;i<i.valueOf(a[0]);i++)s+=" ";for(;i<i.valueOf(a[1]);i++)s+="-";System.out.println(s);};};

A method that takes a comma-seperated input string and prints the resulting ascii Gantt Chart to stdout.

Thanks to durron597 and masterX244 for helping me save 10 bytes

\$\endgroup\$
8
  • \$\begingroup\$ I think you're allowed to use a method instead. \$\endgroup\$
    – lirtosiast
    Jun 30, 2015 at 3:07
  • \$\begingroup\$ It is allowed iff this is the (or a) way to create an anonymous function in Java8. Is it? \$\endgroup\$
    – Jacob
    Jun 30, 2015 at 4:03
  • \$\begingroup\$ It's the closest thing Java 8 has to such a feature. \$\endgroup\$ Jun 30, 2015 at 11:47
  • \$\begingroup\$ If you do Integer i=0; you can do for(;i<i.parseInt;, saving 8 characters. \$\endgroup\$
    – durron597
    Jun 30, 2015 at 21:43
  • \$\begingroup\$ I couldn't get it to compile on Ideone, but it appears that it would not accept empty input, as the rules require (t.split(",") would throw an exception). \$\endgroup\$
    – Nateowami
    Jul 1, 2015 at 6:01
1
\$\begingroup\$

Java, 187 181 197 183 101 bytes

void g(int[][]g){for(int[]i:g)for(int j=0;j<i[1];System.out.print(j++<i[0]?" ":j==i[1]?"-\n":"-"));}

Ungolfed (sort of):

void g(int[][] g){
    for(int[] i : g)
        for(int j = 0; j < i[1]; System.out.print(j++ < i[0] ? " " : j == i[1] ? "-\n" : "-"));
}

Accepts input as 2d array of ints. Thanks to masterX244 for pointing out that this is allowed by the rules.

\$\endgroup\$
2
  • \$\begingroup\$ you can shorten the loops if you use the 3rd bulletpoint of the current question version and varargs for the input \$\endgroup\$
    – masterX244
    Jul 1, 2015 at 14:37
  • \$\begingroup\$ @masterX244 Thanks, I missed that. Seems to me like cheating to have it pre-parsed, but if cheating is allowed... whatever. I'll update it when I have time. \$\endgroup\$
    – Nateowami
    Jul 2, 2015 at 1:06
1
\$\begingroup\$

Jelly, 13 9 bytes

ạ\⁾ -xµ€Y

Try it online!

Takes input as [[5, 20], [5, 20], [2, 10], [15, 19]].

-4 bytes thanks to Erik

\$\endgroup\$
1
1
\$\begingroup\$

JavaScript (ES8), 54 bytes

a=>a.map(([x,y])=>"-".repeat(y-x).padStart(y)).join`
`

Try it online

\$\endgroup\$
1
\$\begingroup\$

PowerShell 3.0, 4836 Bytes

$args|%{" "*$_[0]+"-"*($_[1]-$_[0])}

Thanks to Mazzy for saving 12 with a better way to pass in the list

Old code and explanation:

&{param($b="")$b|%{" "*$_[0]+"-"*($_[1]-$_[0])}}

Takes arguments as a list of tuples, e.g. (5,20),(5,20),(2,10),(15,19). Had to default $b to a value to take care of the empty string because it somehow entered the foreach block when called with no input.

\$\endgroup\$
1
  • \$\begingroup\$ 36 bytes: $args|%{" "*$_[0]+"-"*($_[1]-$_[0])}. Save as get-asciiGantt.ps1. Test script .\get-asciiGantt.ps1 (5,20) (5,20) (2,10) (15,19) \$\endgroup\$
    – mazzy
    Jun 19, 2018 at 9:40
1
\$\begingroup\$

R, 117 90 75 bytes

function(y)for(i in 1:ncol(y))cat(" "<y[1,i],"-"<diff(y)[i],"
")
"<"=strrep

Try it online!

Giuseppe golfed at least 29 bytes off my original answer!

The idea is straightforward: print as many " " as necessary followed by as many "-" as required. Input is a 2*L matrix with L the number of pairs. The vectorized function diff is used to get the number of "-".

\$\endgroup\$
5
  • 1
    \$\begingroup\$ @Giuseppe this is what I get for trying to trying to stick to my original matrix idea while using a for loop... ty! \$\endgroup\$
    – JayCe
    Jun 18, 2018 at 16:02
  • \$\begingroup\$ 86 bytes \$\endgroup\$
    – Giuseppe
    Jun 18, 2018 at 17:34
  • \$\begingroup\$ @Giuseppe Transposed y to save a few more :) \$\endgroup\$
    – JayCe
    Jun 18, 2018 at 17:52
  • \$\begingroup\$ Now 1- indexed would save 4 \$\endgroup\$
    – JayCe
    Jun 18, 2018 at 17:55
  • \$\begingroup\$ Nice, use < instead of * and you can get this to 81 bytes \$\endgroup\$
    – Giuseppe
    Jun 19, 2018 at 20:19
1
\$\begingroup\$

K (ngn/k), 13 bytes

{" -"@&-':x}'

Try it online!

{ } function with argument x

{ }' apply to each - in this case to each pair of numbers from the input

-': subtract each prior - transform (a;b) into (a;b-a)

& "where" - transform (a;b-a) into a list of a zeroes followed by b-a ones

" -"@ use as indices in " -"

\$\endgroup\$
1
\$\begingroup\$

VBA (Excel), 99 90 bytes

Using Immediate Window and [A1] as input eg.0-1,2-5

Thanks to @TaylorSott for cutting some bytes.

b=Split([A1]):For x=0To Ubound(b):c=Split(b(x),"-"):?Spc(c(0)-0)String(c(1)-c(0),"-"):Next
\$\endgroup\$
2
  • 1
    \$\begingroup\$ If you change the input format to being space delimited rather than being comma delimited, you cang chage the first two clauses from a=[A1]:b=Split(a,",") to b=Split([A1]). Also, you can drop the space before the To in the For loop declaration. \$\endgroup\$ Feb 15, 2019 at 19:34
  • \$\begingroup\$ Thanks and noted! :D \$\endgroup\$
    – remoel
    Feb 18, 2019 at 8:32
1
\$\begingroup\$

Vyxal j, 9 bytes

ƛ÷ε\-*nt↳

Try it Online! Expects a list of lists.

ƛ         # Map each pair to...
 ÷ε       # Their difference
   \-*    # -s
      nt↳ # Padded to the length of the second. 
\$\endgroup\$
0
\$\begingroup\$

CoffeeScript, 104 82, 65 bytes

List of tasks (ES6): 65 bytes

(a)->a.map (v)->console.log ' '.repeat(v[0])+'-'.repeat v[1]-v[0]

List of tasks (ES5 variant): 82 bytes

(a)->a.map (v)->j=-1;s='';s+=(if j<v[0]then' 'else'-') while++j<v[1];console.log s

Zero or more arguments: 104 bytes

()->[].slice.call(arguments).map((v)->j=-1;s='';s+=(if j<v[0]then' 'else'-')while++j<v[1];console.log s)

Unminified:

() -> [].slice.call(arguments).map( # convert to array-like arguments to array and loop
 (v) ->
  j = -1 # counter
  s = '' # initialize string
  s += (if j < v[0] then ' ' else '-') while ++j < v[1]
  console.log s # print to STDOUT
)
\$\endgroup\$
2
  • \$\begingroup\$ Not sure from where to where is the JavaScript, CoffeeScript and ECMAScript in your answers, but in ECMAScript you can use Array.from(arguments) instead of [].slice.call(arguments). \$\endgroup\$
    – manatwork
    Jun 29, 2015 at 16:42
  • \$\begingroup\$ @manatwork As you can see in my answers (both ES5 and ES6, in CoffeeScript) addressing the changed requirement allowing a list of tasks, I don't need to reference arguments any more. \$\endgroup\$ Jun 29, 2015 at 16:56
0
\$\begingroup\$

PHP, 94 91 bytes

Takes a list of tasks (e.g. [[5,20],[5,20],[2,10],[15,19]]). Thanks @IsmaelMiguel for the reminder of variable function names.

function x($a){$r=str_repeat;foreach($a as$v){echo$r(' ',$v[0]).$r('-',$v[1]-$v[0])."\n";}}

Original attempt: 94 bytes

function x($a){foreach($a as$v){echo str_repeat(' ',$v[0]).str_repeat('-',$v[1]-$v[0])."\n";}}
\$\endgroup\$
3
  • \$\begingroup\$ 73 bytes, PHP4: $R=str_repeat;foreach($G as$v)echo$R(' ',$v[0]),$R('-',$v[1]-$v[0]),'\n'; (replace the \n with a real newline). For this to work, you need to send an array on the key $G, over POST/GET/SESSION/COOKIE... \$\endgroup\$ Jun 29, 2015 at 19:04
  • \$\begingroup\$ @IsmaelMiguel According to the question, the input needs to come as an argument or from STDIN. \$\endgroup\$ Jun 29, 2015 at 19:15
  • \$\begingroup\$ Does GET parameters count? And I think that GETuses STDIN. \$\endgroup\$ Jun 29, 2015 at 19:22
0
\$\begingroup\$

PHP, 89 characters (function body)

function gantt($x){array_walk($x,function($a){echo str_pad(str_repeat('-',$a[1]-$a[0]),$a[1],' ',0)."\n";});}

I was going to go for reading strings, but as a lot of the entries were taking arrays of integer pairs, I figured I would follow suit for the sake of brevity.

For each tuple $a in array $x I echo a string of dashes repeated $a[1] - $a[0] times, padded up to the larger number $a[1] with spaces. Then the obligatory newline.

\$\endgroup\$
6
  • \$\begingroup\$ You can make your function name just a single letter to save a few bytes. or better yet, if PHP supports anonymous functions, just omit a function name altogether. \$\endgroup\$
    – Alex A.
    Jun 29, 2015 at 17:43
  • 1
    \$\begingroup\$ Oh I see now what you mean by "function body." You have to count the entire function definition in your score, not just the innards. \$\endgroup\$
    – Alex A.
    Jun 29, 2015 at 17:47
  • 1
    \$\begingroup\$ printf() seems shorter than echo+str_pad(): function gantt($x){array_map(function($a){printf("%$a[1]s␊",str_repeat('-',$a[1]-$a[0]));},$x);} (The ␊ in the code is for a literal newline: just wrap your code there.) \$\endgroup\$
    – manatwork
    Jun 29, 2015 at 17:55
  • 1
    \$\begingroup\$ Actually a good old foreach is better: function g($x){foreach($x as$a)printf("%$a[1]s␊",str_repeat('-',$a[1]-$a[0]));} And this is 79 characters including everything. \$\endgroup\$
    – manatwork
    Jun 29, 2015 at 17:58
  • \$\begingroup\$ @AlexA. ah, I've seen golfs where people count or discount function headers. I wasn't sure what to go for, hence why I specified what count was what. \$\endgroup\$
    – JPMC
    Jun 29, 2015 at 20:13
0
\$\begingroup\$

Gema: 47 characters

<D>-\><D><y>=@left{$1;}@repeat{@sub{$2;$1};-}\n

Sample run:

bash-4.3$ gema '<D>-\><D><y>=@left{$1;}@repeat{@sub{$2;$1};-}\n' <<< '0->7,5->6,3->6'
-------
     -
   ---
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.