github.com/cycloss/advent-of-code@v0.0.0-20221210145555-15039b95faa6/2021/day11/objects.dart (about) 1 class Octo { 2 int x, y, value; 3 Octo(this.x, this.y, this.value); 4 5 @override 6 int get hashCode => Object.hashAll([y, x]); 7 8 @override 9 bool operator ==(Object other) { 10 return other is Octo && 11 other.runtimeType == runtimeType && 12 other.y == y && 13 other.x == x; 14 } 15 16 bool increment() { 17 value++; 18 if (value > 9) { 19 value = 0; 20 return true; 21 } 22 return false; 23 } 24 } 25 26 class OctoSim { 27 late final List<List<Octo>> octos; 28 int flashes = 0; 29 30 int get octoCount => 31 octos.fold(0, (tot, row) => tot + row.fold(0, (prev, _) => prev + 1)); 32 33 OctoSim({ 34 required rows, 35 }) { 36 initOctos(rows); 37 } 38 39 void initOctos(List<List<int>> rows) { 40 List<List<Octo>> octos = []; 41 for (var y = 0; y < rows.length; y++) { 42 var row = rows[y]; 43 var octoRow = <Octo>[]; 44 for (var x = 0; x < row.length; x++) { 45 var value = row[x]; 46 var octo = Octo(x, y, value); 47 octoRow.add(octo); 48 } 49 octos.add(octoRow); 50 } 51 this.octos = octos; 52 } 53 54 int iterateOctos(int iterations) { 55 for (var i = 0; i < iterations; i++) { 56 iterate(); 57 } 58 return flashes; 59 } 60 61 int findFirstSimultaneousFlash() { 62 int iterations = 0; 63 while (true) { 64 iterations++; 65 var currentFlashCount = iterate(); 66 if (currentFlashCount >= octoCount) { 67 break; 68 } 69 } 70 return iterations; 71 } 72 73 int iterate() { 74 var flashed = <Octo>{}; 75 var currentFlashCount = 0; 76 for (var y = 0; y < octos.length; y++) { 77 var octoRow = octos[y]; 78 for (var x = 0; x < octoRow.length; x++) { 79 var octo = octoRow[x]; 80 currentFlashCount += processOcto(octo, flashed); 81 } 82 } 83 return currentFlashCount; 84 } 85 86 int processOcto(Octo octo, Set<Octo> flashed) { 87 if (flashed.contains(octo)) { 88 return 0; 89 } 90 var didFlash = octo.increment(); 91 if (didFlash) { 92 flashed.add(octo); 93 flashes++; 94 return 1 + 95 findValidNeighbours(octo) 96 .fold(0, (total, o) => total + processOcto(o, flashed)); 97 } 98 return 0; 99 } 100 101 List<Octo> findValidNeighbours(Octo octo) { 102 var valids = <Octo>[]; 103 var x = octo.x; 104 var y = octo.y; 105 var upOk = y > 0; 106 var downOk = y < octos.length - 1; 107 var leftOk = x > 0; 108 var rightOk = x < octos[y].length - 1; 109 if (upOk) { 110 valids.add(octos[y - 1][x]); 111 if (rightOk) { 112 valids.add(octos[y - 1][x + 1]); 113 } 114 if (leftOk) { 115 valids.add(octos[y - 1][x - 1]); 116 } 117 } 118 if (rightOk) { 119 valids.add(octos[y][x + 1]); 120 } 121 if (downOk) { 122 valids.add(octos[y + 1][x]); 123 if (rightOk) { 124 valids.add(octos[y + 1][x + 1]); 125 } 126 if (leftOk) { 127 valids.add(octos[y + 1][x - 1]); 128 } 129 } 130 if (leftOk) { 131 valids.add(octos[y][x - 1]); 132 } 133 return valids; 134 } 135 }