package org.seqcode.gseutils; /** * @author tdanford */ public class Interval<X> implements Comparable<Interval> { public int start, end; // inclusive coordinates. public X data; public Interval(int s, int e) { start = s; end = e; data = null; } public Interval(int s, int e, X d) { start = s; end = e; data = d; } public int hashCode() { int code = 17; code += start; code *= 37; code += end; code *= 37; if(data != null) { code += data.hashCode(); code *= 37; } return code; } public String toString() { return "[" + start + "," + end + "]"; } public Interval<X> expand(int w) { return new Interval<X>(start-w, end+w, data); } public int getWidth() { return end-start+1; } public int getMidpoint() { return (end+start)/2; } public Pair<Interval<X>,Interval<X>> split(int pt) { if(!contains(pt)) { throw new IllegalArgumentException(); } return new Pair<Interval<X>,Interval<X>>(new Interval<X>(start, pt, data), new Interval<X>(pt, end, data)); } public Interval<X> intersection(Interval intv) { if(!overlaps(intv)) { throw new IllegalArgumentException(); } return new Interval<X>(Math.max(start, intv.start), Math.min(end, intv.end), data); } public boolean equals(Object o) { if(!(o instanceof Interval)) { return false; } Interval i = (Interval)o; if(data != null || i.data != null) { if(data != null && i.data != null && !data.equals(i.data)) { return false; } return false; } return start == i.start && end == i.end; } public boolean contains(int pt) { return start <= pt && end >= pt; } public boolean contains(Interval i) { return start <= i.start && end >= i.end; } public boolean overlaps(Interval i) { return contains(i.start) || i.contains(start); } public int overlap(Interval i) { if(!overlaps(i)) { return 0; } else if(contains(i)) { return i.getWidth(); } else if(i.start < start) { return i.end-start+1; } else { return end-i.start+1; } } public int distance(Interval i) { if(overlaps(i)) { return 0; } else { if(i.end < start) { return start-i.end; } else { return i.start-end; } } } public int compareTo(Interval i) { if(start < i.start) { return -1; } if(start > i.start) { return 1; } if(end < i.end) { return -1; } if(end > i.end) { return 1; } return 0; } }