Skip to content

Instantly share code, notes, and snippets.

@tyuki39
Created April 5, 2011 22:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tyuki39/904709 to your computer and use it in GitHub Desktop.
Save tyuki39/904709 to your computer and use it in GitHub Desktop.
時間帯重複チェック(応用編)
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