Skip to content

Instantly share code, notes, and snippets.

@yasuharu519
Created April 6, 2011 09:07
Show Gist options
  • Save yasuharu519/905367 to your computer and use it in GitHub Desktop.
Save yasuharu519/905367 to your computer and use it in GitHub Desktop.
check if the time is duplicated. if it is duplicated, this code returns the part of the time which is duplicated. see -> http://d.hatena.ne.jp/fumokmm/20110329/1301403400#20110329f1
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# お題: 時間帯重複チェック(応用編)
def CheckIfSyntax(*timeTuple):
for i in xrange(len(timeTuple)):
(timeStartHour, timeStartMin, timeEndHour, timeEndMin) = timeTuple[i]
# 時間の書式のチェック
if timeStartHour > 24 or timeEndHour > 24 \
or timeStartHour < 0 or timeEndHour < 0:
raise Exception("Syntax Error")
if timeStartMin >= 60 or timeEndMin >= 60 \
or timeStartMin < 0 or timeEndMin <0:
raise Exception("Syntax Error")
if (timeStartHour == 24 and timeStartMin != 0) \
or (timeEndHour == 24 and timeEndMin != 0):
raise Exception("Syntax Error")
# 開始時刻よりも終了時刻が遅くなっているか確認
timeStartTimeInMin = timeStartHour * 60 + timeStartMin
timeEndTimeInMin = timeEndHour * 60 + timeEndMin
if timeStartTimeInMin > timeEndTimeInMin:
raise Exception("時刻が開始時刻よりも終了時刻が早くなっています")
def MakeEachTimeLine(*time):
# 時間軸を表すリストを作成
timeLines = [[[ 0 for x in xrange(60)] for y in xrange(25)]
for z in xrange(len(time))]
# 全ての時間情報をリストにして表す
# 時間の範囲を1として、範囲外を0として表現する
count = 0
for i in time:
(timeStartHour, timeStartMin, timeEndHour, timeEndMin) = i
if timeStartHour != timeEndHour:
timeLines[count][timeStartHour][timeStartMin:] = \
[1 for x in xrange(60 - timeStartMin)]
timeLines[count][timeEndHour][:timeEndMin+1] = \
[1 for x in xrange(timeEndMin+1)]
while True:
timeStartHour += 1
if timeStartHour >= timeEndHour:
break
timeLines[count][timeStartHour] = [1 for x in xrange(60)]
if timeStartHour == timeEndHour:
timeLines[count][timeStartHour][timeStartMin:timeEndMin+1] = \
[1 for x in xrange(timeEndMin - timeStartMin + 1)]
count += 1
return timeLines
def timeDuplicationCheck2(*timeData):
"""
>>> timeDuplicationCheck2((12, 0, 13, 0), (10, 0, 12, 15))
((12, 0, 12, 15),)
>>> timeDuplicationCheck2((16, 0, 23, 0), (9, 0, 17, 0), (5, 0, 10, 30))
((9, 0, 10, 30), (16, 0, 17, 0))
>>> timeDuplicationCheck2((12, 0, 23, 0), (13, 0, 14, 0), (15, 0, 16, 0), (17, 0, 18, 0), (19, 0, 20, 0), (21, 0, 22, 0))
((13, 0, 14, 0), (15, 0, 16, 0), (17, 0, 18, 0), (19, 0, 20, 0), (21, 0, 22, 0))
>>> timeDuplicationCheck2((10, 0, 12, 0), (11, 0, 11, 30), (10, 30, 11, 15))
((10, 30, 11, 30),)
>>> timeDuplicationCheck2((9, 0, 17, 0), (19, 0, 21, 0))
()
"""
# シンタックスの確認
CheckIfSyntax(*timeData)
# 時間情報をリストで表す
timeLines = MakeEachTimeLine(*timeData)
# アウトプット用の時間軸リスト
SumOfTimeLine = [[ 0 for x in xrange(60)] for y in xrange(25)]
# 全ての時間情報を表したリストをアウトプット用の時間軸リストに足し合わせる
for timeLine in timeLines:
for hour in xrange(25):
for minute in xrange(60):
SumOfTimeLine[hour][minute] += timeLine[hour][minute]
# 時間情報の整理:時間が重なっているところは2以上になるはず
# 2以上になっているところをすべて1にしてそれ以外を0として表現
for hour in xrange(25):
for minute in xrange(60):
if not SumOfTimeLine[hour][minute] in [0,1]:
SumOfTimeLine[hour][minute] = 1
else:
SumOfTimeLine[hour][minute] = 0
output = list()
# パターンを使って、時間が重なり始めたところか、重なり終わったところか確認
# [0,1] => 重なり始め
# [1,1] => 時間が重なり続けている部分
# [1,0] => 重なり終わり
pattern = [0,0]
hour = 0
for timeLine in SumOfTimeLine:
minute = 0
while timeLine:
pattern.pop(0)
pattern.append(timeLine.pop(0))
if pattern == [0,1]:
(startHour, startMinute) = (hour, minute)
elif pattern == [1,0]:
(endHour, endMinute) = (hour, minute-1)
output.append((startHour, startMinute, endHour, endMinute))
minute += 1
hour += 1
return tuple(output)
def _test():
import doctest
doctest.testmod()
if __name__ == '__main__':
_test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment