My Haskell solution. I created a matrix the size of the input + 7 in each direction and dimension. So the input matrix is in the very middle. Since on 6 cycles it can only grow a maximum of 6 in each direction, I chose 7 because then I can get away with not doing bounds checking. I'm not looping over the outer layer anyways. I also got to use mutable arrays in Haskell, which I recently learned how to use. The part 2 solution was just a copy-paste and adding an extra coordinate. Although I could just have made part 1 take a fourth coordinate but keep it at 0. I also learned that Haskell arrays can handle negative indices just fine, so it was easy to just set the input array at index 0 and then just set the array to be to -7.
importData.ListimportData.ArrayimportData.Array.MArrayimportData.Array.IOimportData.FoldableimportControl.MonadtypePoint=(Int,Int,Int)sumTuple::Point->Point->PointsumTuple(z1,y1,x1)(z2,y2,x2)=(z1+z2,y1+y2,x1+x2)dirs::[Point]dirs=[(z,y,x)|z<-[-1..1],y<-[-1..1],x<-[-1..1],(z,y,x)/=(0,0,0)]neighbours::Point->[Point]neighboursp=map(sumTuplep)dirscount::Char->String->Intcountx=length.filter(==x)newState::ArrayPointChar->Point->MaybeCharnewStatearrpos=letalive=count'#'$map(arr!)$neighboursposcurr=arr!posinifcurr=='#'&&(alive>3||alive<2)thenJust'.'elseifcurr=='.'&&alive==3thenJust'#'elseNothingupdate::ArrayPointChar->IOUArrayPointChar->Point->IO()updateimmutarrmutarrp=forM_(newStateimmutarrp)(writeArraymutarrp)pointsBetween::Point->Point->[Point]pointsBetween(lz,ly,lx)(uz,uy,ux)=[(z,y,x)|z<-[lz..uz],y<-[ly..uy],x<-[lx..ux]]generation::IOUArrayPointChar->IO()generationmutarr=doimmutarr<-freezemutarrlet(l,u)=boundsimmutarrmapM_(updateimmutarrmutarr)$pointsBetween(sumTuple(1,1,1)l)(sumTuple(-1,-1,-1)u)countAlive::ArrayPointChar->IntcountAliveimmutarr=let(l,u)=boundsimmutarrinfoldl(\accp->ifimmutarr!p=='#'thenacc+1elseacc)0$pointsBetween(sumTuple(1,1,1)l)(sumTuple(-1,-1,-1)u)main::IO()main=doinput<-lines<$>readFile"input.txt"-- Part 1: 448letc=7width=length(headinput)+1height=lengthinput+1-- Using (z,y,x) format since that makes it print correctlymutarr<-newArray((-c,-c,-c),(c,height+c,width+c))'.'::IO(IOUArrayPointChar)letinit=[(e,(x,y))|(y,es)<-zip[0..]input,(x,e)<-zip[0..](input!!y)]mapM_(\(e,(x,y))->writeArraymutarr(0,y,x)e)initreplicateM_6(generationmutarr)immutarr<-freezemutarr::IO(ArrayPointChar)-- print immutarrprint$countAliveimmutarr
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 created a matrix the size of the input + 7 in each direction and dimension. So the input matrix is in the very middle. Since on 6 cycles it can only grow a maximum of 6 in each direction, I chose 7 because then I can get away with not doing bounds checking. I'm not looping over the outer layer anyways. I also got to use mutable arrays in Haskell, which I recently learned how to use. The part 2 solution was just a copy-paste and adding an extra coordinate. Although I could just have made part 1 take a fourth coordinate but keep it at 0. I also learned that Haskell arrays can handle negative indices just fine, so it was easy to just set the input array at index 0 and then just set the array to be to -7.