シンプルASCIIガント


31

これは簡単です:ASCII ガントチャートを印刷します。

指定されたタスクの範囲(開始時間-終了時間のタプル)で、-各タスク期間(新しいタスクの各タスク)の文字の形式でガントタイムラインを印刷します。

私のタスクの範囲は28->35, 34->40, 39->44であるとすると、ガントは次のようになります。

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

仕様書

  • 完全なプログラム、名前付き関数、または匿名関数を作成できます。
  • プログラム/関数は、STDINを介して、または引数としてタスクを受け入れる必要があります
  • 各タスクは、start->endwhere startおよびendare Integersの文字列として表される必要があります。タスクはスペースまたはカンマで区切られます。または、整数のタプル、または2つの整数の配列/コレクションとして取得することもできます。(たとえば、JavaScriptでは次のように取得できます[start,end]-これは許可されています)。
  • 負でない数のタスク(引数)をサポートする必要があります。
  • 明確にするために、タスクコレクションの単一の引数は許可されていません。単一の文字列引数を解析するか、0個以上のタスク引数をサポートできます。taskはサイズ2のタプルまたはコレクションです。
  • 有効な入力のみが与えられると想定できます。つまり、各タスクには正の期間があります。
  • 戻り値は重要ではありません。コードはSTDOUTにタイムラインを出力する必要があります。
  • 出力:タスクごとに、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
ポイント3は明らかです。しかし、piint 5(To make it clear...)はまったく明確ではありません。
edc65

申し上げます。文字列でない限り、引数を1つだけ受け入れる関数を作成することはできません。私たちが話しているタプルの束である場合、それらは引数としてコレクションにラップされずに関数に送信される場合があります。たとえば、JavaScriptの場合:arguments関数内で反復できますが、それがarguments[0]タスクの配列であると想定することはできません。
ジェイコブ

8
すべての言語の配列/リスト/ベクトル/などとして単純に入力を許可しないのはなぜですか?個人的な好みはかなり弱い理由のようです。
ドアノブ

1
私の意見では、可変引数と引数リストは純粋に構文上の違いであり、この質問のルールは不必要でarbitrary意的な解釈に任されています。
JohnE

2
@Jacobは理にかなっています。将来の課題については、可能な限り入力仕様を緩くすることをお勧めします。入力のマングリングは課題の一部であってはなりません。
アダム

回答:


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よりも短いです:)入力はバイトのリストです。各ペアはガントの1行です。

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

試してみる

http://copy.sh/brainfuck/

入力の終わりcharをvalueに設定します\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 => worldは間もなく終了します。
アレックスA.

1
説明は実際にうまくいくはずです。そこで唯一のbfコマンドはある<>、彼らは完璧にバランスしています。
地下

@undergroundmonorailすてきなキャッチ、私はそれらがバランスが取れているかどうかを確認しようとさえしなかった;)
ロルフツ


5

C ++ 14、69バイト

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

初めてのゴルフでは、これは最初から良い問題でした!


2
あなたは必要std::ではcinありcoutませんか?
アレックス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}.'()

Iは各(アンパック'ドット適用を(使用)タプルを.ラムダ内部Iは、開始と終了の値にアクセスできるように)xy、それぞれ。次に、これらを(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文字の配列にインデックスを付け、すべてを標準出力(0:)に送信する必要があります。


3

JavaScript(ES6)、63


匿名関数が許可されているため、Fへの割り当てをカウントしない63 バイトの保存された3バイトのthx @apsillersを編集します。

要求に応じて、可変数のパラメーターを持つ関数。
単一のパラメーターとしてタスクのリストを持つ関数。

以下のスニペットの実行をテストします(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]グローバルに割り当てて1バイトを保存します(または、グローバルにしlたくない場合は、安全に割り当てることができます)。また、仕様では「名前付き関数または匿名関数」が許可されているためF=、バイトカウントでを省略できると思います。
apsillers

@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))など

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

表示するタスクごとに1つずつ、複数の2要素配列を受け入れるように更新されました。(それが更新された要件が期待するものだと思います。)


2

Javascript(ES6)、61/66文字

私の答えは@ edc65によって投稿されたものとほぼ同じですが、いくつかの改善があります。単一配列のタスクは許可されていないため(関数は次のように呼び出されa([3,4], [7,15], [0,14], [10, 15])ます:)、正しいものはこれ(名前が割り当てられていない66文字)です。

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

そして、1つの配列引数が許可されている場合(したがって、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]]).出力

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

申し訳ありませんが、この回答の入力形式は仕様を満たしていません。各タスクは2つではなく1つの引数で表す必要があります。(私がよく知らないSWI-Prolog構文の何かを見逃さない限り...)
ジェイコブ

@Jacobうん、あなたの投稿を読み直したとき、私はそれを理解し、それを説明するためにすでにコードを変更しました。
15年

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ダッシュが続き、改行が続き、すべてを1つの文字列に連結します。印刷する。

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に出力する匿名関数が作成されます。

Ungolfed +説明:

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:不便はありません。ナイスチャレンジ。:)
アレックスA.

1

JavaScript(ES6)、106 85 80 68バイト

更新された要件に従って、タスクのリストが受け入れられるようになりました

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

0個以上の引数を取ります: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新しい何かを見せてくれてありがとう!! 残念ながら、コードゴルフの場合、実際にはそれを使用する方が長くなります
rink.attendant.6

実際、その2次元aは実際には役立ちません。私のような心の何かに持っていました()=>{for(i=0,s='';a=arguments[i++];)s+='_'.repeat(a[0])+'-'.repeat(a[1]-a[0])+"\n";return s}
マナトワーク

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三項よりも短いです。(+1バイト)に置き換えるc=!cと、(-3バイト)にc^=13変更できます。からループの終わりにフリップを移動します。-94バイト。c?45:3232+ccfor(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);}}
-aragaer

1

Perl:42 41文字

少なくとも1つのストリング解析を使用したソリューションも必要です。

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の回答がすでにあります:)とにかく、これもありがとう!
ジェイコブ

はい。ただし、質問で指定された形式ではなく、カンマで区切られた数字を想定していることを理解しています。
マナトワーク

1

Javaの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ガントチャートを標準出力に出力するメソッド。

10バイトの節約を支援してくれたdurron597とmasterX244に感謝


I think you're allowed to use a method instead.
lirtosiast

It is allowed iff this is the (or a) way to create an anonymous function in Java8. Is it?
Jacob

It's the closest thing Java 8 has to such a feature.
SuperJedi224

If you do Integer i=0; you can do for(;i<i.parseInt;, saving 8 characters.
durron597

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

1

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.


you can shorten the loops if you use the 3rd bulletpoint of the current question version and varargs for the input
masterX244

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




1

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.


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

1

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 "-".


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!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.