package Ġpl . sh ock ah . a oc . y 2 0 2 0 Ċ Ċ import Ġorg . junit . jupiter . api . Assertions Ċ import Ġorg . junit . jupiter . api . Test Ċ import Ġpl . sh ock ah . a oc . Ad vent Task Ċ import Ġpl . sh ock ah . a oc . parse OrNull Ċ import Ġjava . util . regex . Pattern Ċ Ċ class ĠDay 4 : ĠAd vent Task < List < Day 4 . Passport >, ĠInt , ĠInt >( 2 0 2 0 , Ġ 4 ) Ġ{ Ċ ĉ private Ġval Ġeye Colors Ġ= ĠlistOf (" amb ", Ġ" bl u ", Ġ" br n ", Ġ" gry ", Ġ" gr n ", Ġ" hz l ", Ġ" oth ") Ċ ĉ private Ġval Ġhex Regex Ġ= ĠRegex ("# [ \\ da - f ]{ 6 }") Ċ ĉ private Ġval Ġcm Height Regex Ġ= ĠPattern . compile ("( \\ d +) cm ") Ċ ĉ private Ġval Ġin ch Height Regex Ġ= ĠPattern . compile ("( \\ d +) in ") ĊĊ ĉ data Ġclass ĠPass port ( Ċĉ ĉ val Ġfields : ĠMap < String , ĠString > Ċ ĉ ) ĊĊ ĉ override Ġfun Ġparse Input ( raw Input : ĠString ): ĠList < Passport > Ġ{ Ċĉ ĉ val Ġentries Ġ= Ġraw Input . split ("\ n \ n ") Ċĉ ĉ return Ġentries . map Ġ{ Ċĉĉ ĉ val Ġraw Fields Ġ= Ġit . replace ("\ n ", Ġ" Ġ"). split (" Ġ") Ċĉĉ ĉ val Ġfields Ġ= Ġraw Fields . map Ġfield Map @ Ġ{ Ċĉĉĉ ĉ val Ġsplit Ġ= Ġit . split (": ") Ċĉĉĉ ĉ return @ field Map Ġsplit [ 0 ] Ġto Ġsplit [ 1 ] Ċĉĉ ĉ }. toMap () Ċĉĉ ĉ return @ map ĠPass port ( fields ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ override Ġfun Ġpart 1 ( input : ĠList < Passport >): ĠInt Ġ{ Ċĉ ĉ return Ġinput . count Ġ{ Ġit . fields . keys . contains All ( listOf (" by r ", Ġ" i yr ", Ġ" ey r ", Ġ" h gt ", Ġ" h cl ", Ġ" e cl ", Ġ" pid ")) Ġ} Ċ ĉ } ĊĊ ĉ override Ġfun Ġpart 2 ( input : ĠList < Passport >): ĠInt Ġ{ Ċĉ ĉ return Ġinput . count Ġ{ Ġpassport Ġ-> Ċĉĉ ĉ passport . fields [" by r "] ?. toInt OrNull ()?. take If Ġ{ Ġit Ġin Ġ 1 9 2 0 .. 2 0 0 2 Ġ} Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ passport . fields [" i yr "] ?. toInt OrNull ()?. take If Ġ{ Ġit Ġin Ġ 2 0 1 0 .. 2 0 2 0 Ġ} Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ passport . fields [" ey r "] ?. toInt OrNull ()?. take If Ġ{ Ġit Ġin Ġ 2 0 2 0 .. 2 0 3 0 Ġ} Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ passport . fields [" h gt "] ?. take If Ġ{ Ġis Height Valid ( it ) Ġ} Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ passport . fields [" h cl "] ?. take If Ġ{ Ġit . matches ( hex Regex ) Ġ} Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ passport . fields [" e cl "] ?. take If Ġ{ Ġit Ġin Ġeye Colors Ġ} Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ passport . fields [" pid "] ?. take If Ġ{ Ġit . length Ġ== Ġ 9 Ġ} ?. toInt OrNull () Ġ?: Ġreturn @ count Ġfalse Ċĉĉ ĉ return @ count Ġtrue Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ private Ġfun Ġis Height Valid ( height : ĠString ): ĠBoolean Ġ{ Ċĉ ĉ run Ġ{ Ċĉĉ ĉ val Ġcm Height Ġ= Ġcm Height Regex . parse OrNull < Int >( height ) Ċĉĉ ĉ if Ġ( cm Height Ġ!= Ġnull Ġ&& Ġcm Height Ġin Ġ 1 5 0 .. 1 9 3 ) Ċĉĉĉ ĉ return Ġtrue Ċĉ ĉ } ĊĊĉ ĉ run Ġ{ Ċĉĉ ĉ val Ġin ch Height Ġ= Ġin ch Height Regex . parse OrNull < Int >( height ) Ċĉĉ ĉ if Ġ( in ch Height Ġ!= Ġnull Ġ&& Ġin ch Height Ġin Ġ 5 9 .. 7 6 ) Ċĉĉĉ ĉ return Ġtrue Ċĉ ĉ } ĊĊĉ ĉ return Ġfalse Ċ ĉ } ĊĊ ĉ class ĠTests Ġ{ Ċĉ ĉ private Ġval Ġtask Ġ= ĠDay 4 () ĊĊĉ ĉ private Ġval Ġraw Input Ġ= Ġ""" Ċĉĉ ĉ e cl : gry Ġpid : 8 6 0 0 3 3 3 2 7 Ġe yr : 2 0 2 0 Ġh cl :# ffff fd Ċĉĉ ĉ by r : 1 9 3 7 Ġi yr : 2 0 1 7 Ġcid : 1 4 7 Ġh gt : 1 8 3 cm ĊĉĉĉĊĉĉ ĉ i yr : 2 0 1 3 Ġe cl : amb Ġcid : 3 5 0 Ġe yr : 2 0 2 3 Ġpid : 0 2 8 0 4 8 8 8 4 Ċĉĉ ĉ h cl :# cfa 0 7 d Ġby r : 1 9 2 9 ĊĉĉĉĊĉĉ ĉ h cl :# ae 1 7 e 1 Ġi yr : 2 0 1 3 Ċĉĉ ĉ ey r : 2 0 2 4 Ċĉĉ ĉ e cl : br n Ġpid : 7 6 0 7 5 3 1 0 8 Ġby r : 1 9 3 1 Ċĉĉ ĉ h gt : 1 7 9 cm ĊĉĉĉĊĉĉ ĉ h cl :# cfa 0 7 d Ġe yr : 2 0 2 5 Ġpid : 1 6 6 5 5 9 6 4 8 Ċĉĉ ĉ i yr : 2 0 1 1 Ġe cl : br n Ġh gt : 5 9 in ĊĉĉĉĊĉĉ ĉ ey r : 1 9 7 2 Ġcid : 1 0 0 Ċĉĉ ĉ h cl :# 1 8 1 7 1 d Ġe cl : amb Ġh gt : 1 7 0 Ġpid : 1 8 6 cm Ġi yr : 2 0 1 8 Ġby r : 1 9 2 6 ĊĊĉĉ ĉ i yr : 2 0 1 9 Ċĉĉ ĉ h cl :# 6 0 2 9 2 7 Ġe yr : 1 9 6 7 Ġh gt : 1 7 0 cm Ċĉĉ ĉ e cl : gr n Ġpid : 0 1 2 5 3 3 0 4 0 Ġby r : 1 9 4 6 ĊĊĉĉ ĉ h cl : dab 2 2 7 Ġi yr : 2 0 1 2 Ċĉĉ ĉ e cl : br n Ġh gt : 1 8 2 cm Ġpid : 0 2 1 5 7 2 4 1 0 Ġe yr : 2 0 2 0 Ġby r : 1 9 9 2 Ġcid : 2 7 7 ĊĊĉĉ ĉ h gt : 5 9 cm Ġe cl : zz z Ċĉĉ ĉ ey r : 2 0 3 8 Ġh cl : 7 4 4 5 4 a Ġi yr : 2 0 2 3 Ċĉĉ ĉ pid : 3 5 5 6 4 1 2 3 7 8 Ġby r : 2 0 0 7 ĊĉĉĉĊĉĉ ĉ pid : 0 8 7 4 9 9 7 0 4 Ġh gt : 7 4 in Ġe cl : gr n Ġi yr : 2 0 1 2 Ġe yr : 2 0 3 0 Ġby r : 1 9 8 0 Ċĉĉ ĉ h cl :# 6 2 3 a 2 f ĊĊĉĉ ĉ ey r : 2 0 2 9 Ġe cl : bl u Ġcid : 1 2 9 Ġby r : 1 9 8 9 Ċĉĉ ĉ i yr : 2 0 1 4 Ġpid : 8 9 6 0 5 6 5 3 9 Ġh cl :# a 9 7 8 4 2 Ġh gt : 1 6 5 cm ĊĊĉĉ ĉ h cl :# 8 8 8 7 8 5 Ċĉĉ ĉ h gt : 1 6 4 cm Ġby r : 2 0 0 1 Ġi yr : 2 0 1 5 Ġcid : 8 8 Ċĉĉ ĉ pid : 5 4 5 7 6 6 2 3 8 Ġe cl : hz l Ċĉĉ ĉ ey r : 2 0 2 2 ĊĊĉĉ ĉ i yr : 2 0 1 0 Ġh gt : 1 5 8 cm Ġh cl :# b 6 6 5 2 a Ġe cl : bl u Ġby r : 1 9 4 4 Ġe yr : 2 0 2 1 Ġpid : 0 9 3 1 5 4 7 1 9 Ċĉ ĉ """. trim Indent () ĊĊĉ ĉ @ Test Ċĉ ĉ fun Ġpart 1 () Ġ{ Ċĉĉ ĉ val Ġinput Ġ= Ġtask . parse Input ( raw Input ) Ċĉĉ ĉ Assertions . assertEquals ( 1 0 , Ġtask . part 1 ( input )) Ċĉ ĉ } ĊĊĉ ĉ @ Test Ċĉ ĉ fun Ġpart 2 () Ġ{ Ċĉĉ ĉ val Ġinput Ġ= Ġtask . parse Input ( raw Input ) Ċĉĉ ĉ Assertions . assertEquals ( 6 , Ġtask . part 2 ( input )) Ċĉ ĉ } Ċ ĉ } Ċ }