Advent of Code 2020

12.R 3.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. library(stringr)
  2. library(dplyr)
  3. # Make a dataframe of input, with column 2 as the letter and column 3 as the number
  4. input <- readLines("input12.txt") %>% str_match("^(\\w)(\\d+)$") %>% as.data.frame(stringsAsFactors = FALSE)
  5. names(input) <- c("Orig", "Arg", "Param")
  6. input %>% mutate(
  7. Param = as.numeric(Param), # Make number numeric type
  8. angChange = ifelse(Arg == "R", Param, ifelse(Arg == "L", -Param, 0)), # Calculate what each R/L does to the angle
  9. Angle = cumsum(angChange) %% 360, # Calculate running angle, within 0-359
  10. # Calculate amount to move East, South at each line
  11. MovEast = ifelse(Arg == "E", Param,
  12. ifelse(Arg == "W", -Param,
  13. ifelse(Arg == "F", cos(Angle * pi / 180) * Param, 0))),
  14. MovSouth = ifelse(Arg == "S", Param,
  15. ifelse(Arg == "N", -Param,
  16. ifelse(Arg == "F", sin(Angle * pi / 180) * Param, 0))),
  17. # Running tally of position
  18. PosEast = cumsum(MovEast),
  19. PosSouth = cumsum(MovSouth)
  20. ) -> shipsLog
  21. # Calculate manhattin distance
  22. mandist <- abs(sum(shipsLog$MovEast)) + abs(sum(shipsLog$MovSouth))
  23. # Drop stuff from previous dataframe that wont be used this time
  24. shipsLog %>% select(Orig:Angle) %>%
  25. mutate(
  26. # Calculate the east, south amount being specified by param value
  27. tPMovEast = ifelse(Arg == "E", Param, ifelse(Arg == "W", -Param, 0)),
  28. tPMovSouth = ifelse(Arg == "S", Param, ifelse(Arg == "N", -Param, 0)),
  29. # Convert to a rotating reference frame according to the angle
  30. PMovEast = ifelse(Angle == 0, tPMovEast,
  31. ifelse(Angle == 90, tPMovSouth,
  32. ifelse(Angle == 180, -tPMovEast,
  33. -tPMovSouth))),
  34. PMovSouth = ifelse(Angle == 0, tPMovSouth,
  35. ifelse(Angle == 90, -tPMovEast,
  36. ifelse(Angle == 180, -tPMovSouth,
  37. tPMovEast))),
  38. # Calculate running position of waypoint in rotated frame
  39. PREastPos = cumsum(PMovEast) + 10,
  40. PRSouthPos = cumsum(PMovSouth) - 1,
  41. # Return to original fixed reference frame
  42. PTEastPos = ifelse(Angle == 0, PREastPos,
  43. ifelse(Angle == 90, -PRSouthPos,
  44. ifelse(Angle == 180, -PREastPos,
  45. PRSouthPos))),
  46. PTSouthPos = ifelse(Angle == 0, PRSouthPos,
  47. ifelse(Angle == 90, PREastPos,
  48. ifelse(Angle == 180, -PRSouthPos,
  49. -PREastPos))),
  50. # Calculate movement of ship at each line
  51. ShipMoveEast = ifelse(Arg == "F", Param * PTEastPos, 0),
  52. ShipMoveSouth = ifelse(Arg == "F", Param * PTSouthPos, 0)
  53. ) -> shipsLog2
  54. # Calculate manhattin distance
  55. mandist2 <- abs(sum(shipsLog2$ShipMoveEast)) + abs(sum(shipsLog2$ShipMoveSouth))