Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 77cb70e

Browse files
day 22
1 parent 250acdf commit 77cb70e

File tree

6 files changed

+188
-0
lines changed

6 files changed

+188
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package com.codefork.aoc2024.day22;
2+
3+
import com.codefork.aoc2024.util.Assert;
4+
5+
import java.util.ArrayList;
6+
import java.util.HashMap;
7+
import java.util.LinkedList;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.stream.Collectors;
11+
import java.util.stream.LongStream;
12+
import java.util.stream.Stream;
13+
14+
public class MonkeyExchangeMarket {
15+
16+
public static long mix(long a, long b) {
17+
return a ^ b;
18+
}
19+
20+
public static long prune(long a) {
21+
return a % 16777216;
22+
}
23+
24+
public static long getNextNumber(long n) {
25+
var r1 = prune(mix(n * 64, n));
26+
var r2 = prune(mix(r1 / 32, r1));
27+
var r3 = prune(mix(r2 * 2048, r2));
28+
return r3;
29+
}
30+
31+
public static long sum(Stream<String> data, int generations) {
32+
return data.mapToLong(line -> {
33+
var initial = Long.parseLong(line);
34+
return LongStream
35+
.range(0, generations)
36+
.reduce(initial, (acc, i) -> getNextNumber(acc));
37+
}).sum();
38+
}
39+
40+
public static int getOnesDigit(long n) {
41+
var nStr = String.valueOf(n);
42+
var onesDigitStr = nStr.substring(nStr.length() - 1);
43+
return Integer.parseInt(onesDigitStr);
44+
}
45+
46+
/*
47+
* generate pseudorandom numbers starting from initial, for max iterations,
48+
* and return a map of 4-change sequences to the price at that sequence.
49+
*/
50+
public static Map<List<Integer>, Integer> createChangesMap(long initial, int max) {
51+
var number = initial;
52+
var i = 0;
53+
var lastChanges = new LinkedList<Integer>();
54+
var changesToPrice = new HashMap<List<Integer>, Integer>();
55+
while(i < max) {
56+
var numberOnesDigit = getOnesDigit(number);
57+
var newNumber = getNextNumber(number);
58+
var newNumberOnesDigit = getOnesDigit(newNumber);
59+
var change = newNumberOnesDigit - numberOnesDigit;
60+
61+
lastChanges.add(change);
62+
if (lastChanges.size() == 5) {
63+
lastChanges.removeFirst();
64+
}
65+
if (lastChanges.size() == 4) {
66+
var changesKey = new ArrayList<>(lastChanges);
67+
// only store it if this is the first time we've seen it
68+
if (!changesToPrice.containsKey(changesKey)) {
69+
//System.out.println("adding key=" + changesKey + " value=" + newNumberOnesDigit);
70+
changesToPrice.put(changesKey, newNumberOnesDigit);
71+
} else {
72+
//System.out.println("already seen key=" + changesKey);
73+
}
74+
}
75+
// if (i == 0) {
76+
// System.out.println(number + ": " + numberOnesDigit);
77+
// }
78+
// System.out.println(newNumber + ": " + newNumberOnesDigit + " (" + change + ")");
79+
// update all our state variables
80+
number = newNumber;
81+
i++;
82+
}
83+
return changesToPrice;
84+
}
85+
86+
public record Sequence(List<Integer> seq, int totalBananas) {
87+
88+
}
89+
90+
public static Sequence findSequence(Stream<String> data, int generations) {
91+
record Flat(List<Integer> changes, Integer price) {
92+
93+
}
94+
95+
var results = data
96+
.map(line -> createChangesMap(Long.parseLong(line), generations))
97+
.flatMap(changesMap ->
98+
// transform key/value pairs in map to a list
99+
changesMap.entrySet().stream().map(entry ->
100+
new Flat(entry.getKey(), entry.getValue())
101+
)
102+
)
103+
.toList();
104+
105+
// group the Flats by changes
106+
var byChanges = results.stream()
107+
.collect(Collectors.groupingBy(Flat::changes));
108+
109+
// sum the Flats in the values part of map
110+
var changesToSums = byChanges.entrySet().stream()
111+
.collect(Collectors.toMap(
112+
Map.Entry::getKey,
113+
(entry) ->
114+
entry.getValue().stream().mapToInt(Flat::price).sum()
115+
)
116+
);
117+
118+
var highestTotal = changesToSums.values().stream().mapToInt(i -> i).max().orElseThrow();
119+
120+
var changesFound = changesToSums.keySet().stream()
121+
.filter(changes -> Integer.valueOf(highestTotal).equals(changesToSums.get(changes)))
122+
.toList();
123+
124+
Assert.assertEquals(1, changesFound.size());
125+
126+
return new Sequence(changesFound.getFirst(), highestTotal);
127+
}
128+
129+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.codefork.aoc2024.day22;
2+
3+
import com.codefork.aoc2024.Problem;
4+
import com.codefork.aoc2024.util.Assert;
5+
6+
import java.util.stream.Stream;
7+
8+
public class Part01 extends Problem {
9+
10+
public String solve(Stream<String> data) {
11+
var result = MonkeyExchangeMarket.sum(data, 2000);
12+
return String.valueOf(result);
13+
}
14+
15+
@Override
16+
public String solve() {
17+
Assert.assertEquals("37327623", solve(getSampleInput()));
18+
return solve(getInput());
19+
}
20+
21+
public static void main(String[] args) {
22+
new Part01().run();
23+
}
24+
25+
}
26+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.codefork.aoc2024.day22;
2+
3+
import com.codefork.aoc2024.Problem;
4+
import com.codefork.aoc2024.util.Assert;
5+
6+
import java.util.List;
7+
import java.util.stream.Collectors;
8+
import java.util.stream.Stream;
9+
10+
public class Part02 extends Problem {
11+
12+
public String seqToString(List<Integer> seq) {
13+
return seq.stream().map(String::valueOf).collect(Collectors.joining(","));
14+
}
15+
16+
public MonkeyExchangeMarket.Sequence solve(Stream<String> data) {
17+
return MonkeyExchangeMarket.findSequence(data, 2000);
18+
}
19+
20+
@Override
21+
public String solve() {
22+
var sampleSeq = solve(getFileAsStream("sample2"));
23+
Assert.assertEquals("-2,1,-1,3", seqToString(sampleSeq.seq()));
24+
Assert.assertEquals(23, sampleSeq.totalBananas());
25+
return String.valueOf(solve(getInput()).totalBananas());
26+
}
27+
28+
public static void main(String[] args) {
29+
new Part02().run();
30+
}
31+
32+
}
33+

‎src/main/resources/day22/input

12.3 KB
Binary file not shown.

‎src/main/resources/day22/sample

36 Bytes
Binary file not shown.

‎src/main/resources/day22/sample2

33 Bytes
Binary file not shown.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /