package Ġdays Ċ Ċ class ĠDay 7 Ġ: ĠDay ( 7 ) Ġ{ ĊĊĠĠĠ Ġ// ĠThe Ġtarget Ġof Ġour Ġinvestigation Ġis ... ĊĠĠĠ Ġprivate Ġval Ġtarget Bag Ġ= Ġ" sh iny Ġgold " ĊĊĠĠĠ Ġ// Ġcreate Ġa Ġ" Bag Ġname " Ġlookup Ġmap Ġfor Ġconvenience ĊĠĠĠ Ġprivate Ġval Ġbags : ĠMap < String , ĠList < Rule >> Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġinput List ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġdescription Ġ-> Ġbag From Description ( description ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. associate By ({ Ġit . first Ġ}, Ġ{ Ġit . second Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġsimple Ġrepresentation Ġof Ġ" sub - bag " Ġrules ĊĠĠĠ Ġdata Ġclass ĠRule ( val Ġname : ĠString , Ġval Ġquantity : ĠInt ) ĊĊĠĠĠ Ġfun Ġbag From Description ( description : ĠString ) Ġ: ĠPair < String , ĠList < Rule >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġname And Contents Ġ= Ġdescription . split (" Ġbags Ġcontain Ġ") ĊĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġname And Contents . first () ĊĠĠĠĠĠĠĠ Ġval Ġcontents Ġ= Ġname And Contents . last () ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhen Ġthe Ġcontents Ġcontain Ġthe Ġphrase Ġ" no Ġother Ġbags " Ġthere Ġis Ġno Ġfurther Ġrule Ġto Ġextract ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontents Ġ== Ġ" no Ġother Ġbags ." Ġ-> ĠPair ( name , Ġempty List ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġotherwise , Ġproceed Ġto Ġextract Ġeach Ġ" sub - bag " Ġrule ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠPair ( name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontents ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġeach Ġbag Ġrule Ġis Ġseparated Ġwith Ġa Ġcomma ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. split (", Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġbag Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBag Ġquantity Ġis Ġthe Ġfirst Ġchar ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġquantity Ġ= Ġbag . first (). toString (). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBag Ġname Ġcomes Ġafter Ġfirst Ġtwo Ġchars Ġand Ġbefore Ġthe Ġword Ġ" bag " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbag Name Ġ= Ġbag . drop ( 2 ). split (" Ġbag "). first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRule ( bag Name , Ġquantity ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠFind Ġthe Ġset Ġof ĠB ags Ġwhich Ġcontain Ġthe Ġtarget Ġbag ĊĠĠĠ Ġfun Ġfind B ags Which Contain ( target : ĠString ): ĠSet < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbags Which Direct ly Contain Ġ= Ġbags . filter Ġ{ Ġbag Ġ-> Ġbag . value . any { Ġcontent Ġ-> Ġcontent . name Ġ== Ġtarget Ġ} Ġ}. keys . toSet () ĊĠĠĠĠĠĠĠ Ġval Ġbags Which Indirect ly Contain Ġ= Ġbags Which Direct ly Contain . flatMap Ġ{ Ġbag Name Ġ-> Ġfind B ags Which Contain ( Ġbag Name Ġ) Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġreturn Ġbags Which Direct ly Contain . union ( b ags Which Indirect ly Contain ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠFind Ġthe Ġset Ġof Ġbags Ġwhich Ġmust Ġbe Ġpacked Ġin Ġthe Ġtarget Ġbag ĊĠĠĠ Ġfun Ġfind B ags Required ( target : ĠString , Ġnum : ĠInt ): ĠList < Pair < String , Int >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrules Ġ= Ġbags [ target ] ĊĠĠĠĠĠĠĠ Ġval Ġadditional B ags Ġ= Ġrules ?. flatMap Ġ{ Ġbag Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind B ags Required ( bag . name , Ġbag . quantity Ġ* Ġnum ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadditional B ags Ġ== Ġnull Ġ-> ĠlistOf ( Pair ( target , Ġnum )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠlistOf ( Pair ( target , Ġnum )) Ġ+ Ġadditional B ags ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġpart One (): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfind B ags Which Contain ( target Bag ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. count () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġpart Two (): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfind B ags Required ( target Bag , Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. fold ( 0 ) Ġ{ Ġacc , Ġpair Ġ-> Ġacc Ġ+ Ġpair . second Ġ} Ġ- Ġ 1 ĊĠĠĠ Ġ} Ċ } ĊĊ