crontab書式を解釈しよう
締め切りが 2017/06/16 10:00 AM なので,その 1 分後に投稿されるように予約
設問
あなたはとあるジョブ管理ツールの開発を任されており、定時実行のためにcrontab(Wikipediaへのリンク)の書式で記述されたスケジュールに対応することになりました。
そこで、まず与えられたスケジュールを正しく解釈できるかテストするためのプログラムを作ることにしました。
求められるプログラムの前提条件は、以下の通りとなります。
標準入力から、crontabの書式で記述されたスケジュールの文字列が1行送られる
文字列は、9文字以上80文字以下とし、フィールド間はスペースで区切られているものとする
文字列のうち、解釈の対象となるのは"時フィールド"のみとし、その他は無視するものとする
文字列に、コメントや、第6フィールド以降(コマンド記述)は含まれないものとする
文字列から、何時(0-23)に実行されるかを求め、数値が複数の場合はスペース区切りで標準出力に送ること
複数の値を指定する特殊記号として、アスタリスク (*) スラッシュ(/) ダッシュ (-) コンマ(,)を考慮すること
それぞれのルールはWikipedia上のcrontabの解説(リンク先)に従うこと
入出力例にはないが、範囲外の値(0未満または24以上)の指定がある場合も、無視すること
出力する数値に重複があった場合は、除外した上で出力すること
出力する数値は、小さい値から大きい値の順になるようソートすること
以下、入出力例になります。
入力 出力
0 1,3,2 * * * 1 2 3
0 5,5,6 * * * 5 6
0 */6 * * * 0 6 12 18
0 3-4,7-8 * * * 3 4 7 8
0 1-10/5 * * * 1 6
【問題】
標準入力から、crontabの書式で記述されたスケジュールの文字列が送られます。
この文字列を解釈し、何時に実行されるかを求め、その結果を標準出力に返してください。
============================
f = function(S) {
S = strsplit(S, " ")[[1]][2]
S = strsplit(S, ",")[[1]]
ans = NULL
for (s in S) {
if (grepl("/", s)) {
s = strsplit(s, "/")[[1]]
if (s[1] == "*") {
s[1] = "0-23"
}
if (grepl("-", s[1])) {
s2 = as.integer(strsplit(s[1], "-")[[1]])
hour = seq(s2[1], s2[2], by = as.integer(s[2]))
ans = c(hour, ans)
}
} else if (grepl("-", s)) {
s = as.integer(strsplit(s, "-")[[1]])
ans = c(s[1]:s[2], ans)
} else {
ans = c(as.numeric(s), ans)
}
}
cat(unique(sort(ans)))
}
f("0 9-10,18-19 * * *") # 9 10 18 19
f("0 8-18/3 * * *") # 8 11 14 17
f("0 */8,18-23 * * *") # 0 8 16 18 19 20 21 22 23