Skip to content

Instantly share code, notes, and snippets.

@dha-lo-jd
Last active December 31, 2015 22:08
Show Gist options
  • Save dha-lo-jd/8051106 to your computer and use it in GitHub Desktop.
Save dha-lo-jd/8051106 to your computer and use it in GitHub Desktop.
らんげ
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