Last active
December 31, 2015 22:08
-
-
Save dha-lo-jd/8051106 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
import java.util.Iterator; | |
import lombok.Value; | |
public class Range<T> implements Iterable<T> { | |
public static class Index { | |
private int value = -1; | |
public int value() { | |
return value; | |
} | |
private int next() { | |
return value++; | |
} | |
} | |
public interface Rangeable<T> extends Comparable<T> { | |
public Rangeable<T> next(); | |
public T getRangeableValue(); | |
public int sub(Rangeable<T> value); | |
} | |
public static class RangeIndexIterator<T> extends RangeIterator<T> { | |
private final Index idx; | |
protected RangeIndexIterator(Rangeable<T> min, Rangeable<T> max, Index idx) { | |
super(min, max); | |
this.idx = idx; | |
} | |
@Override | |
public T next() { | |
idx.next(); | |
return super.next(); | |
} | |
} | |
public static class RangeIterator<T> implements Iterator<T> { | |
private final Rangeable<T> min; | |
private final Rangeable<T> max; | |
private Rangeable<T> v; | |
protected RangeIterator(Rangeable<T> min, Rangeable<T> max) { | |
this.min = min; | |
this.max = max; | |
v = min; | |
} | |
@Override | |
public boolean hasNext() { | |
return v.compareTo(max.getRangeableValue()) <= 0; | |
} | |
@Override | |
public T next() { | |
T r = v.getRangeableValue(); | |
v = v.next(); | |
return r; | |
} | |
@Override | |
public void remove() { | |
throw new UnsupportedOperationException(); | |
} | |
} | |
private interface Factory { | |
<T> RangeIterator<T> create(Rangeable<T> min, Rangeable<T> max, Index idx); | |
} | |
@Value | |
private static class RangeableInteger implements Rangeable<Integer> { | |
private final Integer rangeableValue; | |
@Override | |
public int compareTo(Integer o) { | |
return rangeableValue.compareTo(o); | |
} | |
@Override | |
public Rangeable<Integer> next() { | |
return new RangeableInteger(rangeableValue + 1); | |
} | |
@Override | |
public int sub(Rangeable<Integer> value) { | |
return this.rangeableValue - value.getRangeableValue(); | |
} | |
} | |
private static final Factory FACTORY_IDX = new Factory() { | |
@Override | |
public <T> RangeIterator create(Rangeable<T> min, Rangeable<T> max, Index idx) { | |
return new RangeIndexIterator(min, max, idx); | |
} | |
}; | |
private static final Factory FACTORY_NO_IDX = new Factory() { | |
@Override | |
public <T> RangeIterator create(Rangeable<T> min, Rangeable<T> max, Index idx) { | |
return new RangeIterator(min, max); | |
} | |
}; | |
public static void main(String[] args) throws Exception { | |
Range<Integer> range; | |
for (int i : Range.of(8)) { | |
{ | |
range = Range.of(i); | |
System.out.print(String.format("size: %d ", range.size())); | |
int loop = 1; | |
for (int idx : range) { | |
System.out.print(String.format("[idx: %d, loop: %d]", idx, loop)); | |
loop++; | |
} | |
System.out.println(); | |
System.out.println(); | |
} | |
{ | |
Range.Index index = new Range.Index(); | |
range = Range.of(i, index); | |
System.out.print(String.format("size: %d ", range.size())); | |
int loop = 1; | |
for (int v : range) { | |
System.out.print(String.format("[idx: %d, loop: %d, index: %d]", v, loop, index.value())); | |
loop++; | |
} | |
System.out.println(); | |
System.out.println(); | |
} | |
} | |
for (int i : Range.of(8)) { | |
for (int j : Range.of(8)) { | |
System.out.print(String.format("from: %d -> to: %d ", i, j)); | |
Range.Index index = new Range.Index(); | |
range = Range.of(i, j, index); | |
System.out.print(String.format("size: %d ", range.size())); | |
int loop = 1; | |
for (int v : range) { | |
System.out.print(String.format("[idx: %d, loop: %d, index: %d]", v, loop, index.value())); | |
loop++; | |
} | |
System.out.println(); | |
System.out.println(); | |
} | |
} | |
} | |
public static Range<Integer> of(int size) { | |
return of(size, null); | |
} | |
public static Range<Integer> of(int size, Index idx) { | |
return of(0, size - 1, idx); | |
} | |
public static Range<Integer> of(int start, int end) { | |
return new Range(new RangeableInteger(start), new RangeableInteger(end), null); | |
} | |
public static Range<Integer> of(int start, int end, Index idx) { | |
return new Range(new RangeableInteger(start), new RangeableInteger(end), idx); | |
} | |
public static <T> Range<T> of(Rangeable<T> start, Rangeable<T> end) { | |
return new Range(start, end, null); | |
} | |
public static <T> Range<T> of(Rangeable<T> start, Rangeable<T> end, Index idx) { | |
return new Range(start, end, idx); | |
} | |
private final Rangeable<T> min; | |
private final Rangeable<T> max; | |
private final Index idx; | |
private final Factory factory; | |
private Range(Rangeable<T> min, Rangeable<T> max, Index idx) { | |
this.min = min; | |
this.max = max; | |
this.idx = idx; | |
if (idx == null) { | |
factory = FACTORY_NO_IDX; | |
} else { | |
factory = FACTORY_IDX; | |
} | |
} | |
public boolean isIn(T index) { | |
return min.compareTo(index) <= 0 && 0 <= max.compareTo(index); | |
} | |
@Override | |
public Iterator<T> iterator() { | |
return factory.create(min, max, idx); | |
} | |
public int size() { | |
int s; | |
return (s = max.sub(min) + 1) < 0 ? 0 : s; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment