1+ // @ts -nocheck
12import fs from "node:fs" ;
23import path from "node:path" ;
34import { performance } from "node:perf_hooks" ;
@@ -8,16 +9,111 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
89// = Copyright (c) NullDev = //
910// ========================= //
1011
11- const INPUT = String ( fs . readFileSync ( path . join ( __dirname , "input.txt" ) ) ) . trim ( ) . split ( "\n" ) ;
12+ const INPUT = String ( fs . readFileSync ( path . join ( __dirname , "input.txt" ) ) ) . trim ( ) . split ( / \n \s * \n / ) ;
1213
1314const pStart = performance . now ( ) ;
1415
15- //
16- // YOUR CODE HERE
17- //
18- const result = "..." ;
16+ const normal = (
17+ cells ,
18+ minX = Math . min ( ...cells . map ( c => c [ 0 ] ) ) ,
19+ minY = Math . min ( ...cells . map ( c => c [ 1 ] ) ) ,
20+ norm = cells . map ( ( [ x , y ] ) => [ x - minX , y - minY ] ) ,
21+ ) => ( {
22+ cells : norm ,
23+ key : norm . slice ( )
24+ . sort ( ( a , b ) => a [ 0 ] - b [ 0 ] || a [ 1 ] - b [ 1 ] )
25+ . map ( ( [ x , y ] ) => `${ x } ,${ y } ` )
26+ . join ( ";" ) ,
27+ w : Math . max ( ...norm . map ( c => c [ 0 ] ) ) + 1 ,
28+ h : Math . max ( ...norm . map ( c => c [ 1 ] ) ) + 1 ,
29+ } ) ;
30+
31+ const mOrient = (
32+ rawCells , baseBox = normal ( rawCells ) ,
33+ { cells : base , w : w0 , h : h0 } = baseBox ,
34+ ) => {
35+ const rot = ( x , y , w , h , r ) => {
36+ if ( r === 0 ) return [ x , y ] ;
37+ if ( r === 1 ) return [ h - 1 - y , x ] ;
38+ if ( r === 2 ) return [ w - 1 - x , h - 1 - y ] ;
39+ return [ y , w - 1 - x ] ;
40+ } ;
41+
42+ const orients = [ ] ;
43+ const seen = new Set ( ) ;
44+ for ( let r = 0 ; r < 4 ; r ++ ) {
45+ const wRot = r % 2 === 0 ? w0 : h0 ;
46+ const rt = base . map ( ( [ x , y ] ) => rot ( x , y , w0 , h0 , r ) ) ;
47+
48+ for ( let f = 0 ; f < 2 ; f ++ ) {
49+ const { cells, key, w, h } = normal (
50+ f ? rt . map ( ( [ x , y ] ) => [ wRot - 1 - x , y ] ) : rt ,
51+ ) ;
52+ if ( ! seen . has ( key ) ) seen . add ( key ) && orients . push ( { cells, w, h } ) ;
53+ }
54+ }
55+
56+ return { orients, area : base . length } ;
57+ } ;
58+
59+ const shapes = [ ] ;
60+ INPUT . forEach ( ( block , _ , __ , l = block . trim ( ) . split ( "\n" ) ) => (
61+ shapes [ Number ( l [ 0 ] . replace ( ":" , "" ) ) ] = mOrient (
62+ l . slice ( 1 ) . flatMap (
63+ ( row , y ) => [ ...row ] . map ( ( ch , x ) => ( ch === "#" ? [ x , y ] : null ) ) . filter ( Boolean ) ,
64+ ) ,
65+ )
66+ ) ) ;
67+
68+ const res = INPUT . pop ( ) ?. trim ( ) . split ( "\n" ) . filter ( Boolean ) . filter ( (
69+ line , _ , __ ,
70+ [ dim , rest ] = line . split ( ":" ) ,
71+ [ W , H ] = dim . match ( / ( \d + ) x ( \d + ) / ) . slice ( 1 ) . map ( Number ) ,
72+ counts = rest . trim ( ) . split ( / \s + / ) . map ( Number ) ,
73+ ) => {
74+ if (
75+ counts . reduce ( ( s , c , i ) => s + c * ( shapes [ i ] ?. area || 0 ) , 0 ) > ( W * H )
76+ ) return false ;
77+
78+ const pl = shapes . map ( ( ) => [ ] ) ;
79+ for ( let i = 0 ; i < shapes . length ; i ++ ) {
80+ if ( ! ( counts [ i ] || 0 ) ) continue ;
81+ const masks = [ ] ;
82+ shapes [ i ] . orients . forEach ( o => {
83+ if ( o . w > W || o . h > H ) return ;
84+ for ( let y0 = 0 ; y0 <= H - o . h ; y0 ++ ) {
85+ for ( let x0 = 0 ; x0 <= W - o . w ; x0 ++ ) {
86+ let mask = 0n ;
87+ for ( const [ dx , dy ] of o . cells ) mask |= 1n << BigInt ( ( y0 + dy ) * W + ( x0 + dx ) ) ;
88+ masks . push ( mask ) ;
89+ }
90+ }
91+ } ) ;
92+
93+ if ( ! masks . length ) return false ;
94+ pl [ i ] = masks ;
95+ }
96+
97+ const pieces = counts . flatMap ( ( c , i ) => ( c ? Array ( c ) . fill ( i ) : [ ] ) )
98+ . sort ( ( a , b ) => pl [ a ] . length - pl [ b ] . length ) ;
99+
100+ const dfs = ( idx , occ ) => {
101+ if ( idx === pieces . length ) return true ;
102+ const opts = pl [ pieces [ idx ] ] ;
103+ for ( let k = 0 ; k < opts . length ; k ++ ) {
104+ const m = opts [ k ] ;
105+ if ( m & occ ) continue ;
106+ if ( dfs ( idx + 1 , occ | m ) ) return true ;
107+ }
108+ return false ;
109+ } ;
110+
111+ return dfs ( 0 , 0n ) ;
112+ } ) . length ;
113+
114+ // This sht takes about 15s to run but whatever
19115
20116const pEnd = performance . now ( ) ;
21117
22- console . log ( "<DESCRIPTION> : " + result ) ;
118+ console . log ( "REGIONS THAT FIT PRESENTS : " + res ) ;
23119console . log ( pEnd - pStart ) ;
0 commit comments