#import "Basic";
#import "Math";
#import "File";
#import "String";
solve_day13 :: (test: bool) {
contents := read_entire_file(ifx test then "inputs/day13_test2.txt" else "inputs/day13.txt");
section_split := split(contents, "\n\n");
sections: [..]string;
part1 := 0;
part2 := 0;
for section_split {
builder: String_Builder;
lines := split(it, "\n");
section := Section.{
width = lines[0].count,
height = lines.count,
lines = NewArray(50 * 50, u8),
};
rows := NewArray(50, u32);
defer array_free(rows);
for line,line_index: lines {
for 0..line.count - 1 {
if line[it] == #char "#" {
section.lines[line_index * 50 + it] = #char "1";
} else if line[it] == #char "." {
section.lines[line_index * 50 + it] = #char "0";
}
}
rows[line_index] = string_to_int(cast(string)array_view(section.lines, line_index * 50, line.count), 2, u32);
}
p1, p2 := find_symmetries(array_view(rows, 0, section.height));
part1 += p1 * 100;
part2 += p2 * 100;
transpose(*section);
for line_index: 0..section.height {
rows[line_index] = string_to_int(cast(string)array_view(section.lines, line_index * 50, section.width), 2, u32);
}
p1, p2 = find_symmetries(array_view(rows, 0, section.height));
part1 += p1;
part2 += p2;
}
print("Part 1: %\n", part1);
print("Part 2: %\n", part2);
}
transpose :: (section: *Section) {
max_val := max(section.width, section.height);
for row: 0..max_val - 1 {
for column: row..max_val - 1 {
section.lines[row * 50 + column], section.lines[column * 50 + row] = section.lines[column * 50 + row], section.lines[row * 50 + column];
}
}
section.width, section.height = section.height, section.width;
}
is_pow_2 :: (val: u32) -> bool {
return (val & (val - 1)) == 0 && val != 0;
}
find_symmetries :: (lines: []u32) -> (part1: u32, part2: u32) {
errors: u32 = 0;
error_val : u32 = 0;
part1: u32 = 0;
part2: u32 = 0;
for row: 0..lines.count - 2 {
errors = 0;
j: u32 = 0;
while errors < 2 && row >= j && j + row + 1 < lines.count {
defer j += 1;
if lines[row - j] != lines[row + j + 1] {
errors += 1;
error_val = lines[row - j] ^ lines[row + j + 1];
}
}
if errors == 1 && is_pow_2(error_val) {
part2 += xx (row + 1);
}
if errors == 0 {
part1 += xx (row + 1);
}
}
return part1, part2;
}
Section :: struct {
width: s64;
height: s64;
lines: []u8;
}