-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay16.java
139 lines (111 loc) · 4.36 KB
/
Day16.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package net.eugenpaul.adventofcode.y2019.day16;
import java.util.logging.Level;
import lombok.Getter;
import lombok.Setter;
import net.eugenpaul.adventofcode.helper.SolutionTemplate;
import net.eugenpaul.adventofcode.helper.StringConverter;
public class Day16 extends SolutionTemplate {
@Getter
private String output;
@Getter
private String realOutput;
@Setter
private boolean doStep2 = true;
private int[] basePattern = { 0, 1, 0, -1 };
public static void main(String[] args) {
Day16 puzzle = new Day16();
puzzle.doPuzzleFromFile("y2019/day16/puzzle1.txt");
}
@Override
public boolean doEvent(String eventData) {
output = doPuzzle1(eventData);
if (doStep2) {
realOutput = doPuzzle2(eventData);
}
logger.log(Level.INFO, () -> "output : " + getOutput());
logger.log(Level.INFO, () -> "realOutput : " + getRealOutput());
return true;
}
private String doPuzzle1(String eventData) {
long[] digits = StringConverter.digitsToLongArray(eventData);
for (int i = 0; i < 100; i++) {
long[] outputData = new long[digits.length];
for (int j = 0; j < digits.length; j++) {
int[] mult = getPattern(j + 1, digits.length);
outputData[j] = getDigit(digits, mult);
}
digits = outputData;
}
StringBuilder outputString = new StringBuilder();
for (int i = 0; i < 8; i++) {
outputString.append(digits[i]);
}
return outputString.toString();
}
/**
* The digits from n/2, where n is equal to the total length, are always the sum of all subsequent digits. It is so because of the repetition of the digit 1
* in basic pattern. Since the offset is after n/2, you do not have to calculate the whole output but only the last digits from the offset.
*
* <code>
* Input signal: 12345678
* 1*1 + 2*0 + 3*-1 + 4*0 + 5*1 + 6*0 + 7*-1 + 8*0 = 4
* 1*0 + 2*1 + 3*1 + 4*0 + 5*0 + 6*-1 + 7*-1 + 8*0 = 8
* 1*0 + 2*0 + 3*1 + 4*1 + 5*1 + 6*0 + 7*0 + 8*0 = 2
* 1*0 + 2*0 + 3*0 + 4*1 + 5*1 + 6*1 + 7*1 + 8*0 = 2
* 1*0 + 2*0 + 3*0 + 4*0 + 5*1 + 6*1 + 7*1 + 8*1 = 6 <- sum of {n-3, n-2, n-1, n}
* 1*0 + 2*0 + 3*0 + 4*0 + 5*0 + 6*1 + 7*1 + 8*1 = 1 <- sum of {n-2, n-1, n}
* 1*0 + 2*0 + 3*0 + 4*0 + 5*0 + 6*0 + 7*1 + 8*1 = 5 <- sum of {n-1, n}
* 1*0 + 2*0 + 3*0 + 4*0 + 5*0 + 6*0 + 7*0 + 8*1 = 8 <- sum of {n}
* </code>
*
* @param eventData
* @return
*/
private String doPuzzle2(String eventData) {
long[] digitspart = StringConverter.digitsToLongArray(eventData);
long[] digits = new long[digitspart.length * 10_000];
for (int i = 0; i < 10_000; i++) {
System.arraycopy(digitspart, 0, digits, digitspart.length * i, digitspart.length);
}
int offset = Integer.parseInt(eventData.substring(0, 7));
for (int i = 0; i < 100; i++) {
long[] outputData = new long[digits.length];
long value = 0L;
for (int pos = digits.length - 1; pos >= offset; pos--) {
value += digits[pos];
value = (Math.abs(value) % 10L);
outputData[pos] = value;
}
digits = outputData;
}
StringBuilder outputString = new StringBuilder();
for (int i = offset; i < offset + 8; i++) {
outputString.append(digits[i]);
}
return outputString.toString();
}
private int getDigit(long[] digits, int[] mult) {
long result = 0;
for (int i = 0; i < digits.length; i++) {
result += digits[i] * mult[i];
}
return (int) (Math.abs(result) % 10L);
}
private int[] getPattern(int outputPosition, int len) {
int[] responsePattern = new int[len];
int basePatternPos = 0;
int rep = 1;
for (int i = 0; i < len; i++) {
if (rep == outputPosition) {
rep = 0;
basePatternPos++;
if (basePatternPos == basePattern.length) {
basePatternPos = 0;
}
}
responsePattern[i] = basePattern[basePatternPos];
rep++;
}
return responsePattern;
}
}