1- // import { Box, BooleanOperations, Polygon } from "@flatten-js/core";
2- // const { intersect } = BooleanOperations;
3-
41export function part1 ( input ) {
52 let points = input . split ( "\n" ) . map ( line => {
63 let [ x , y ] = line . split ( "," ) . map ( Number ) ;
@@ -11,7 +8,7 @@ export function part1(input) {
118 for ( let j = i + 1 ; j < points . length ; j ++ ) {
129 let p1 = points [ i ] ;
1310 let p2 = points [ j ] ;
14- let area = Math . abs ( p1 . x - p2 . x + 1 ) * Math . abs ( p1 . y - p2 . y + 1 ) ;
11+ let area = ( Math . abs ( p1 . x - p2 . x ) + 1 ) * ( Math . abs ( p1 . y - p2 . y ) + 1 ) ;
1512 if ( area > maxArea ) {
1613 maxArea = area ;
1714 }
@@ -20,159 +17,38 @@ export function part1(input) {
2017 return maxArea ;
2118}
2219
23- function connectPoints ( p1 , p2 , grid ) {
24- let xStep = p1 . x < p2 . x ? 1 : p1 . x > p2 . x ? - 1 : 0 ;
25- let yStep = p1 . y < p2 . y ? 1 : p1 . y > p2 . y ? - 1 : 0 ;
26- let x = p1 . x ;
27- let y = p1 . y ;
28- while ( x !== p2 . x || y !== p2 . y ) {
29- grid . set ( `${ y } ,${ x } ` , 1 ) ;
30- x += xStep ;
31- y += yStep ;
32- }
33- }
34-
35- function findPointWithinShape ( grid , height , width ) {
36- for ( let y = 0 ; y < height ; y ++ ) {
37- for ( let x = 0 ; x < width ; x ++ ) {
38- x = ( Math . random ( ) * width ) | 0 ;
39- y = ( Math . random ( ) * height ) | 0 ;
40- if ( grid . get ( `${ y } ,${ x } ` ) === 1 ) continue ;
41- let queue = [ { x, y } ] ;
42- let visited = new Set ( ) ;
43- let found = true ;
44- while ( queue . length > 0 ) {
45- let { x : cx , y : cy } = queue . shift ( ) ;
46- let key = `${ cx } ,${ cy } ` ;
47- if ( visited . has ( key ) ) continue ;
48- visited . add ( key ) ;
49- if ( cx < 0 || cx >= width || cy < 0 || cy >= height ) {
50- found = false ;
51- break ;
52- }
53- if ( grid . get ( `${ cy } ,${ cx } ` ) === 1 ) continue ;
54- queue . push ( { x : cx + 1 , y : cy } ) ;
55- queue . push ( { x : cx - 1 , y : cy } ) ;
56- queue . push ( { x : cx , y : cy + 1 } ) ;
57- queue . push ( { x : cx , y : cy - 1 } ) ;
58- }
59- if ( found ) {
60- return { x, y } ;
61- }
62- }
63- }
64- return null ;
65- }
66-
67- function fillGrid ( points , grid , height , width ) {
68- for ( let i = 0 ; i < points . length ; i ++ ) {
69- let p1 = points [ i ] ;
70- let p2 = points [ ( i + 1 ) % points . length ] ;
71- connectPoints ( p1 , p2 , grid ) ;
72- }
73- let insidePoint = findPointWithinShape ( grid , height , width ) ;
74- let queue = [ insidePoint ] ;
75- let visited = new Set ( ) ;
76- while ( queue . length > 0 ) {
77- let { x : cx , y : cy } = queue . shift ( ) ;
78- let key = `${ cx } ,${ cy } ` ;
79- if ( visited . has ( key ) ) continue ;
80- visited . add ( key ) ;
81- if ( grid . get ( `${ cy } ,${ cx } ` ) === 1 ) continue ;
82- grid . set ( `${ cy } ,${ cx } ` , 1 ) ;
83- queue . push ( { x : cx + 1 , y : cy } ) ;
84- queue . push ( { x : cx - 1 , y : cy } ) ;
85- queue . push ( { x : cx , y : cy + 1 } ) ;
86- queue . push ( { x : cx , y : cy - 1 } ) ;
87- }
88- }
89-
90- // function test(input) {
91- // let points = input.split("\n").map(line => {
92- // let [x, y] = line.split(",").map(Number);
93- // return { x, y };
94- // });
95- // let maxArea = 0;
96- // let polygon = new Polygon(points.map(p => [p.x, p.y]));
97- // for (let i = 0; i < points.length; i++) {
98- // for (let j = i + 1; j < points.length; j++) {
99- // let a = points[i];
100- // let b = points[j];
101- // let minX = Math.min(a.x, b.x);
102- // let maxX = Math.max(a.x, b.x);
103- // let minY = Math.min(a.y, b.y);
104- // let maxY = Math.max(a.y, b.y);
105- // let box = new Box(minX, minY, maxX, maxY);
106-
107- // let boxPolygon = new Polygon(box);
108- // try {
109- // let intersectionArea = intersect(polygon, boxPolygon).area();
110- // let boxArea = boxPolygon.area();
111- // if (intersectionArea === boxArea) {
112- // let area = Math.abs(a.x - b.x + 1) * Math.abs(a.y - b.y + 1);
113- // if (area > maxArea) {
114- // maxArea = area;
115- // }
116- // }
117- // } catch {
118- // //
119- // }
120- // }
121- // }
122- // return maxArea;
123- // }
124-
125- function slow ( input ) {
20+ export function part2 ( input ) {
12621 let points = input . split ( "\n" ) . map ( line => {
12722 let [ x , y ] = line . split ( "," ) . map ( Number ) ;
12823 return { x, y } ;
12924 } ) ;
130- let maxArea = 0 ;
131- for ( let p of points ) {
132- p . x = Math . floor ( p . x / 100 ) ;
133- p . y = Math . floor ( p . y / 100 ) ;
134- }
135- let maxX = Math . max ( ...points . map ( p => p . x ) ) ;
136- let maxY = Math . max ( ...points . map ( p => p . y ) ) ;
137- let grid = new Map ( ) ;
138- fillGrid ( points , grid , maxY + 1 , maxX + 1 ) ;
139- let result ;
25+ let squares = [ ] ;
14026 for ( let i = 0 ; i < points . length ; i ++ ) {
14127 for ( let j = i + 1 ; j < points . length ; j ++ ) {
14228 let p1 = points [ i ] ;
14329 let p2 = points [ j ] ;
144- let isContained = true ;
145- let minX = Math . min ( p1 . x , p2 . x ) ;
146- let maxX = Math . max ( p1 . x , p2 . x ) ;
147- let minY = Math . min ( p1 . y , p2 . y ) ;
148- let maxY = Math . max ( p1 . y , p2 . y ) ;
149- for ( let y = minY ; y <= maxY ; y ++ ) {
150- for ( let x = minX ; x <= maxX ; x ++ ) {
151- if ( grid . get ( `${ y } ,${ x } ` ) !== 1 ) {
152- isContained = false ;
153- break ;
154- }
155- }
156- if ( ! isContained ) break ;
157- }
158- if ( ! isContained ) continue ;
159- let area = Math . abs ( p1 . x - p2 . x + 1 ) * Math . abs ( p1 . y - p2 . y + 1 ) ;
160- if ( area > maxArea ) {
161- maxArea = area ;
162- result = { i, j } ;
163- }
30+ let area = ( Math . abs ( p1 . x - p2 . x ) + 1 ) * ( Math . abs ( p1 . y - p2 . y ) + 1 ) ;
31+ squares . push ( { area, p1, p2 } ) ;
16432 }
16533 }
166- points = input . split ( "\n" ) . map ( line => {
167- let [ x , y ] = line . split ( "," ) . map ( Number ) ;
168- return { x, y } ;
169- } ) ;
170- let p1 = points [ result . i ] ;
171- let p2 = points [ result . j ] ;
172- maxArea = Math . abs ( p1 . x - p2 . x + 1 ) * Math . abs ( p1 . y - p2 . y + 1 ) ;
173- return maxArea ;
174- }
34+ squares . sort ( ( a , b ) => b . area - a . area ) ;
17535
176- export function part2 ( input ) {
177- return slow ( input ) ;
36+ let sides = [ ] ;
37+ for ( let i = 0 ; i < points . length ; i ++ ) {
38+ let p1 = points [ i ] ;
39+ let p2 = points [ ( i + 1 ) % points . length ] ;
40+ sides . push ( { p1, p2 } ) ;
41+ }
42+
43+ const disjoint = ( a1 , a2 , b1 , b2 ) =>
44+ ( a1 <= b1 && a1 <= b2 && a2 <= b1 && a2 <= b2 ) ||
45+ ( a1 >= b1 && a1 >= b2 && a2 >= b1 && a2 >= b2 ) ;
46+
47+ return squares . find ( square => {
48+ return sides . every (
49+ side =>
50+ disjoint ( side . p1 . y , side . p2 . y , square . p1 . y , square . p2 . y ) ||
51+ disjoint ( side . p1 . x , side . p2 . x , square . p1 . x , square . p2 . x ) ,
52+ ) ;
53+ } ) . area ;
17854}
0 commit comments