简单ASCII甘特图


31

这很简单:打印ASCII 甘特图

给定任务的范围(开始时间-结束时间元组),请以-字符形式为每个任务持续时间-每个任务在新行中打印甘特时间轴。

说我的任务范围是28->35, 34->40, 39->44,甘特图将如下所示:

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

技术指标

  • 您可以编写完整的程序,命名函数或匿名函数。
  • 您的程序/函数应通过STDIN 或作为参数接受任务。
  • 每个任务应表示为start->endwhere startendare Integers的字符串。任务由空格或逗号分隔。或者,您可以将其作为整数元组或2个整数的数组/集合来获取。(例如,在JavaScript中,您可以按以下方式获取它[start,end]-允许这样做)。
  • 任何非负数的任务(参数)都应受支持。
  • 为了清楚起见,不允许使用任务收集的单个参数。您可以解析单个字符串参数,也可以支持零个或多个任务参数。其中task是一个元组或大小为2的集合。
  • 您可以假设将仅给出有效输入。这意味着每个任务的持续时间都是正的。
  • 返回值无关紧要,您的代码必须在STD​​OUT上打印时间轴。
  • 输出:每个任务,start空格后接(end-start)破折号和a \n
  • 不用说,输出线应该与输入(任务)顺序相对应地排序。
  • \n如果可以的话,可以在之前加上空格。

测试用例

Input:
(empty)

Output:
(empty)


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

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


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

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

获奖

  • 这是因此最小的代码长度(以字节为单位)获胜。
  • 传统上,决胜局是较早的职位。
  • “标准漏洞不再有趣”。

-----

编辑

你们中的许多人都知道,允许有一个单一的任务集合参数,并且由于它与原始varargs要求之间没有太大区别, 因此如果您不想使用它,现在可以有一个单一的集合参数。 varargs选项,或者如果您的语言不支持varargs。


1
第三点似乎很清楚。但是piint 5(To make it clear...)根本不清楚。
edc65 2015年

好吧,让我重新表述一下:您不能编写仅接受一个参数的函数,除非它是字符串。如果我们要讨论的是一堆元组,它们可能会作为参数发送给您的函数,而不是包装在集合中。例如,在JavaScript中:您可以arguments在函数中进行迭代,但不能假定这arguments[0]是一个任务数组。
雅各布

8
为什么不简单地将所有语言的输入作为数组/列表/向量/等等?个人喜好似乎是一个很弱的原因。
门把手

1
在我看来,Varargs与参数列表是纯粹的语法区别,并且使该问题的规则具有不必要和任意程度的解释。
JohnE 2015年

2
@Jacob很有道理。对于未来的挑战,我建议尽可能宽松的输入规范:应对输入进行挑战不应该成为挑战。
亚当

Answers:


14

CJam,16个 14字节

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

这需要一个列表列表作为输入。例如:

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

给出:

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

怎么运行的

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

在这里在线尝试


20

Python 2,39字节

使用字符串乘法的简单解决方案:)

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

接受格式如下的输入:

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

在这里查看。


11

Brainfuck 120 115 111字节

至少它比Java短:)输入是字节列表,其中每一对都是甘特图中的一行。

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

试用

http://copy.sh/brainfuck/

将输入结束设置为charwith \0。输入示例: \5\20\5\20\2\10\15\19

请注意,将输入结束值设置为\0会产生副作用,当输入包含数字零时,将不再读取更多输入(并因此停止程序)。在BF中,没有其他方法可以知道输入何时耗尽。

说明*

++++[->++++++++<]>  #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

*(由于注释,您将无法编译/运行此文件)


6
比Java更短的Brainfuck =>世界即将结束。
Alex A.

1
解释实际上应该很好。其中仅有的bf命令为<>,它们完全平衡。
undergroundmonorail

@undergroundmonorail不错,我什至没有尝试看看它们是否平衡;)
Rolf

8

佩斯,36 22 19 14个字节

这是我的第一个Pyth程序。Jakube帮助打出5个字节!

FNQ<s*V" -"NeN

它期望以以下形式输入 [[5,20], [5,20], [2,10], [15,19]]

您可以在线尝试


5

C ++ 14,69个字节

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

第一次打高尔夫球,首先要解决好这个问题!


2
你不需要std::cincout
Alex A.

3

K,18个字节

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

