Created
April 5, 2011 22:23
-
-
Save tyuki39/904709 to your computer and use it in GitHub Desktop.
時間帯重複チェック(応用編)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MyTime implements Comparable { | |
int hour | |
int minutes | |
MyTime(hour, minutes) { | |
this.hour = hour | |
this.minutes = minutes | |
assert isValid(), "The time ${this} is not valid." | |
} | |
int compareTo(that) { | |
(hour*60+minutes) <=> (that.hour*60+that.minutes) | |
} | |
boolean isValid() { | |
((0..23).contains(hour) && (0..59).contains(minutes)) || (hour == 24 && minutes == 0) | |
} | |
MyTime next() { | |
new MyTime(hour + (int)((minutes+1)/60), (minutes+1)%60) | |
} | |
MyTime previous() { | |
new MyTime(hour + (int)((minutes-61)/60), (minutes+59)%60) | |
} | |
String toString() { | |
"${hour}:${minutes}" | |
} | |
} | |
@Newify([MyTime]) | |
class MyDuration implements Comparable { | |
ObjectRange duration | |
MyDuration(fromHour, fromMinutes, toHour, toMinutes) { | |
duration = MyTime(fromHour, fromMinutes)..MyTime(toHour, toMinutes) | |
assert duration.from <= duration.to, "The time ${duration.from} must be followed by the time ${duration.to}." | |
} | |
int compareTo(that) { | |
duration.from == that.duration.from ? duration.to <=> that.duration.to : duration.from <=> that.duration.from | |
} | |
String toString() { | |
"${duration.from}-${duration.to}" | |
} | |
// MyDurationのOR演算( 重なりあり => [ MyDuration ], 重なりなし => [ MyDuration, MyDuration ] ) | |
ArrayList or(that) { | |
if( this & that ) { | |
def result = ((duration as List) + (that.duration as List)).sort().unique() | |
[ new MyDuration(result[0].hour, result[0].minutes, result[-1].hour, result[-1].minutes) ] | |
} | |
else { | |
[ this, that ] | |
} | |
} | |
// MyDurationのAND演算( 重なりあり => [ MyDuration ], 重なりなし => [ ] ) | |
ArrayList and(that) { | |
def result = duration.intersect(that.duration) | |
if( result.size() > 1 ) [ new MyDuration(result[0].hour, result[0].minutes, result[-1].hour, result[-1].minutes) ] | |
else [] | |
} | |
} | |
@Newify([MyDuration]) | |
def makeDuration() { [ | |
[ | |
input : [ MyDuration(12, 0, 13, 0), MyDuration(10, 0, 12, 15) ], | |
output: [ MyDuration(12, 0, 12, 15) ], | |
], | |
[ | |
input : [ MyDuration(16, 0, 23, 0), MyDuration(9, 0, 17, 0), MyDuration(5, 0, 10, 30) ], | |
output: [ MyDuration(9, 0, 10, 30), MyDuration(16, 0, 17, 0) ], | |
], | |
[ | |
input : [ MyDuration(12, 0, 23, 0), MyDuration(13, 0, 14, 0), MyDuration(15, 0, 16, 0), MyDuration(17, 0, 18, 0), MyDuration(19, 0, 20, 0), MyDuration(21, 0, 22, 0) ], | |
output: [ MyDuration(13, 0, 14, 0), MyDuration(15, 0, 16, 0), MyDuration(17, 0, 18, 0), MyDuration(19, 0, 20, 0), MyDuration(21, 0, 22, 0) ], | |
], | |
[ | |
input : [ MyDuration(10, 0, 12, 0), MyDuration(11, 0, 11, 30), MyDuration(10, 30, 11, 15) ], | |
output: [ MyDuration(10, 30, 11, 30) ], | |
], | |
[ | |
input : [ MyDuration(9, 0, 17, 0), MyDuration(19, 0, 21, 0) ], | |
output: [ ], | |
], | |
] } | |
def timeDuplicationCheck2 = { input -> | |
// MyDurationのすべてのペアに対して重複している時間帯を得る | |
def rawList = [] | |
input.eachWithIndex { d1, i -> | |
input.eachWithIndex { d2, j -> | |
if( i > j ) { | |
(d1 & d2).with { if( it ) rawList << it[0] } | |
} | |
} | |
} | |
// 並べ替えと同一範囲の除去を行う | |
rawList.sort().unique() | |
// 重複している時間帯を結合したリストを作成する | |
def resultList = [] | |
rawList.each { | |
if(resultList) { | |
resultList.addAll(resultList.pop() | it) | |
} | |
else { | |
resultList << it | |
} | |
} | |
resultList | |
} | |
makeDuration().each { | |
assert timeDuplicationCheck2(it.input) == it.output | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment