調整さん問題をRubyで解く

日時を列挙する問題

m月d日からd+n日のhh:MM-hh:MMに取れるm時間枠の日時を列挙する。

枠は開始時刻から詰めて取るものとする。終了時刻以降に差し掛かる場合は、その枠は取れない。

入力
1/7-1/16 9:30-17:30 1.5
出力

たとえば、1月7日から1月16日の9:30-17:30に取れる1.5h枠の会議日時を列挙すると、次のようになる。(追記)出力する数字は0詰めするものする。

01/07(水) 09:30-11:00
01/07(水) 11:00-12:30
01/07(水) 12:30-14:00
[...]
01/16(金) 12:30-14:00
01/16(金) 14:00-15:30
01/16(金) 15:30-17:00
自分のコード
#!/usr/bin/ruby
# coding: utf-8
require 'date'

def check(input)
  unless input[0].split(",")[0].include?("/")
    print "mm/dd-mm/dd形式で日付を入力\n"
    exit
  end
end

def get_day(day)
  md = day.split("/")
  Date::new(Time.now.year, md[0].to_i, md[1].to_i)
end

def f_day(d)
  wdays = ["", "", "", "", "", "", ""]
  d.strftime("%m") << "/" << d.strftime("%d") << "(#{wdays[d.wday]})"
end

def f_time(t)
  t.strftime("%H") << ":" << t.strftime("%M")
end

input = ARGV
check(input)

days = input[0].split(",")[0].split("-")
begin_time = input[1].split("-")[0]
end_time = input[1].split("-")[1]
min_box = input[2].to_f * 60

for d in get_day(days[0]) .. get_day(days[1]) do
  t_day = Time.local(d.year, d.month, d.day, 0, 0, 0)
  begin_min = begin_time.split(":")[0].to_i * 60 + begin_time.split(":")[1].to_i
  end_min = end_time.split(":")[0].to_i * 60 + end_time.split(":")[1].to_i

  begin_min.step(end_min - min_box, min_box){|min|
    print f_day(d) << " " << f_time(t_day + min * 60) << "-" << f_time(t_day + min * 60 + min_box * 60) << "\n"
  }
end

こんなんRubyならワンライナーじゃないの、とか雑に思ってたけど、自分にはムリでした。残念。

Rubyの範囲オブジェクトとstepを覚えた。

背景

社内勉強会のアレンジをチャットや調整さんでする時、

だいたいこういう感じになります。日時を列挙するのが面倒だったので。