Skip to content

Commit

Permalink
java - refactor Range
Browse files Browse the repository at this point in the history
  • Loading branch information
pareronia committed Dec 9, 2023
1 parent 6b9777e commit 04620ff
Show file tree
Hide file tree
Showing 15 changed files with 395 additions and 156 deletions.
24 changes: 12 additions & 12 deletions src/main/java/AoC2016_20.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
import java.util.ArrayList;
import java.util.List;

import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aocd.Aocd;
import com.github.pareronia.aocd.Puzzle;

public class AoC2016_20 extends AoCBase {

private static final long TOTAL_IPS = 4294967296L;

private final List<Range<Long>> ranges;
private final List<RangeInclusive<Long>> ranges;

private AoC2016_20(final List<String> input, final boolean debug) {
super(debug);
this.ranges = input.stream()
.map(s -> s.split("-"))
.map(sp -> Range.between(Long.valueOf(sp[0]), Long.valueOf(sp[1])))
.map(sp -> RangeInclusive.between(Long.valueOf(sp[0]), Long.valueOf(sp[1])))
.collect(toList());
}

Expand All @@ -30,25 +30,25 @@ public static AoC2016_20 createDebug(final List<String> input) {
return new AoC2016_20(input, true);
}

private List<Range<Long>> combineRanges() {
final List<Range<Long>> combines = new ArrayList<>();
this.ranges.sort(comparing(Range::getMinimum)); // why doesn't this work without sorting?
private List<RangeInclusive<Long>> combineRanges() {
final List<RangeInclusive<Long>> combines = new ArrayList<>();
this.ranges.sort(comparing(RangeInclusive::getMinimum)); // why doesn't this work without sorting?
combines.add(this.ranges.get(0));
for (int i = 1; i < ranges.size(); i++) {
final Range<Long> r = ranges.get(i);
final RangeInclusive<Long> r = ranges.get(i);
boolean combined = false;
for (int j = 0; j < combines.size(); j++) {
final Range<Long> combine = combines.get(j);
final RangeInclusive<Long> combine = combines.get(j);
if (combine.isOverlappedBy(r)) {
final long min = Math.min(combine.getMinimum(), r.getMinimum());
final long max = Math.max(combine.getMaximum(), r.getMaximum());
combines.set(j, Range.between(min, max));
combines.set(j, RangeInclusive.between(min, max));
combined = true;
} else if (r.getMaximum() + 1 == combine.getMinimum()) {
combines.set(j, Range.between(r.getMinimum(), combine.getMaximum()));
combines.set(j, RangeInclusive.between(r.getMinimum(), combine.getMaximum()));
combined = true;
} else if (combine.getMaximum() + 1 == r.getMinimum()) {
combines.set(j, Range.between(combine.getMinimum(), r.getMaximum()));
combines.set(j, RangeInclusive.between(combine.getMinimum(), r.getMaximum()));
combined = true;
}
}
Expand All @@ -62,7 +62,7 @@ private List<Range<Long>> combineRanges() {
@Override
public Long solvePart1() {
return combineRanges().stream()
.sorted(comparing(Range::getMinimum))
.sorted(comparing(RangeInclusive::getMinimum))
.findFirst()
.map(c -> c.getMaximum() + 1)
.orElseThrow();
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/AoC2020_04.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.function.Function;
import java.util.function.Predicate;

import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aoc.StringUtils;
import com.github.pareronia.aoc.Utils;
import com.github.pareronia.aocd.Puzzle;
Expand Down Expand Up @@ -150,23 +150,23 @@ public boolean isValid1() {
}

private boolean byrValid() {
return Range.between(1920, 2002).contains(Integer.valueOf(this.byr));
return RangeInclusive.between(1920, 2002).contains(Integer.valueOf(this.byr));
}

private boolean iyrValid() {
return Range.between(2010, 2020).contains(Integer.valueOf(this.iyr));
return RangeInclusive.between(2010, 2020).contains(Integer.valueOf(this.iyr));
}

private boolean eyrValid() {
return Range.between(2020, 2030).contains(Integer.valueOf(this.eyr));
return RangeInclusive.between(2020, 2030).contains(Integer.valueOf(this.eyr));
}

private boolean hgtValid() {
final Integer hgt = Integer.valueOf(this.hgt.substring(0, this.hgt.length() - 2));
if (this.hgt.endsWith("in")) {
return Range.between(59, 76).contains(hgt);
return RangeInclusive.between(59, 76).contains(hgt);
} else if (this.hgt.endsWith("cm")) {
return Range.between(150, 193).contains(hgt);
return RangeInclusive.between(150, 193).contains(hgt);
} else {
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/AoC2020_16.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;

import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aocd.Puzzle;

import lombok.Builder;
Expand Down Expand Up @@ -46,7 +46,7 @@ private final Rule parseRule(final String s) {
final String[] splits3 = split.split("-");
final int start = Integer.parseInt(splits3[0]);
final int end = Integer.parseInt(splits3[1]);
builder.validRange(Range.between(start, end));
builder.validRange(RangeInclusive.between(start, end));
}
return builder.build();
}
Expand Down Expand Up @@ -127,7 +127,7 @@ public static void main(final String[] args) throws Exception {
private static final class Rule {
private final String field;
@Singular
private final Set<Range<Integer>> validRanges;
private final Set<RangeInclusive<Integer>> validRanges;

public boolean validate(final int value) {
return this.validRanges.stream().anyMatch(r -> r.contains(value));
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/AoC2021_22.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.Optional;
import java.util.regex.Pattern;

import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aoc.geometry3d.Cuboid;
import com.github.pareronia.aocd.Aocd;
import com.github.pareronia.aocd.Puzzle;
Expand Down Expand Up @@ -36,9 +36,9 @@ private AoC2021_22(final List<String> input, final boolean debug) {
final Integer z1 = Integer.valueOf(m.group(6));
final Integer z2 = Integer.valueOf(m.group(7));
assert x1 <= x2 && y1 <= y2 && z1 <= z2;
final Range<Integer> x = Range.between(x1, x2);
final Range<Integer> y = Range.between(y1, y2);
final Range<Integer> z = Range.between(z1, z2);
final RangeInclusive<Integer> x = RangeInclusive.between(x1, x2);
final RangeInclusive<Integer> y = RangeInclusive.between(y1, y2);
final RangeInclusive<Integer> z = RangeInclusive.between(z1, z2);
final boolean on = "on".equals(m.group(1));
return new RebootStep(x, y, z, on);
})
Expand Down Expand Up @@ -204,9 +204,9 @@ public static void main(final String[] args) throws Exception {
@RequiredArgsConstructor
@ToString
private static final class RebootStep {
private final Range<Integer> x;
private final Range<Integer> y;
private final Range<Integer> z;
private final RangeInclusive<Integer> x;
private final RangeInclusive<Integer> y;
private final RangeInclusive<Integer> z;
private final boolean on;
}
}
8 changes: 4 additions & 4 deletions src/main/java/AoC2022_04.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.regex.MatchResult;
import java.util.regex.Pattern;

import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aocd.Aocd;
import com.github.pareronia.aocd.Puzzle;

Expand Down Expand Up @@ -33,12 +33,12 @@ private final int[] numbers(final String string) {
.toArray();
}

private int solve(final BiPredicate<Range<Integer>, Range<Integer>> predicate) {
private int solve(final BiPredicate<RangeInclusive<Integer>, RangeInclusive<Integer>> predicate) {
return (int) this.input.stream()
.map(this::numbers)
.filter(nums -> predicate.test(
Range.between(nums[0], nums[1]),
Range.between(nums[2], nums[3])))
RangeInclusive.between(nums[0], nums[1]),
RangeInclusive.between(nums[2], nums[3])))
.count();
}

Expand Down
26 changes: 13 additions & 13 deletions src/main/java/AoC2022_15.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.Map;
import java.util.Set;

import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aoc.Utils;
import com.github.pareronia.aoc.geometry.Position;
import com.github.pareronia.aocd.Aocd;
Expand Down Expand Up @@ -44,8 +44,8 @@ public static final AoC2022_15 createDebug(final List<String> input) {
return new AoC2022_15(input, true);
}

private Deque<Range<Integer>> getRanges(final int y) {
final Set<Range<Integer>> ranges = new HashSet<>();
private Deque<RangeInclusive<Integer>> getRanges(final int y) {
final Set<RangeInclusive<Integer>> ranges = new HashSet<>();
for (final Sensor sensor : this.sensors) {
if (Math.abs(sensor.y - y) > sensor.distanceToBeacon) {
continue;
Expand All @@ -65,9 +65,9 @@ private int solve1(final int y) {

private long solve2(final int max) {
for (int y = max; y >= 0; y--) {
final Deque<Range<Integer>> ranges = getRanges(y);
final Deque<RangeInclusive<Integer>> ranges = getRanges(y);
for (int x = 0; x <= max; x++) {
for (final Range<Integer> merged : ranges) {
for (final RangeInclusive<Integer> merged : ranges) {
if (merged.isAfter(x)) {
log(Position.of(x, y));
return x * 4_000_000L + y;
Expand Down Expand Up @@ -131,36 +131,36 @@ public Sensor(final int x, final int y, final int beaconX, final int beaconY) {
this.distanceToBeacon = Math.abs(beaconX - x) + Math.abs(beaconY - y);
}

public Range<Integer> xRangeAt(final int y) {
public RangeInclusive<Integer> xRangeAt(final int y) {
final int dy = Math.abs(this.y - y);
assert dy <= distanceToBeacon;
return Range.between(
return RangeInclusive.between(
x - distanceToBeacon + dy,
x + distanceToBeacon - dy);
}
}

static final class RangeMerger {

public static Deque<Range<Integer>> mergeRanges(final Set<Range<Integer>> ranges) {
final Deque<Range<Integer>> m = new ArrayDeque<>();
final List<Range<Integer>> sorted = new ArrayList<>(ranges);
public static Deque<RangeInclusive<Integer>> mergeRanges(final Set<RangeInclusive<Integer>> ranges) {
final Deque<RangeInclusive<Integer>> m = new ArrayDeque<>();
final List<RangeInclusive<Integer>> sorted = new ArrayList<>(ranges);
Collections.sort(sorted, (r1, r2) -> {
final int first = Integer.compare(r1.getMinimum(), r2.getMinimum());
if (first == 0) {
return Integer.compare(r1.getMaximum(), r2.getMaximum());
}
return first;
});
for (final Range<Integer> range : sorted) {
for (final RangeInclusive<Integer> range : sorted) {
if (m.isEmpty()) {
m.addLast(range);
continue;
}
final Range<Integer> last = m.peekLast();
final RangeInclusive<Integer> last = m.peekLast();
if (range.isOverlappedBy(last)) {
m.removeLast();
m.add(Range.between(
m.add(RangeInclusive.between(
last.getMinimum(),
Math.max(last.getMaximum(), range.getMaximum())));
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/AoC2023_02.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import static com.github.pareronia.aoc.Utils.enumerate;
import static com.github.pareronia.aoc.IterTools.enumerate;

import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -43,8 +43,8 @@ protected List<Game> parseInput(final List<String> inputs) {
};
return enumerate(inputs.stream())
.map(e -> new Game(
e.getIndex() + 1,
Arrays.stream(e.getValue().split(":")[1].split(";"))
e.index() + 1,
Arrays.stream(e.value().split(":")[1].split(";"))
.map(parseDraw).toList()))
.toList();
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/AoC2023_03.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import com.github.pareronia.aoc.CharGrid;
import com.github.pareronia.aoc.Grid.Cell;
import com.github.pareronia.aoc.Range;
import com.github.pareronia.aoc.RangeInclusive;
import com.github.pareronia.aoc.solution.Sample;
import com.github.pareronia.aoc.solution.Samples;
import com.github.pareronia.aoc.solution.SolutionBase;
Expand All @@ -35,14 +35,14 @@ protected List<EnginePart> parseInput(final List<String> inputs) {
return enumerate(grid.getRowsAsStrings())
.flatMap(e -> regex.matcher(e.value()).results()
.map(m -> findEnginePart(grid, e.index(),
Range.between(m.start(), m.end()))))
RangeInclusive.between(m.start(), m.end()))))
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
}

private Optional<EnginePart> findEnginePart(
final CharGrid grid, final int row, final Range<Integer> colspan
final CharGrid grid, final int row, final RangeInclusive<Integer> colspan
) {
return IntStream.range(colspan.getMinimum(), colspan.getMaximum())
.boxed()
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/com/github/pareronia/aoc/LongRange.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.github.pareronia.aoc;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;

public class LongRange extends Range<Long> {

public LongRange(final long element1, final long element2) {
super(element1, element2);
}

public static LongRange between(final long fromInclusive, final long toExclusive) {
return new LongRange(fromInclusive, toExclusive);
}

public Iterator<Long> iterator() {
return new Iterator<>() {
private long n = LongRange.this.minimum;

@Override
public Long next() {
final long next = n;
n += 1;
return next;
}

@Override
public boolean hasNext() {
return n < LongRange.this.maximum;
}
};
}

public JoinResult leftJoin(final LongRange other) {
final long o0 = Math.max(this.minimum, other.minimum);
final long o1 = Math.min(this.maximum, other.maximum);
if (o0 < o1) {
final Set<LongRange> others = new HashSet<>();
if (this.minimum < o0) {
others.add(LongRange.between(this.minimum, o0));
}
if (o1 < this.maximum) {
others.add(LongRange.between(o1, this.maximum));
}
return new JoinResult(
Optional.of(LongRange.between(o0, o1)), others);
} else {
return new JoinResult(
Optional.empty(),
Set.of(LongRange.between(this.minimum.longValue(), this.maximum.longValue())));
}
}

public LongRange translate(final long amount) {
return LongRange.between(this.minimum + amount, this.maximum + amount);
}

public record JoinResult(Optional<LongRange> intersection, Set<LongRange> others) {}
}
Loading

0 comments on commit 04620ff

Please sign in to comment.