11using System ;
2- using System . Text ;
32using System . Collections . Generic ;
4- using AdventOfCode . UserClasses ;
5- using System . Linq ;
63using System . Data ;
7- using System . Threading ;
8- using System . Security ;
9- using static AdventOfCode . Solutions . Utilities ;
10- using System . Runtime . CompilerServices ;
4+ using System . Linq ;
115
126namespace AdventOfCode . Solutions . Year2023
137{
148 [ DayInfo ( 22 , 2023 , "" ) ]
159 class Day22 : ASolution
1610 {
11+ List < Brick > AllBricks = new ( ) ;
12+ Dictionary < char , int > BrickFallCounts = new ( ) ;
1713 public Day22 ( ) : base ( )
1814 {
15+ char i = 'A' ;
16+ foreach ( var l in Input . SplitByNewline ( ) )
17+ {
18+ var n = l . ExtractInts ( ) . ToList ( ) ;
19+ Brick tmp = new ( i , ( n [ 0 ] , n [ 1 ] , n [ 2 ] ) , ( n [ 3 ] , n [ 4 ] , n [ 5 ] ) ) ;
20+ AllBricks . Add ( tmp ) ;
21+ i ++ ;
22+ }
23+
24+
25+ //Shift bricks that can move down until everyone is settled
26+ int numBricksShifted ;
27+ do
28+ {
29+ numBricksShifted = 0 ;
30+
31+ HashSet < Coordinate3D > AllBrickPoints = new ( ) ;
32+
33+ foreach ( var b in AllBricks ) foreach ( var p in b . Members ( ) ) AllBrickPoints . Add ( p ) ;
34+
35+ foreach ( var b in AllBricks )
36+ {
37+ if ( b . Members ( ) . Any ( m => m . z == 1 || ( AllBrickPoints . Contains ( m - ( 0 , 0 , 1 ) ) && ! b . Members ( ) . Contains ( m - ( 0 , 0 , 1 ) ) ) ) ) continue ;
1938
39+ b . Start = b . Start - ( 0 , 0 , 1 ) ;
40+ b . End = b . End - ( 0 , 0 , 1 ) ;
41+ numBricksShifted ++ ;
42+ }
43+
44+
45+ } while ( numBricksShifted != 0 ) ;
46+
47+ AllBricks . Sort ( ( a , b ) => a . Start . z . CompareTo ( b . Start . z ) ) ;
48+
49+ //Get everyone's interactions with one another.
50+ foreach ( var b in AllBricks )
51+ {
52+ foreach ( var p in AllBricks . Where ( a => a . Start . z == b . End . z + 1 ) )
53+ {
54+ foreach ( var m in b . Members ( ) )
55+ {
56+ if ( p . Members ( ) . Any ( a => a . x == m . x && a . y == m . y && a . z - 1 == m . z ) )
57+ {
58+ b . Supports . Add ( p ) ;
59+ p . SupportedBy . Add ( b ) ;
60+ break ;
61+ }
62+ }
63+ }
64+ }
65+
66+ foreach ( var b in AllBricks ) BrickFallCount ( b , new ( ) , true ) ;
2067 }
2168
2269 protected override object SolvePartOne ( )
2370 {
24- return null ;
71+ return BrickFallCounts . Count ( kvp => kvp . Value == 0 ) ;
2572 }
2673
2774 protected override object SolvePartTwo ( )
2875 {
29- return null ;
76+ return BrickFallCounts . Sum ( k => k . Value ) ;
77+ }
78+
79+ private void BrickFallCount ( Brick b , List < char > toIgnore , bool updateDict = false )
80+ {
81+ toIgnore . Add ( b . id ) ;
82+ if ( b . Supports . Count == 0 )
83+ {
84+ if ( updateDict ) BrickFallCounts [ b . id ] = 0 ;
85+ }
86+
87+ //Collect all that would fall with the removal of that support
88+ var bricksThatFall = b . Supports . Where ( p => p . SupportedBy . Count ( a => ! toIgnore . Contains ( a . id ) ) == 0 ) . ToList ( ) ;
89+ foreach ( var p in bricksThatFall )
90+ {
91+ toIgnore . Add ( p . id ) ;
92+ }
93+
94+ foreach ( var p in bricksThatFall )
95+ {
96+ BrickFallCount ( p , toIgnore ) ;
97+ }
98+
99+ if ( updateDict ) BrickFallCounts [ b . id ] = toIgnore . Distinct ( ) . Count ( ) - 1 ;
100+ }
101+
102+ private class Brick
103+ {
104+ public char id ;
105+ public Coordinate3D Start ;
106+ public Coordinate3D End ;
107+
108+ public List < Brick > Supports = new ( ) ;
109+ public List < Brick > SupportedBy = new ( ) ;
110+
111+ public int Length => Start . ManhattanDistance ( End ) + 1 ;
112+
113+ public IEnumerable < Coordinate3D > Members ( )
114+ {
115+ yield return Start ;
116+ var curLoc = Start ;
117+ while ( curLoc != End )
118+ {
119+ if ( Start . x == End . x && Start . y == End . y ) curLoc = curLoc + ( 0 , 0 , 1 ) ; //Vertically Oriented Brick
120+ else if ( Start . x == End . x && Start . z == End . z ) curLoc = curLoc + ( 0 , 1 , 0 ) ; //Oriented Along Y- Axis
121+ else if ( Start . y == End . y && Start . z == End . z ) curLoc = curLoc + ( 1 , 0 , 0 ) ; //Oriented Along x- Axis
122+ yield return curLoc ;
123+ }
124+ }
125+
126+ public Brick ( char id , Coordinate3D p1 , Coordinate3D p2 )
127+ {
128+ this . id = id ;
129+ if ( p1 . x < p2 . x || p1 . y < p2 . y || p1 . z < p2 . z )
130+ {
131+ Start = p1 ;
132+ End = p2 ;
133+ }
134+ else
135+ {
136+ Start = p2 ;
137+ End = p2 ;
138+ }
139+ }
140+
141+ public override string ToString ( )
142+ {
143+ return id . ToString ( ) ;
144+ }
30145 }
31146 }
32- }
147+ }
0 commit comments