There are (at least) two ways to "model" the solution: polar coordinates or vector/gonio math. Here is a Ruby OOP solution using the latter:
require'benchmark'classShipattr_reader:positiondefinitializeself.facing=90self.position=Position.new(0,0)self.waypoint=Waypoint.newenddefsail!(instruction)caseinstruction.actionwhen'N'position.translate!(0,-instruction.value)when'S'position.translate!(0,instruction.value)when'E'position.translate!(instruction.value,0)when'W'position.translate!(-instruction.value,0)when'L'self.facing=(self.facing-instruction.value)%360when'R'self.facing=(self.facing+instruction.value)%360when'F'direction=%w[N E S W][facing/90]sail!instruction.with_action(direction)# input only contains 90 180 270 so no need for# SOS Castoa (gonio).endenddefsail_with_waypoint!(instruction)if%w[N S E W L R].include?(instruction.action)waypoint.sail!instructionreturnenddx,dy=waypoint.position.difference(Position.new(0,0))self.position.translate!(dx*instruction.value,dy*instruction.value)endprivateattr_accessor:facing,:waypointattr_writer:positionendclassWaypointattr_reader:positiondefinitializeself.position=Position.new(10,-1)enddefsail!(instruction)caseinstruction.actionwhen'N'position.translate!(0,-instruction.value)when'S'position.translate!(0,instruction.value)when'E'position.translate!(instruction.value,0)when'W'position.translate!(-instruction.value,0)when'L'theta=-(instruction.value/180.to_f*Math::PI)self.position=Position.new((position.x*Math.cos(theta)-position.y*Math.sin(theta)).round,(position.x*Math.sin(theta)+position.y*Math.cos(theta)).round)when'R'theta=instruction.value/180.to_f*Math::PIself.position=Position.new((position.x*Math.cos(theta)-position.y*Math.sin(theta)).round,(position.x*Math.sin(theta)+position.y*Math.cos(theta)).round)endendprivateattr_accessor:facingattr_writer:positionendclassInstructionattr_reader:action,:valuedefinitialize(action,value)self.action=actionself.value=value.to_ienddefwith_action(new_action)Instruction.new(new_action,value)endprivateattr_writer:action,:valueendclassPositionattr_reader:x,:ydefinitialize(x,y)self.x=xself.y=yenddeftranslate!(x,y)self.x+=xself.y+=yselfenddefdistance(other)difference(other).map(&:abs).sumenddefdifference(other)[x-other.x,y-other.y]endprivateattr_writer:x,:yendmoduleNavigationInstructionsdefself.from_lines(lines)lines.mapdo|line|line=line.chompInstruction.new(line[0],line[1..])endendenddeftrack(ship)original=ship.position.dupyieldoriginal.distance(ship.position)endsource='input.txt'instructions=NavigationInstructions.from_lines(File.readlines(source))verbose=falseBenchmark.bmbmdo|x|x.report(:part_1)doship=Ship.newdistance=track(ship)doinstructions.eachdo|instruction|ship.sail!instructionputs"[ahoy] #{instruction.action} by #{instruction.value}: #{ship.position.x}, #{ship.position.y}"ifverboseendendputsdistanceendx.report(:part_2)doship=Ship.newdistance=track(ship)doinstructions.eachdo|instruction|ship.sail_with_waypoint!instructionputs"[ahoy] #{instruction.action} by #{instruction.value}: #{ship.position.x}, #{ship.position.y}"ifverboseendendputsdistanceendend
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.
There are (at least) two ways to "model" the solution: polar coordinates or vector/gonio math. Here is a Ruby OOP solution using the latter: