55import java .util .HashMap ;
66import java .util .HashSet ;
77import java .util .Map ;
8+ import java .util .Optional ;
89import java .util .Set ;
910
1011public class GardenGroups {
@@ -15,6 +16,7 @@ public class GardenGroups {
1516 private final Map <Integer , Integer > regionAreas = new HashMap <>();
1617 private final Map <Integer , Integer > regionSides = new HashMap <>();
1718 private final Map <Integer , Set <GardenPlot >> regionPlots = new HashMap <>();
19+ private GardenPlot noPlot ;
1820
1921 public GardenGroups (char [][] inputs ) {
2022
@@ -28,6 +30,9 @@ public GardenGroups(char[][] inputs) {
2830 }
2931 }
3032
33+ noPlot = new GardenPlot ('.' , new Vector2 (-1 ,-1 ));
34+ noPlot .setRegionId (-1 );
35+
3136 }
3237
3338 public long solveA () {
@@ -55,73 +60,156 @@ public long solveB() {
5560
5661 // Posibles casos eje: la primera celda y la última de cada fila/columna, ¿cuántos lados hay que contar?
5762
58- countHorizontalSides (); // TODO descomentar
63+ countHorizontalSides ();
5964 countVerticalSides ();
65+
66+ return calculatePriceB ();
67+ }
68+
69+ private int calculatePriceB () {
70+ int price = 0 ;
71+ for (Map .Entry <Integer ,Integer > regionArea : regionAreas .entrySet ()) {
72+ System .out .println ("Region: " + regionArea .getKey () + " - Area: " + regionArea .getValue () + " - Sides: " + regionSides .get (regionArea .getKey ()));
73+ price += regionArea .getValue () * regionSides .get (regionArea .getKey ());
74+ }
75+
6076 return price ;
6177 }
6278
6379 private void countHorizontalSides () {
64- GardenPlot [] previousRow = null ;
65-
80+
6681 for (int row = 0 ; row < rows ; row ++) {
67- GardenPlot leftPlot = null ;
6882 for (int col = 0 ; col < cols ; col ++) {
6983
70- GardenPlot plot = map [row ][col ];
71-
72- if (leftPlot != null && leftPlot .getRegionId () == plot .getRegionId ()) {
73- // Left is same region
74- continue ;
75- }
84+ GardenPlot currentPlot = map [row ][col ];
85+ GardenPlot leftPlot = getLeftPlot (row , col ).orElse (noPlot ());
7686
77- GardenPlot topPlot = previousRow != null ? previousRow [col ] : null ;
87+ // Search horizontal sides up
88+ GardenPlot topPlot = getUpPlot (row , col ).orElse (noPlot ());
89+ GardenPlot topLeftPlot = getUpLeftPlot (row ,col ).orElse (noPlot ());
7890
79- if (topPlot != null && topPlot . getRegionId () == plot . getRegionId ()) {
80- // Top is same region
81- continue ;
91+ if (checkAdjacents ( leftPlot , topPlot , currentPlot )
92+ || checkAdjacentsAndDiagonal ( leftPlot , topPlot , topLeftPlot , currentPlot )) {
93+ addSides ( currentPlot ) ;
8294 }
8395
84- int sides = regionSides .getOrDefault (plot .getRegionId (),0 );
85- regionSides .put (plot .getRegionId (), sides +1 );
96+ // Search horizontal sides down
97+ GardenPlot downPlot = getDownPlot (row ,col ).orElse (noPlot ());
98+ GardenPlot downLeftPlot = getDownLeftPlot (row , col ).orElse (noPlot );
8699
87- leftPlot = plot ;
100+ if (checkAdjacents (leftPlot , downPlot , currentPlot ) ||
101+ checkAdjacentsAndDiagonal (leftPlot , downPlot , downLeftPlot , currentPlot )) {
102+ addSides (currentPlot );
103+ }
88104 }
89- previousRow = map [row ];
90105 }
91106 }
92107
108+ private boolean checkAdjacents (GardenPlot left , GardenPlot topDown , GardenPlot current ) {
93109
94- private void countVerticalSides () {
110+ // Cases:
111+ // XX AX
112+ // XA< XA<
95113
96- GardenPlot [] previousCol = null ;
114+ // XA< XA<
115+ // XX AX
97116
98- for (int col = 0 ; col < cols ; col ++) {
99- GardenPlot topPlot = null ;
100- GardenPlot [] currentCol = new GardenPlot [cols ];
117+ return (left .getRegionId () != current .getRegionId () && topDown .getRegionId () != current .getRegionId ());
118+ }
101119
102- for ( int row = 0 ; row < rows ; row ++ ) {
120+ private boolean checkAdjacentsAndDiagonal ( GardenPlot left , GardenPlot topDown , GardenPlot diagonal , GardenPlot current ) {
103121
104- GardenPlot plot = map [row ][col ];
105- currentCol [row ] = plot ;
122+ // Cases:
106123
107- if (topPlot != null && topPlot .getRegionId () == plot .getRegionId ()) {
108- // Top is same region
109- continue ;
110- }
124+ // AX
125+ // -
126+ // AA <
127+
128+ // AA<
129+ // -
130+ // AX
131+
132+ return (left .getRegionId () == current .getRegionId () &&
133+ topDown .getRegionId () != current .getRegionId () &&
134+ diagonal .getRegionId () == current .getRegionId ());
135+ }
111136
112- GardenPlot leftPlot = previousCol != null ? previousCol [row ] : null ;
137+ private boolean checkAdjacentsAndDiagonalV (GardenPlot top , GardenPlot left , GardenPlot upLeft , GardenPlot current ) {
138+ // Cases:
139+
140+ // A A
141+ // X|A <
142+
143+ return top .getRegionId () == current .getRegionId () &&
144+ left .getRegionId () != current .getRegionId () &&
145+ upLeft .getRegionId () == current .getRegionId ();
146+
147+ }
148+
149+ private void addSides (GardenPlot gardenPlot ) {
150+ int sides = regionSides .getOrDefault (gardenPlot .getRegionId (),0 );
151+ regionSides .put (gardenPlot .getRegionId (), sides +1 );
152+ }
113153
114- if (leftPlot != null && leftPlot .getRegionId () == plot .getRegionId ()) {
115- // Top is same region
116- continue ;
154+ private GardenPlot noPlot () {
155+ return noPlot ;
156+ }
157+
158+ private Optional <GardenPlot > getLeftPlot (int row , int col ) {
159+ return (col > 0 ) ? Optional .of (map [row ][col -1 ]) : Optional .empty ();
160+ }
161+
162+ private Optional <GardenPlot > getRightPlot (int row , int col ) {
163+ return (col +1 < cols ) ? Optional .of (map [row ][col +1 ]) : Optional .empty ();
164+ }
165+
166+ private Optional <GardenPlot > getUpPlot (int row , int col ) {
167+ return (row > 0 ) ? Optional .of (map [row -1 ][col ]) : Optional .empty ();
168+ }
169+
170+ private Optional <GardenPlot > getDownPlot (int row , int col ) {
171+ return (row +1 < rows ) ? Optional .of (map [row +1 ][col ]) : Optional .empty ();
172+ }
173+
174+ private Optional <GardenPlot > getUpLeftPlot (int row , int col ) {
175+ return (row > 0 && col > 0 ) ? Optional .of (map [row -1 ][col -1 ]) : Optional .empty ();
176+ }
177+
178+ private Optional <GardenPlot > getUpRightPlot (int row , int col ) {
179+ return (row > 0 && col +1 < cols ) ? Optional .of (map [row -1 ][col +1 ]) : Optional .empty ();
180+ }
181+
182+ private Optional <GardenPlot > getDownLeftPlot (int row , int col ) {
183+ return (row +1 < rows && col > 0 ) ? Optional .of (map [row +1 ][col -1 ]) : Optional .empty ();
184+ }
185+
186+
187+ private void countVerticalSides () {
188+
189+ for (int col = 0 ; col < cols ; col ++) {
190+ for (int row = 0 ; row < rows ; row ++) {
191+
192+ GardenPlot currentPlot = map [row ][col ];
193+ GardenPlot topPlot = getUpPlot (row , col ).orElse (noPlot ());
194+
195+ // Search vertical sides right
196+ GardenPlot rightPlot = getRightPlot (row , col ).orElse (noPlot ());
197+ GardenPlot topRightPlot = getUpRightPlot (row ,col ).orElse (noPlot ());
198+
199+ if (checkAdjacents (rightPlot , topPlot , currentPlot )
200+ || checkAdjacentsAndDiagonal (rightPlot , topPlot , topRightPlot , currentPlot )) {
201+ addSides (currentPlot );
117202 }
118203
119- int sides = regionSides .getOrDefault (plot .getRegionId (),0 );
120- regionSides .put (plot .getRegionId (), sides +1 );
204+ // Search vertical sides left
205+ GardenPlot leftPlot = getLeftPlot (row ,col ).orElse (noPlot ());
206+ GardenPlot topLeftPlot = getUpLeftPlot (row , col ).orElse (noPlot );
121207
122- topPlot = plot ;
208+ if (checkAdjacents (leftPlot , topPlot , currentPlot ) ||
209+ checkAdjacentsAndDiagonalV (topPlot , leftPlot , topLeftPlot , currentPlot )) {
210+ addSides (currentPlot );
211+ }
123212 }
124- previousCol = currentCol ;
125213 }
126214 }
127215
0 commit comments