day-03-solution.R

#-------------------------------------------------------------------------------
# Load libraries
#-------------------------------------------------------------------------------

# Clear console
cat("\014")

# Load the crud library
devtools::load_all()
devtools::document()

# Load external packages
pckgs <- c("here", "tidyverse", "magrittr")
adventofcode2017::ipak(pckgs)

# Data directory
DATA_DIR <- file.path(here::here(), "tests/testthat/data")

#-------------------------------------------------------------------------------
# Exercise Day 03-01 Solution
#-------------------------------------------------------------------------------

new_corners <- function(n){
    new_corners_val <- c("BR" = complex(real = n, imaginary = -n)
                         , "TR" = complex(real = n, imaginary = n)
                         , "TL" = complex(real = -n, imaginary = n)
                         , "BL" = complex(real = -n, imaginary = -n))
}

increments <- c("R" = complex(real = 0, imaginary = 1)
                , "T" = complex(real = -1, imaginary = 0)
                , "L" = complex(real = 0, imaginary = -1)
                , "B" = complex(real = 1, imaginary = 0))

get_prev_int_sqrt <- function(int_val){
    # Coerce input value to an integer
    int_val <- base::as.integer(int_val)
    get_int_sqrt <- as.integer(floor(sqrt(int_val)))

    # Check if it is a perfect square
    chk_square <- (base::sqrt(int_val) == get_int_sqrt)
    is_odd     <- (get_int_sqrt %% 2 == 1)

    if(chk_square && is_odd){
        out_val <- get_int_sqrt - 2
    } else if(is_odd){
        out_val <- get_int_sqrt
    } else {
        out_val <- get_int_sqrt - 1
    }

    base::return(out_val)
}

get_spiral_pos <- function(inp_val){
    MAX_ROTS  <- 4
    MIN_STEPS <- 0

    # Get the whole number (integer) of spirals created up to the current value
    prev_int_sqrt_inp <- get_prev_int_sqrt(int_val = inp_val)
    prev_int_sqrt_inp

    # Get the whole number (integer) of spirals for the current value
    curr_int_sqrt_inp <- prev_int_sqrt_inp + 2
    curr_int_sqrt_inp

    # Radius of spiral in previous iteration to our input value spiral radius
    prev_spiral_rad <- as.integer((prev_int_sqrt_inp - 1)/2)
    prev_spiral_rad

    # Radius of spiral of our input value
    curr_spiral_rad <- prev_spiral_rad + 1
    curr_spiral_rad

    # Get the number of full rotations of the new spiral
    max_diff_steps <- inp_val - prev_int_sqrt_inp**2
    max_diff_steps

    # Number of new spiral lengths to rotate (quotient)
    curr_spiral_rots <- max_diff_steps %/% (curr_int_sqrt_inp - 1)
    curr_spiral_rots

    # Number of steps (remainder) to take on new spiral after completing whole rotations
    num_new_spir_steps <- max_diff_steps %% (curr_int_sqrt_inp - 1)
    num_new_spir_steps

    # Get the current spiral corners
    curr_spiral_corners <- new_corners(curr_spiral_rad)
    curr_spiral_corners

    inp_val
    max_diff_steps
    curr_spiral_rots
    num_new_spir_steps

    # Get the coordinate of the current input value
    if((curr_spiral_rots == MAX_ROTS && num_new_spir_steps == MIN_STEPS)){
        out_val <- curr_spiral_corners["BR"]}
    else {
        out_val <-
            curr_spiral_corners[curr_spiral_rots + 1] +
            num_new_spir_steps*increments[curr_spiral_rots + 1]
            }

    out_val <- base::unname(out_val)
    out_vars <- c("position" = out_val
                  , "manhattan_dist" = as.integer(
                                        base::Re(abs(base::Re(out_val)) +
                                        abs(base::Im(out_val)))))
    base::return(out_vars)
}

get_spiral_pos(inp_val = 325489)
shamindras/adventofcode2017 documentation built on May 14, 2019, 7:37 a.m.