package Ġcom . chr is wk . a oc . ad vent 2 0 2 0 Ċ Ċ import Ġcom . chr is wk . a oc . Ad vent Day Ċ import Ġcom . chr is wk . a oc . util . Point 3 D Ċ import Ġcom . chr is wk . a oc . util . Point 4 D Ċ import Ġcom . chr is wk . a oc . util . report Ċ Ċ class ĠDay 1 7 : ĠAd vent Day ( 2 0 2 0 , Ġ 1 7 ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġday Ġ= ĠDay 1 7 () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġday . part 1 () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġday . part 2 () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġevaluate Point ( world : ĠWorld , Ġpoint : ĠPoint 3 D , Ġcurrent State : ĠBoolean ): ĠCube Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġactive Ne ighbour Count Ġ= Ġpoint . ne ighbours . count Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġworld . get OrDefault ( it , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠnewState Ġ= Ġactive Ne ighbour Count Ġ== Ġ 3 Ġ|| Ġcurrent State Ġ&& Ġactive Ne ighbour Count Ġ== Ġ 2 ĊĠĠĠĠĠĠĠ Ġreturn Ġpoint Ġto ĠnewState ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġevaluate Hyper Point ( world : ĠHyper World , Ġpoint : ĠPoint 4 D , Ġcurrent State : ĠBoolean ): ĠHyper Cube Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġactive Ne ighbour Count Ġ= Ġpoint . ne ighbours . count Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġworld . get OrDefault ( it , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠnewState Ġ= Ġwhen ( currentState ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> Ġactive Ne ighbour Count Ġin Ġ 2 .. 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> Ġactive Ne ighbour Count Ġ== Ġ 3 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġpoint Ġto ĠnewState ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġgather Points ToCheck ( world : ĠWorld ): ĠList < Point 3 D > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġworld . entries . filter Ġ{ Ġit . value Ġ}. flatMap Ġ{ Ġit . key . ne ighbours Ġ}. distinct (). toList () ĊĠĠĠ Ġ} ĊĠĠĠ Ġfun Ġgather Hyper Points ToCheck ( world : ĠHyper World ): ĠList < Point 4 D > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġworld . entries . filter Ġ{ Ġit . value Ġ}. flatMap Ġ{ Ġit . key . ne ighbours Ġ}. distinct () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstep ( world : ĠWorld ): ĠWorld Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġall Points Ġ= Ġgather Points ToCheck ( world ) ĊĠĠĠĠĠĠĠ Ġreturn Ġall Points . map Ġ{ Ġpoint Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevaluate Point ( world , Ġpoint , Ġworld . get OrDefault ( point , Ġfalse )) ĊĠĠĠĠĠĠĠ Ġ}. filter Ġ{ Ġit . second Ġ}. toMap () ĊĠĠĠ Ġ} ĊĠĠĠ Ġfun Ġhyper Step ( world : ĠHyper World ): ĠHyper World Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġall Points Ġ= Ġgather Hyper Points ToCheck ( world ) ĊĠĠĠĠĠĠĠ Ġreturn Ġall Points . map Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevaluate Hyper Point ( world , Ġp , Ġworld . get OrDefault ( p , Ġfalse )) ĊĠĠĠĠĠĠĠ Ġ}. filter Ġ{ Ġit . second Ġ}. toMap () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsimulate ( world : ĠWorld , Ġsteps : ĠInt ): ĠWorld Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġgenerate Sequence ( world ) Ġ{ Ġstep ( it ) Ġ}. drop ( steps ). first () ĊĠĠĠ Ġ} ĊĠĠĠ Ġfun Ġsimulate Hyper ( world : ĠHyper World , Ġsteps : ĠInt ): ĠHyper World Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġgenerate Sequence ( world ) Ġ{ Ġhyper Step ( it ) Ġ}. drop ( steps ). first () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġc ubes ( input : ĠList < String >): ĠWorld Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġinput . flatMap Indexed Ġ{ Ġx , Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrow . map Indexed Ġ{ Ġy , Ġcolumn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( Point 3 D ( x , Ġy , Ġ 0 ), Ġcolumn Ġ== Ġ'# ') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. toMap () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhyper C ubes ( input : ĠList < String >): ĠHyper World Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġinput . flatMap Indexed Ġ{ Ġx , Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrow . map Indexed Ġ{ Ġy , Ġcolumn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( Point 4 D ( x , Ġy , Ġ 0 , Ġ 0 ), Ġcolumn Ġ== Ġ'# ') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. toMap () ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpart 1 (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsimulate ( c ubes ( input As Lines ), Ġ 6 ). size ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpart 2 (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsimulate Hyper ( hyper C ubes ( input As Lines ), Ġ 6 ). size ĊĠĠĠ Ġ} Ċ Ċ } Ċ type alias ĠWorld Ġ= ĠMap < Point 3 D , ĠBoolean > Ċ type alias ĠHyper World Ġ= ĠMap < Point 4 D , ĠBoolean > Ċ type alias ĠHyper Cube Ġ= ĠPair < Point 4 D , ĠBoolean > Ċ type alias ĠCube Ġ= ĠPair < Point 3 D , ĠBoolean >