Today's Haskell solution, much longer than yesterday. The parsing was a bit annoying today, but not too bad. Part 1 was very easy. Part 2 was extremely tedious, but at least no performance issues today. I'm still pretty satisfied with my solution and it worked on the first try.
{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE TupleSections #-}moduleMainwhereimportData.ListimportData.MaybeimportqualifiedData.TextasTimportData.CharimportDebug.TraceimportData.BifunctorasBfdataField=FieldString[Int->Bool]typeTicket=[Int]typeTicketWId=[(Int,Int)]--------------------- Part 1 -----------------solve_1::[Int->Bool]->[Ticket]->Intsolve_1fs=foldr((+).foldl(\accn->ifany(\f->fn)fsthenaccelseacc+n)0)0--------------------- Part 2 ------------------- Discards the invalid fields from part 1discardInvalid::[Int->Bool]->[Ticket]->[Ticket]discardInvalidfs=filter(all(\x->any(\f->fx)fs))-- Finds which id's a field can be, for a specific ticketfindValidIdForField::[Int->Bool]->TicketWId->[Int]findValidIdForField[f1,f2]=mapfst.filter(\(i,n)->f1n||f2n)-- Removes valid id's from a field in case another ticket invalidated that idremoveInvalidIds::(Field,[Int])->TicketWId->(Field,[Int])removeInvalidIds(fl@(Fieldnfs),xs)ticket=(fl,xs`intersect`findValidIdForFieldfsticket)-- Finds the valid id's for a fieldfindTicketFields::[(Field,[Int])]->TicketWId->[(Field,[Int])]findTicketFieldsfieldsticket=map(`removeInvalidIds`ticket)fields-- findFields maps each field to which id's they can go tofindFields::[(Field,[Int])]->[TicketWId]->[(String,[Int])]findFieldsflsts=map(\(Fieldn_,i)->(n,i))$foldlfindTicketFieldsflsts-- assignFields will whittle down the id's that a field can go to, -- until all fields have been assigned an id.assignFields::[(String,[Int])]->[(String,Int)]assignFieldsfields=reducesortedwheresorted=sortBy(\(_,xs)(_,ys)->compare(lengthxs)(lengthys))fieldsreduce::[(String,[Int])]->[(String,Int)]reduce[]=[]reduce((n,[x]):xs)=(n,x):reduce(map(Bf.second(filter(/=x)))xs)-- multiplyDeparture finds the final answer.multiplyDeparture::TicketWId->[(String,Int)]->IntmultiplyDeparturemyticketfields=product$mapsnd$filter(\(i,v)->i`elem`depFields)myticketwheredepFields=mapsnd$filter(\(n,_)->"departure"`isPrefixOf`n)fieldssolve_2::[Field]->Ticket->[Ticket]->Intsolve_2fieldreqsmytickettickets=letvalids=discardInvalid(concatMap(\(Field_fs)->fs)fieldreqs)ticketswithId=map(zip[0..])valids::[TicketWId]reqsWIds=map(,[0..length(headvalids)-1])fieldreqs::[(Field,[Int])]inmultiplyDeparture(zip[0..]myticket)$assignFields$findFieldsreqsWIdswithId--------------------- Main & parsing -----------------parseTicket::T.Text->[Int]parseTicket=map((read::String->Int).T.unpack).T.splitOn","parseFieldReq::T.Text->FieldparseFieldReqs=Field(T.unpackname)reqFwhere(name,rest)=T.span(/=':')sreqs=T.splitOn" or "$T.drop2restreqF=map(\s->let[l,u]=T.splitOn"-"sin\n->n>=read(T.unpackl)&&n<=read(T.unpacku))reqsparse::[T.Text]->([Field],Ticket,[Ticket])parsess=(mapparseFieldReqfields,myticket,othertickets)where(fields,rest)=span(/="")ssmyticket=parseTicket$rest!!2othertickets=mapparseTicket$drop5restmain::IO()main=do(fieldreqs,myticket,tickets)<-parse.T.lines.T.pack<$>readFile"input.txt"print$solve_1(concatMap(\(Field_fs)->fs)fieldreqs)ticketsprint$solve_2fieldreqsmytickettickets
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.
Today's Haskell solution, much longer than yesterday. The parsing was a bit annoying today, but not too bad. Part 1 was very easy. Part 2 was extremely tedious, but at least no performance issues today. I'm still pretty satisfied with my solution and it worked on the first try.