期望输入对的列表:

  `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}.'()

'使用dot-apply(.)解压缩每个()元组,以便在lambda内分别访问作为x和的开始和结束值y。然后,将它们重新组合成一个(start,length)元组(x,y-x)并应用“ where”(&)。这给了我这样的输出:

  {&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)

然后,我只需要使用这个参差不齐的矩阵(" -"@)索引到2个字符的数组中,并将其全部发送到stdout(0:)。


3

JavaScript(ES6),63

编辑保存的3字节thx @apsillers
63字节,不计入F作为匿名函数的分配。

根据要求具有可变数量参数的功能。
将任务列表作为单个参数的函数。

测试下面的代码段(仅EcmaScript 6,仅Firefox)

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>


通过分配t[0]给全局变量来节省一个字节(或者,l如果您不想创建全局变量,则可以安全地将其分配给该字节)。另外,该规范允许使用“命名函数或匿名函数”,因此我认为您可以F=在字节数中省略。
apsillers 2015年

@apsillers我想念这个anonymous想法。谢谢
edc65

3

Scala,67 63 59字节

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

用法: res0()res0(Seq(28->35, 34->40, 39->44))等。

感谢gilad使用for表达式削减了4个字节!


2

Ruby:35个字符

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

样品运行:

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

更新为接受多个两个元素的数组,每个任务显示一个。(我认为这是更新的要求所期望的。)


2

Javascript(ES6),61/66个字符

我的答案与@ edc65发布的答案几乎相似,但有一些改进。由于不允许在单个数组中执行任务(因此将这样调用函数:)a([3,4], [7,15], [0,14], [10, 15]),正确的将是this(不带名称分配的66个字符):

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

并且如果允许一个数组参数(因此fn调用像这样:)a([[3,4], [7,15], [0,14], [10, 15]]),那么它将是(不分配的61个字符):

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

1

SWI-Prolog,55字节

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

示例:a([[5,20],[5,20],[2,10],[15,19]]).输出

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

抱歉,此答案中的输入格式不符合规范-每个任务应以一个参数而不是两个参数表示。(除非我错过了我不熟悉的SWI-Prolog语法中的内容...)
雅各布(Jacob

@Jacob是的,在重读您的帖子时,我想到了这一点,并且已经更改了我的代码以解决该问题。
致命

1

Haskell,76个字节

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

输入格式是一串用逗号分隔的元组,例如 "(1,2),(3,4)"

用法示例:

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

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

工作原理:对于输入解析,我将输入字符串括起来[]然后将Haskell的本机read函数用于整数元组列表。其余的操作很简单:对于每个元组,请(s,e)s空格后接e-s破折号,后跟换行符,并将所有内容连接成一个字符串。打印。

Haskell,59个字节

输入格式宽松:

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

现在,它获取一个元组列表,例如f [(0,7),(5,6),(3,6)]

如上所述工作,但是没有输入解析。


1

朱莉娅,44字节

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

这将创建一个匿名函数,该函数接受元组数组作为输入并打印到STDOUT。

取消+说明:

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

例子:

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

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

julia> f([])

当然。抱歉给你带来不便。
雅各布(Jacob)2015年

@Jacob:不便。很好的挑战。:)
Alex A.

1

JavaScript(ES6),106 85 80 68字节

根据更新的要求,现在可以接受任务列表

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

接受零个或多个参数:80个字节

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

原始尝试,106字节:

(...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}

如果是ES6,那为什么不String.repeat()呢?
manatwork 2015年

@manatwork感谢您给我展示一些新东西!不幸的是,对于代码高尔夫,实际上使用它的时间更长
rink.attendant.6 2015年

确实,这二维并a没有真正帮助。我想到了类似的东西()=>{for(i=0,s='';a=arguments[i++];)s+='_'.repeat(a[0])+'-'.repeat(a[1]-a[0])+"\n";return s}
manatwork 2015年

r ='repeat'吗?... 2次?不!a=>a.reduce((p,v)=>p+=' '.repeat(z=v[0])+'-'.repeat(v[1]-z)+"\n",'')
edc65

1
没有输出。Return value does not matter, your code must print the timeline on STDOUT.(并且也会更短)
edc65

1

C:108个字节

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;}}

取消高尔夫:

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;
    }
}

将以终止的整数列表作为参数-1。例如:

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

它用于c在书写空格和破折号之间切换。


1
将c设为静态-您可以删除其类型(它将为int)和初始化(它将为零)。*l>=0*l+1较短的相同。c&&putchar比三元短。如果替换c=!cc^=13(+1字节),则可以更改c?45:3232+c(-3字节)。将c翻转从移至for循环的结尾:(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个字节。
aragaer 2015年

1

Perl:42 41个字符

至少也要有一个字符串解析的解决方案。

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

样品运行:

bash-4.3$ perl -pe 's!(\d+)->(\d+),?!$"x$1."-"x($2-$1).$/!ge' <<< '0->7,5->6,3->6'
-------
     -
   ---

实际上,我们已经有了解析字符串的简单直接的Java答案:)无论如何,也感谢您!
雅各布(Jacob)

是的,但据我了解,期望使用逗号分隔的数字,而不是问题中指定的格式。
manatwork 2015年

1

爪哇8,280个 275 246 204 195 185 180字节

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);};};

该方法采用逗号分隔的输入字符串,并将结果ascii Gantt图表打印到stdout。

感谢durron597和masterX244帮助我节省了10个字节


我认为您可以改用一种方法。
lirtosiast

如果这是在Java8中创建匿名函数的(或一种)方法,则允许这样做。是吗?
雅各布

这是Java 8最接近这种功能的东西。
SuperJedi224

如果Integer i=0;可以for(;i<i.parseInt;,可以保存8个字符。
durron597

我无法在Ideone上对其进行编译,但是它似乎不接受空输入,这是规则所要求的(t.split(",")会引发异常)。
Nateowami

1

Java中,187个 181 197 183 101字节

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":"-"));}

松散的(某种):

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" : "-"));
}

接受输入为的2d数组int。感谢masterX244指出规则允许这样做。


如果您使用当前问题版本的第3个项目符号和varargs作为输入,则可以缩短循环
masterX244

@ masterX244谢谢,我错过了。对我来说,好像很喜欢作弊,要预先准备好,但是如果允许作弊……等等。有时间我会更新。
Nateowami




1

PowerShell 3.0, 4836字节

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

感谢Mazzy节省了12条以更好的方式传递列表的方法

旧代码和解释:

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

将参数作为元组列表,例如(5,20),(5,20),(2,10),(15,19)。必须将$ b缺省为一个值来处理空字符串,因为在无输入的情况下,它以某种方式进入了foreach块。


36个字节:$args|%{" "*$_[0]+"-"*($_[1]-$_[0])}。另存为get-asciiGantt.ps1。测试脚本.\get-asciiGantt.ps1 (5,20) (5,20) (2,10) (15,19)
mazzy

1

R117 90 75字节

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

在线尝试!

朱塞佩打高尔夫球至少比我原来的答案低29个字节!

这个想法很简单:先打印" "所需数量,然后再打印"-"所需数量。输入是2*L对数为L的矩阵。向量化函数diff用于获取“-”的数量。


1
@Giuseppe this is what I get for trying to trying to stick to my original matrix idea while using a for loop... ty!
JayCe


@Giuseppe Transposed y to save a few more :)
JayCe

Now 1- indexed would save 4
JayCe

Nice, use < instead of * and you can get this to 81 bytes
Giuseppe

1

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

1
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.
Taylor Scott

Thanks and noted! :D
remoel

0

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
)

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).
manatwork

@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.
rink.attendant.6

0

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";}}

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...
Ismael Miguel

@IsmaelMiguel According to the question, the input needs to come as an argument or from STDIN.
rink.attendant.6

Does GET parameters count? And I think that GETuses STDIN.
Ismael Miguel

0

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.


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.
Alex A.

1
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.
Alex A.

1
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.)
manatwork

1
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.
manatwork

@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.
JPMC

0

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'
-------
     -
   ---

0

PostgreSQL: 160 characters

create function g(int[])returns text as
$$select string_agg(lpad(repeat('-',$1[x][2]-$1[x][1]),$1[x][2]),chr(10))from generate_subscripts($1,1)x$$
language sql;

Sample run:

manatwork=# create function g(int[])returns text as
manatwork-# $$select string_agg(lpad(repeat('-',$1[x][2]-$1[x][1]),$1[x][2]),chr(10))from generate_subscripts($1,1)x$$
manatwork-# language sql;
CREATE FUNCTION

manatwork=# select g(array[[0,7],[5,6],[3,6]]);
-------
     -
   ---

0

J, 21 bytes

(' -'#~{.,-~/)"1 ::''

ungolfed

(' -' #~ {. , -~/)"1 ::''

This is essentially just J's copy verb #, but its we're copying the space character head of list {. number of times, and the hyphen character "2nd list element minus 1st list element" number of times: -~/. Sadly this forces us to have to specify the rank "1 explictly, and we need to use Adverse :: to handle the empty case.

Try it online!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.