My Haskell solution. I realized regex would be useful, but I didn't find any built-in regex in Haskell, so I went for the parser approach instead. Using a parser library like Parsec would also have been an option, but I couldn't bother installing and spending time learning it just for this. So I made my own shitty parser combinator. Then a little hacky solution for part 2.
{-# LANGUAGE LambdaCase #-}moduleMainwhereimportqualifiedData.MapasMapimportData.MaybeimportData.BifunctorasBfimportControl.ApplicativeimportControl.MonaddataRule=Or[Int][Int]|Then[Int]|ConstantChar-- I know this generic `a` doesn't make much sense. I just wanted the Monoid stuff.newtypeRuleParsera=RuleParser(String->MaybeString)instanceSemigroup(RuleParsera)where(RuleParserp1)<>(RuleParserp2)=RuleParser$\s->p1s<|>(p2s<|>Nothing)instanceMonoid(RuleParsera)wheremempty=RuleParserJustpThen::RuleParsera->RuleParsera->RuleParserapThen(RuleParserp1)(RuleParserp2)=RuleParser(p1>=>p2)pConstant::Char->RuleParserapConstantc=RuleParser$\case""->Nothing(x:xs)->ifx==cthenJustxselseNothingrunParser::RuleParsera->String->MaybeStringrunParser(RuleParserp)=pparseN::RuleParsera->Int->RuleParseraparseNpn=foldl(\acc_->acc`pThen`p)mempty[1..n]isValidRule::RuleParsera->String->BoolisValidRuleps=caserunParserpsofJust[]->True;_->FalsegetRule::Ordk=>Map.Mapka->k->agetRulemappingi=fromJust$Map.lookupimappinggetParser::Map.MapIntRule->Rule->RuleParseragetParserr(Orxsys)=foldl(\acci->acc`pThen`getParserr(getRuleri))memptyxs<>foldl(\acci->acc`pThen`getParserr(getRuleri))memptyysgetParserr(Thenxs)=foldl(\acci->acc`pThen`getParserr(getRuleri))memptyxsgetParserr(Constantc)=pConstantc-- For part 2, try parsing 8 an increasing amount of times -- until 11 successfully parses or until 8 fails.createParser::Bool->Map.MapIntRule->RuleParseracreateParserisPart1r=ifisPart1thengetParserr$fromJust$Map.lookup0relseRuleParser$\s->tryParsenEightsswherenEights=map(parseN(getParserr(getRuler42)))[1..]pEleven=getParserr(getRuler11)tryParse(p:ps)s=caserunParserpsofJustrest->caserunParserpElevenrestofJust""->Just""_->tryParsepss_->NothingparseInput::String->(Int,Rule)parseInputs=ifr2==""thenif'\"'`elem`r1then(num,Constant(r1!!2))elseletrule=read<$>wordsr1in(num,Thenrule)elseletrs1=read<$>wordsr1rs2=read<$>wordsr2in(num,Orrs1rs2)where(num,rules)=Bf.bimap(read::String->Int)tail$span(/=':')s(r1,r2)=Bf.second(drop1)$span(/='|')rulesparse::[String]->(Map.MapIntRule,[String])parsess=(rulemap,msgs)where(rules,msgs)=Bf.secondtail$span(/="")ssrulemap=Map.fromList$mapparseInputrulesmain::IO()main=do(rules,msgs)<-parse.lines<$>readFile"input.txt"letp1=createParserTruerulesprint$length$filter(==True)$map(isValidRulep1)msgs(rules,msgs)<-parse.lines<$>readFile"input2.txt"letp2=createParserFalserulesprint$length$filter(==True)$map(isValidRulep2)msgs
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
My Haskell solution. I realized regex would be useful, but I didn't find any built-in regex in Haskell, so I went for the parser approach instead. Using a parser library like Parsec would also have been an option, but I couldn't bother installing and spending time learning it just for this. So I made my own shitty parser combinator. Then a little hacky solution for part 2.