my advent of code solutions
at main 131 lines 3.8 kB view raw
1namespace Solutions._2020; 2 3/// <summary> 4/// Day 11: <a href="https://adventofcode.com/2020/day/11" /> 5/// </summary> 6public sealed class Day11SeatingSystem() : Day(2020, 11, "Seating System") 7{ 8 public override object Part1() 9 { 10 var prev = new LifeGame(Input); 11 12 while (true) 13 { 14 var next = prev.StepPart1(); 15 var same = true; 16 for (var i = 0; i < next.Grid.Length; i++) 17 if (!next.Grid[i].SequenceEqual(prev.Grid[i])) 18 { 19 same = false; 20 break; 21 } 22 23 if (same) break; 24 prev = next; 25 } 26 27 return prev.TotalSeated; 28 } 29 30 public override object Part2() 31 { 32 var prev = new LifeGame(Input); 33 while (true) 34 { 35 var next = prev.StepPart2(); 36 var same = true; 37 for (var i = 0; i < next.Grid.Length; i++) 38 if (!next.Grid[i].SequenceEqual(prev.Grid[i])) 39 { 40 same = false; 41 break; 42 } 43 44 if (same) break; 45 prev = next; 46 } 47 48 return prev.TotalSeated; 49 } 50 51 private class LifeGame 52 { 53 private int _h, _w; 54 public char[][] Grid; 55 56 public LifeGame(IEnumerable<string> input) 57 { 58 Grid = input.Select(line => line.ToCharArray()).ToArray(); 59 _h = Grid.Length; 60 _w = Grid[0].Length; 61 } 62 63 private LifeGame() => Grid = []; 64 65 public int TotalSeated => 66 Grid.Sum(l => l.Count(c => c == '#')); 67 68 public LifeGame StepPart1() 69 { 70 var next = new LifeGame { _h = _h, _w = _w, Grid = Grid.Select(s => s.ToArray()).ToArray() }; 71 for (var y = 0; y < _h; y++) 72 for (var x = 0; x < _w; x++) 73 next.Grid[y][x] = Grid[y][x] switch 74 { 75 'L' when CountAdjacent(y, x) == 0 => '#', 76 '#' when CountAdjacent(y, x) >= 4 => 'L', 77 _ => Grid[y][x], 78 }; 79 80 // next.PrintBoard(); 81 return next; 82 } 83 84 private char At(int y, int x) => 85 x < 0 || y < 0 || x >= _w || y >= _h ? '.' : Grid[y][x]; 86 87 private int CountAdjacent(int y, int x) => 88 new[] 89 { 90 At(y - 1, x - 1), At(y - 1, x + 0), At(y - 1, x + 1), At(y + 0, x - 1), At(y + 0, x + 1), 91 At(y + 1, x - 1), At(y + 1, x + 0), At(y + 1, x + 1), 92 }.Count(c => c == '#'); 93 94 public LifeGame StepPart2() 95 { 96 var next = new LifeGame { _h = _h, _w = _w, Grid = Grid.Select(s => s.ToArray()).ToArray() }; 97 for (var y = 0; y < _h; y++) 98 for (var x = 0; x < _w; x++) 99 next.Grid[y][x] = Grid[y][x] switch 100 { 101 'L' when CanSee(y, x) == 0 => '#', 102 '#' when CanSee(y, x) >= 5 => 'L', 103 _ => Grid[y][x], 104 }; 105 106 // next.PrintBoard(); 107 return next; 108 } 109 110 private int CanSee(int y, int x) => 111 new[] 112 { 113 TraceRay(y, x, -1, -1), TraceRay(y, x, -1, +0), TraceRay(y, x, -1, +1), TraceRay(y, x, +0, -1), 114 TraceRay(y, x, +0, +1), TraceRay(y, x, +1, -1), TraceRay(y, x, +1, +0), TraceRay(y, x, +1, +1), 115 }.Count(c => c == '#'); 116 117 private char TraceRay(int y, int x, int dy, int dx) 118 { 119 y += dy; 120 x += dx; 121 while (y >= 0 && y < _h && x >= 0 && x < _w) 122 { 123 if (Grid[y][x] != '.') return Grid[y][x]; 124 y += dy; 125 x += dx; 126 } 127 128 return '.'; 129 } 130 } 131}