Ahh... that's better... More Sealed Classes/Discriminated Unions to the rescue. Managed to cut a lot of duplicated code out.
importDay10.destructionimportDay10.mostVisibleimportarrow.core.andThenimportjava.nio.file.Filesimportjava.nio.file.Pathsimportkotlin.math.PIimportkotlin.math.absimportkotlin.math.atanimportkotlin.math.powimportkotlin.math.sqrtdata classPoint(valx:Int,valy:Int)privatefunPoint.slope(b:Point)=(y-b.y).toDouble()/(x-b.x).toDouble()privatefunPoint.distance(b:Point)=sqrt(abs(x.toDouble()-b.x.toDouble()).pow(2.0)+abs(y.toDouble()-b.y.toDouble()).pow(2.0))privatefunPoint.anglePair(entry:Map.Entry<EuclideanGrouping,List<Point>>)=entry.key.anglePair(this,entry.value)privatefunPoint.countByGroup(entry:Map.Entry<EuclideanGrouping,List<Point>>)=entry.key.count(this,entry.value)sealedclassEuclideanGroupingobjectDown:EuclideanGrouping()objectDownLeft:EuclideanGrouping()objectDownRight:EuclideanGrouping()objectLeft:EuclideanGrouping()objectRight:EuclideanGrouping()objectUp:EuclideanGrouping()objectUpLeft:EuclideanGrouping()objectUpRight:EuclideanGrouping()funPoint.mapEuclideanGroup(other:Point):EuclideanGrouping{returnwhen{other.x>x&&other.y>y->DownRightother.x>x&&other.y<y->UpRightother.x>x&&other.y==y->Rightother.x<x&&other.y>y->DownLeftother.x<x&&other.y<y->UpLeftother.x<x&&other.y==y->Leftother.x==x&&other.y>y->Downother.x==x&&other.y<y->Upelse->throwError("Invalid point comparison: $this to $other")}}funPoint.sortByDistanceFromKeyValue(entry:Map.Entry<Double,List<Point>>)=entry.keytoentry.value.sortedBy(this::distance)funPoint.radiansConverter(offset:Double)={p:Point->(atan(p.slope(this))+offset)}privatefunEuclideanGrouping.anglePair(station:Point,list:List<Point>)=when(this){Up->listOf(0.0tolist)Down->listOf(PItolist)DownLeft,UpLeft->list.groupBy(station.radiansConverter(3*PI/2)).map(station::sortByDistanceFromKeyValue).toList()DownRight,UpRight->list.groupBy(station.radiansConverter(PI/2)).map(station::sortByDistanceFromKeyValue).toList()Left->listOf(3*PI/2tolist)Right->listOf(PI/2tolist)}funEuclideanGrouping.count(station:Point,list:List<Point>)=when(this){Up,Down,Left,Right->list.take(1).count()DownLeft,DownRight,UpLeft,UpRight->list.groupBy{station.slope(it)}.count{(_,v)->v.any()}}objectDay10{privateconstvalFILENAME="src/main/resources/day10.txt"valfileData=Files.readAllLines(Paths.get(FILENAME)).onlyAsteroids()privatefunList<String>.onlyAsteroids()=mapIndexed{y,row->row.mapIndexed{x,c->Point(x,y)toc}}.flatten().filter(Pair<Point,Char>::secondandThen'#'::equals).map(Pair<Point,Char>::first)funmostVisible(data:List<Point>)=data.map{station->stationtodata.asSequence().filterNot(station::equals).groupBy(station::mapEuclideanGroup).asSequence().sumBy(station::countByGroup)}.maxBy{it.second}fundestruction(data:List<Point>):Int{valstation=Point(20,20)valgroupedAsteroids=data.asSequence().filterNot(station::equals).groupBy(station::mapEuclideanGroup).flatMap(station::anglePair)valinitial=emptyList<Point>()togroupedAsteroids.sortedBy{it.first}return(0..(groupedAsteroids.maxBy{it.second.size}?.second?.size?:0)).fold(initial){(destroyed,remaining),_->valnextDestroyed=destroyed+remaining.flatMap{(_,list)->list.take(1)}valnextRemaining=remaining.map{(angle,list)->angletolist.drop(1)}nextDestroyedtonextRemaining}.first[199].let{it.x*100+it.y}}}funmain(){println(mostVisible(Day10.fileData))println(destruction(Day10.fileData))}
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.
Ahh... that's better... More Sealed Classes/Discriminated Unions to the rescue. Managed to cut a lot of duplicated code out.