Summary
See Part 1
The twist is that one #
or .
should be the opposite on every pattern;
Fixing that error will make a new reflection point. The goal is to fix the error
and get the sum like Part 1
Smudges
Luckily this challenge doesn’t seem that bad as I can reuse the contents of
get_reflection_points()
and slightly tweak it.
First of all I need to keep track of amount of “smudges” I fix, it can’t be
more than 1 for every potential reflection. Secondly I need to break up the
pattern into a nested array format: string[][]
1
2
3
4
5
6
7
8
9
10
|
function get_reflection_points(contents: string[]): number[]{
const contents_len: number = contents.length;
const contents_arr: string[][] = contents.map((ele) => ele.split(''));
return contents
.map((ele, index) => {
let flipped_count: number = 0;
//...etc
})
.filter((ele) => ele != -1);
}
|
Helper
The next step is to write a function that will tell us if two rows are
“smudge-able”, ie they have exactly a 1 char difference.
1
2
3
4
5
6
7
8
9
10
11
12
|
function has_single_difference(a: string[], b: string[]): boolean{
let difference_count: number = 0;
for (let i = 0; i < a.length; i++){
if (a[i] !== b[i]){
difference_count++;
if (difference_count > 1){
return false;
}
}
};
return true;
}
|
Case 1
The smudge I go after first will be the ones that are on the reflection point.
By changing the logic of the first if in the map and by using our helper
function from the previous section should solve this case
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
|
contents
.map((ele, index) => {
if (index == contents.length - 1){
return -1;
}
let flipped_count: number = 0;
let reflection_match: boolean = false;
if (ele === contents[index+1]){
// exact match
reflection_match = true
}else{
if (has_single_difference(contents_arr[index], contents_arr[index+1])){
reflection_match = true;
flipped_count++; // record we 'changed' a value
}
}
if (reflection_match){
// ..etc
return index;
}
return -1;
})
.filter((ele) => ele != -1);
|
Case 2
The second smudge type would be one that isn’t directly touching the
reflection points. To do this I edit the reflection point validation to
also use our helper function. This will use the exact same logic as in case 1,
but it needs to check that if a char is flipped in case 1 it can’t be
flipped in case 2.
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
|
contents
.map((ele, index) => {
//.. etc
if (reflection_match){
// -1 to account for len-1 and -1 for reflect
const rows_below: number = contents_len - index - 2;
// grab the lowest one
const rows_to_check: number = index < rows_below ? index : rows_below;
for (let i = 0; i < rows_to_check; i++){
if (contents[index-(1+i)] !== contents[index+(2+i)]){
if (
flipped_count == 0 &&
has_single_difference(
contents_arr[index-(1+i)],
contents_arr[index+(2+i)]
)
){
flipped_count++; // record we 'changed' a value
}else{
return -1;
}
}
};
if (flipped_count){
return index;
}else{
return -1;
}
}
})
.filter((ele) => ele != -1);
|
Final
Putting all these pieces together would look like:
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
|
function has_single_difference(a: string[], b: string[]): boolean{
let difference_count: number = 0;
for (let i = 0; i < a.length; i++){
if (a[i] !== b[i]){
difference_count++;
if (difference_count > 1){
return false;
}
}
};
return true;
}
function get_reflection_points(contents: string[]): number[]{
const contents_len: number = contents.length;
const contents_arr: string[][] = contents.map((ele) => ele.split(''))
return contents
.map((ele, index) => {
if (index == contents.length - 1){
return -1;
}
let flipped_count: number = 0;
let reflection_match: boolean = false;
if (ele === contents[index+1]){
reflection_match = true
}else{
if (has_single_difference(contents_arr[index], contents_arr[index+1])){
reflection_match = true;
flipped_count++; // record we 'changed' a value
}
}
if (reflection_match){
// -1 to account for len-1 and -1 for reflect
const rows_below: number = contents_len - index - 2;
// grab the lowest one
const rows_to_check: number = index < rows_below ? index : rows_below;
for (let i = 0; i < rows_to_check; i++){
if (contents[index-(1+i)] !== contents[index+(2+i)]){
if (
flipped_count == 0 &&
has_single_difference(
contents_arr[index-(1+i)],
contents_arr[index+(2+i)]
)
){
flipped_count++; // record we 'changed' a value
}else{
return -1;
}
}
};
if (flipped_count){
return index;
}else{
return -1;
}
}
return -1;
})
.filter((ele) => ele != -1);
}
function get_vertical(horizontal: string[]): string[]{
let vertical: string[] = [];
let vertical_count: number = -1;
horizontal.forEach((row) => {
row.split('').forEach((cell, index) => {
if (vertical_count < index){
vertical.push(cell);
vertical_count++;
}else{
vertical[index] = cell + vertical[index];
}
});
});
return vertical;
}
const puzzle_list: string[][]; // filled from file
let horizontal: number = 0;
let vertical: number = 0;
puzzle_list.forEach((puzzle) => {
let horiz: number[] = get_reflection_points(puzzle);
if (horiz.length){ horizontal += horiz[0] }
let vert: number[] = get_reflection_points(get_vertical(puzzle));
if (vert.length){ vertical += vert[0] }
});
console.log(`Answer => ${vertical + (100 * horizontal)}`);
|