Skip to content

Commit 8471b03

Browse files
committed
Update Core Math Lib
1 parent ebbfda7 commit 8471b03

20 files changed

+1496
-315
lines changed

build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ tasks.withType<JavaCompile>().configureEach {
4141
options.compilerArgs.add("--enable-preview")
4242
}
4343

44+
tasks.withType<JavaCompile> {
45+
options.encoding = "UTF-8"
46+
}
47+
4448
jmh {
4549
warmupIterations = 2
4650
iterations = 2
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.togetherjava.aoc.core;
2+
3+
import java.util.List;
4+
import java.util.regex.MatchResult;
5+
import java.util.regex.Pattern;
6+
7+
public class Regex {
8+
9+
public static final Pattern WHITESPACES = Pattern.compile("\\s+");
10+
public static final Pattern INTEGERS = Pattern.compile("-?\\d+");
11+
public static final Pattern WORDS = Pattern.compile("\\w+");
12+
public static final Pattern EOL = Pattern.compile("\\R");
13+
public static final Pattern BLANK_LINES = Pattern.compile("\\R{2,}");
14+
15+
/**
16+
* Find all the matches in the given input string and collect to an immutable list.
17+
* @param input input to search
18+
* @param regex pattern to match on
19+
* @return immutable list of matches
20+
*/
21+
public static List<MatchResult> allMatches(Pattern regex, String input) {
22+
return regex.matcher(input).results().toList();
23+
}
24+
25+
/**
26+
* Find all the matches in the given input string and collect to an immutable list.
27+
* @param input input to search
28+
* @param regex string pattern to match on
29+
* @return immutable list of matches
30+
*/
31+
public static List<MatchResult> allMatches(String regex, String input) {
32+
return allMatches(Pattern.compile(regex), input);
33+
}
34+
35+
/**
36+
* Extract a list of all the signed integers in the input string.
37+
* @param s input text
38+
* @return immutable List of 64-bit integer matches
39+
*/
40+
public static List<Long> parseLongs(String s) {
41+
return INTEGERS.matcher(s)
42+
.results()
43+
.map(MatchResult::group)
44+
.map(Long::parseLong)
45+
.toList();
46+
}
47+
48+
/**
49+
* Extract a list of all the signed integers in the input string.
50+
* @param s input text
51+
* @return immutable List of 32-bit integer matches
52+
*/
53+
public static List<Integer> parseInts(String s) {
54+
return INTEGERS.matcher(s)
55+
.results()
56+
.map(MatchResult::group)
57+
.map(Integer::parseInt)
58+
.toList();
59+
}
60+
61+
/**
62+
* Extract a list of all the contiguous words (\w+)
63+
* @param s input text
64+
* @return immutable List of string matches
65+
*/
66+
public static List<String> parseStrings(String s) {
67+
return WORDS.matcher(s)
68+
.results()
69+
.map(MatchResult::group)
70+
.toList();
71+
}
72+
73+
/**
74+
* Split the given input on the given regex delimiter.
75+
* @param regex Pattern to split on
76+
* @param input input to split
77+
* @return immutable List of string results after splitting
78+
*/
79+
public static List<String> split(String regex, String input) {
80+
return List.of(input.split(regex));
81+
}
82+
83+
/**
84+
* Split the given input on the given regex delimiter.
85+
* @param regex Pattern to split on
86+
* @param input input to split
87+
* @return immutable List of string results after splitting
88+
*/
89+
public static List<String> split(Pattern regex, String input) {
90+
return List.of(regex.split(input));
91+
}
92+
93+
/**
94+
* Split the given input on whitespaces. Multiple whitespaces are treated as one.
95+
* @param input input string
96+
* @return immutable List of strings
97+
*/
98+
public static List<String> split(String input) {
99+
return split(WHITESPACES, input);
100+
}
101+
102+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.togetherjava.aoc.core.math;
2+
3+
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
public class Combinatorics {
8+
9+
/**
10+
* Arrange n from k with repetition allowed.
11+
* <br>
12+
* Permutations with repetitions allowed.
13+
*
14+
* @param n permutation resulting size (arrange n)
15+
* @param kValues from k values
16+
* @return all permutations, with repetitions allowed, of length n
17+
* @param <T> type of elements to permute
18+
*/
19+
public static <T> List<List<T>> arrangeWithRepetition(int n, List<T> kValues) {
20+
List<List<T>> permutations = new ArrayList<>();
21+
arrangeWithRepetitionRecursive(kValues, new ArrayList<>(), n, permutations);
22+
return permutations;
23+
}
24+
25+
private static <T> void arrangeWithRepetitionRecursive(List<T> values, List<T> current, int remaining, List<List<T>> permutations) {
26+
if (remaining == 0) {
27+
permutations.add(new ArrayList<>(current));
28+
return;
29+
}
30+
31+
for (T value : values) {
32+
current.add(value);
33+
arrangeWithRepetitionRecursive(values, current, remaining - 1, permutations);
34+
current.remove(current.size() - 1);
35+
}
36+
}
37+
38+
public static <T> List<List<T>> arrange(List<T> values, int length) {
39+
List<List<T>> permutations = new ArrayList<>();
40+
arrangeHelper(values, new ArrayList<>(), length, permutations);
41+
return permutations;
42+
}
43+
44+
private static <T> void arrangeHelper(List<T> values, List<T> current, int remaining, List<List<T>> permutations) {
45+
if (remaining == 0) {
46+
permutations.add(new ArrayList<>(current));
47+
return;
48+
}
49+
50+
for (T value : values) {
51+
if (current.contains(value)) {
52+
continue;
53+
}
54+
current.add(value);
55+
arrangeHelper(values, current, remaining - 1, permutations);
56+
current.remove(current.size() - 1);
57+
}
58+
}
59+
60+
public static List<String> getRotations(String s) {
61+
List<String> rotations = new ArrayList<>();
62+
int length = s.length();
63+
for (int i = 0; i < length; i++) {
64+
String rotated = s.substring(i) + s.substring(0, i);
65+
rotations.add(rotated);
66+
}
67+
return rotations;
68+
}
69+
70+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.togetherjava.aoc.core.math;
2+
3+
4+
import java.util.Comparator;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.function.Function;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.Stream;
10+
11+
public enum Direction {
12+
NORTH(0, 1, 0),
13+
NORTH_EAST(1, 1, 45),
14+
EAST(1, 0, 90),
15+
SOUTH_EAST(1, -1, 135),
16+
SOUTH(0, -1, 180),
17+
SOUTH_WEST(-1, -1, 225),
18+
WEST(-1, 0, 270),
19+
NORTH_WEST(-1, 1, 315);
20+
21+
private final int x;
22+
private final int y;
23+
private final int angleInDegrees;
24+
25+
Direction(int x, int y, int angleInDegrees) {
26+
this.x = x;
27+
this.y = y;
28+
this.angleInDegrees = angleInDegrees;
29+
}
30+
31+
private static final List<Direction> DIRECTIONS = Stream.of(values())
32+
.sorted(Comparator.comparingInt(Direction::getAngleInDegrees)).toList();
33+
private static final List<Direction> CARDINAL = List.of(NORTH, EAST, SOUTH, WEST);
34+
private static final List<Direction> ORDINAL = List.of(NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST);
35+
private static final Map<Integer, Direction> ANGLE_MAP = DIRECTIONS.stream()
36+
.collect(Collectors.toMap(Direction::getAngleInDegrees, Function.identity()));
37+
38+
public static Direction getByAngle(int angle) {
39+
return ANGLE_MAP.get(angle % 360);
40+
}
41+
42+
public static Direction getByPosition(int x, int y) {
43+
for (Direction direction : DIRECTIONS) {
44+
if (direction.x == x && direction.y == y) {
45+
return direction;
46+
}
47+
}
48+
return null;
49+
}
50+
51+
public static List<Direction> getAll() {
52+
return DIRECTIONS;
53+
}
54+
55+
public static List<Direction> getCardinal() {
56+
return CARDINAL;
57+
}
58+
59+
public static List<Direction> getOrdinal() {
60+
return ORDINAL;
61+
}
62+
63+
public int getX() {
64+
return x;
65+
}
66+
67+
public int getY() {
68+
return y;
69+
}
70+
71+
public int getAngleInDegrees() {
72+
return angleInDegrees;
73+
}
74+
75+
public Direction rotate(int angleInDegrees) {
76+
return Direction.getByAngle(this.angleInDegrees + angleInDegrees);
77+
}
78+
79+
public Direction rotateRight() {
80+
return rotate(90);
81+
}
82+
83+
public Direction rotateLeft() {
84+
return rotate(-90);
85+
}
86+
87+
public Direction opposite() {
88+
return rotate(180);
89+
}
90+
91+
92+
93+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.togetherjava.aoc.core.math;
2+
3+
public class Distance {
4+
public static double euclidean(Point a, Point b) {
5+
double dx = a.x() - b.x();
6+
double dy = a.y() - b.y();
7+
return Math.sqrt(dx * dx + dy * dy);
8+
}
9+
10+
public static double taxicab(Point a, Point b) {
11+
double dx = Math.abs(a.x() - b.x());
12+
double dy = Math.abs(a.y() - b.y());
13+
return dx + dy;
14+
}
15+
16+
public static double chebyshev(Point a, Point b) {
17+
double dx = Math.abs(a.x() - b.x());
18+
double dy = Math.abs(a.y() - b.y());
19+
return Math.max(dx, dy);
20+
}
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.togetherjava.aoc.core.math;
2+
3+
public record Point(double x, double y) {
4+
5+
public static final Point ORIGIN = new Point(0, 0);
6+
7+
public Point move(double x, double y) {
8+
return new Point(this.x + x, this.y + y);
9+
}
10+
11+
public static Point of(double x, double y) {
12+
return new Point(x, y);
13+
}
14+
15+
}

0 commit comments

Comments
 (0)