import std; void main() { File("input", "r").byLineCopy.array.productOfTreesForDefaultSlopes.writeln; } alias product = partial!(reverseArgs!(fold!((a, b) => a * b)), 1UL); auto productOfTreesForDefaultSlopes(const char[][] input) { return [tuple(1, 1), tuple(3, 1), tuple(5, 1), tuple(7, 1), tuple(1, 2)].map!( slope => input.dup.countTrees(slope[0], slope[1])).product; } auto countTrees(const char[][] input, int angleX, int angleY) in(input.length > 0) { immutable width = input[0].length; size_t x = 0; return input.stride(angleY).map!((row) { auto result = row[x]; x = (x + angleX) % width; return result; }) .filter!(pos => pos == '#') .count; } unittest { auto input = `..##....... #...#...#.. .#....#..#. ..#.#...#.# .#...##..#. ..#.##..... .#.#.#....# .#........# #.##...#... #...##....# .#..#...#.#`.byChar.splitter("\n").map!array.array; assert(input.countTrees(1, 1) == 2); } unittest { auto input = `..##....... #...#...#.. .#....#..#. ..#.#...#.# .#...##..#. ..#.##..... .#.#.#....# .#........# #.##...#... #...##....# .#..#...#.#`.byChar.splitter("\n").map!array.array; assert(input.countTrees(3, 1) == 7); } unittest { auto input = `..##....... #...#...#.. .#....#..#. ..#.#...#.# .#...##..#. ..#.##..... .#.#.#....# .#........# #.##...#... #...##....# .#..#...#.#`.byChar.splitter("\n").map!array.array; assert(input.countTrees(5, 1) == 3); } unittest { auto input = `..##....... #...#...#.. .#....#..#. ..#.#...#.# .#...##..#. ..#.##..... .#.#.#....# .#........# #.##...#... #...##....# .#..#...#.#`.byChar.splitter("\n").map!array.array; assert(input.countTrees(7, 1) == 4); } unittest { auto input = `..##....... #...#...#.. .#....#..#. ..#.#...#.# .#...##..#. ..#.##..... .#.#.#....# .#........# #.##...#... #...##....# .#..#...#.#`.byChar.splitter("\n").map!array.array; assert(input.countTrees(1, 2) == 2); }