Last active
January 28, 2019 21:50
-
-
Save marekciupak/27dbe48d3f011129b905865e3a86fc61 to your computer and use it in GitHub Desktop.
Day 3 Part 1 - Advent of Code 2017
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Day3 do | |
require Integer | |
def part1(location) do | |
width = width(location) | |
steps = steps(location, width) | |
distance(steps, width) | |
end | |
def width(location) do | |
:math.sqrt(location - 1) | |
|> trunc() | |
|> floor_to_odd() | |
|> Kernel.+(1) | |
end | |
defp steps(location, width) do | |
location - (width - 1) * (width - 1) | |
end | |
defp floor_to_odd(integer) when Integer.is_odd(integer), do: integer | |
defp floor_to_odd(integer) when Integer.is_even(integer), do: integer - 1 | |
def distance(steps, width) do | |
distance_to_the_perimeter(width) + distance_on_the_perimeter(steps, width) | |
end | |
defp distance_to_the_perimeter(width), do: div(width, 2) | |
def distance_on_the_perimeter(0, 0), do: 0 | |
def distance_on_the_perimeter(steps, width) do | |
steps | |
|> rem(width) | |
|> distance_on_the_side(width) | |
end | |
def distance_on_the_side(steps, width) do | |
abs(steps - div(width, 2)) | |
end | |
end | |
defmodule Day3Test do | |
use ExUnit.Case | |
test "calculates answers for part 1" do | |
assert Day3.part1(1) == 0 | |
assert Day3.part1(12) == 3 | |
assert Day3.part1(23) == 2 | |
assert Day3.part1(1024) == 31 | |
end | |
# 17 16 15 14 13 | |
# 18 . . . 12 | |
# 19 . . . 11 | |
# 20 . . . 10 | |
# 21 22 23 24 25 | |
# | |
# 16 / 4 = 4 = width | |
# | |
test "calculates the width (number of locations in the square divided by 4) based on the given location" do | |
assert Day3.width(1) == 0 | |
assert Day3.width(2) == 2 | |
assert Day3.width(9) == 2 | |
assert Day3.width(10) == 4 | |
assert Day3.width(25) == 4 | |
assert Day3.width(26) == 6 | |
assert Day3.width(49) == 6 | |
assert Day3.width(50) == 8 | |
end | |
# Day3.distance(steps, width) | |
# | |
# Example for width = 6 and steps: | |
# | |
# 12 11 10 9 8 7 6 | |
# 13 5 | |
# 14 4 | |
# 15 3 | |
# 16 2 | |
# 17 1 | |
# 18 19 20 21 22 23 24 | |
# | |
# => | |
# | |
# 6 5 4 3 4 5 6 | |
# 5 5 | |
# 4 4 | |
# 3 3 | |
# 4 4 | |
# 5 5 | |
# 6 5 4 3 4 5 6 | |
# | |
test "calculates the distance from the center of the spiral based on steps and width" do | |
assert Day3.distance(5, 6) == 5 | |
end | |
# Day3.distance_on_the_perimeter(steps, width) | |
# | |
# Example for width = 6 and steps: | |
# | |
# 12 11 10 9 8 7 6 | |
# 13 5 | |
# 14 4 | |
# 15 3 | |
# 16 2 | |
# 17 1 | |
# 18 19 20 21 22 23 24 | |
# | |
# => | |
# | |
# 3 2 1 0 1 2 3 | |
# 2 2 | |
# 1 1 | |
# 0 0 | |
# 1 1 | |
# 2 2 | |
# 3 2 1 0 1 2 3 | |
# | |
test "calculates the distance from the center of the side of the square based on steps and width" do | |
assert Day3.distance_on_the_perimeter(2, 2) == 1 | |
assert Day3.distance_on_the_perimeter(1, 6) == 2 | |
assert Day3.distance_on_the_perimeter(2, 6) == 1 | |
assert Day3.distance_on_the_perimeter(3, 6) == 0 | |
assert Day3.distance_on_the_perimeter(4, 6) == 1 | |
assert Day3.distance_on_the_perimeter(5, 6) == 2 | |
assert Day3.distance_on_the_perimeter(6, 6) == 3 | |
assert Day3.distance_on_the_perimeter(7, 6) == 2 | |
assert Day3.distance_on_the_perimeter(8, 6) == 1 | |
assert Day3.distance_on_the_perimeter(9, 6) == 0 | |
assert Day3.distance_on_the_perimeter(10, 6) == 1 | |
assert Day3.distance_on_the_perimeter(24, 6) == 3 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment