advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git
commit 76506c1d5fcdaf4de152016aa0fdf23b7ec81526
parent 41ab46a9750e334ef3457cfd80cff18a58009a1f
Author: Shimmy Xu <shimmy.xu@shimmy1996.com>
Date:   Tue,  3 Dec 2019 11:58:28 -0500

Add Julia solution for day 03

Diffstat:
Aday-03/day-03.jl | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+), 0 deletions(-)
diff --git a/day-03/day-03.jl b/day-03/day-03.jl
@@ -0,0 +1,105 @@
+function build_path(ops)
+    path = map(ops) do op
+        steps = parse(Int, op[2:end])
+        if op[1] == 'R'
+             [steps, 0]
+        elseif op[1] == 'L'
+             [-steps, 0]
+        elseif op[1] == 'U'
+            [0, steps]
+        else
+            [0, -steps]
+        end
+    end
+    path = cumsum(path)
+    insert!(path, 1, sign.(path[1]))
+    path
+end
+
+function build_steps(ops)
+    steps = cumsum(map(op -> parse(Int, op[2:end]),ops))
+    insert!(steps, 1, 1)
+    steps
+end
+
+function get_min_intersection(p1a, p1b, p2a, p2b)
+    rotated = false
+    if p1a[1] != p1b[1]
+        p1a = [p1a[2], p1a[1]];
+        p1b = [p1b[2], p1b[1]];
+        p2a = [p2a[2], p2a[1]];
+        p2b = [p2b[2], p2b[1]];
+        rotated = true;
+    end
+    res = nothing
+    if p2a[1] == p2b[1]
+        # Parallel case.
+        if p1a[1] == p2a[1]
+            cross_start = max(p1a[2], p2a[2])
+            cross_end = min(p1b[2], p2b[2])
+            if cross_start <= cross_end
+                if cross_start * cross_end <= 0
+                    res = [p1a[1], 0]
+                else
+                    if abs(cross_start) <= abs(cross_end)
+                        res = [p1a[1], cross_start]
+                    else
+                        res = [p1a[1], cross_end]
+                    end
+                end
+            end
+        end
+    else
+        # Vertical case.
+        if (p1a[1] - p2a[1]) * (p1a[1] - p2b[1]) <= 0 &&
+            (p2a[2] - p1a[2]) * (p2a[2] - p1b[2]) <= 0
+            res = [p1a[1], p2a[2]]
+        end
+    end
+    if rotated && res != nothing
+        res = [res[2], res[1]]
+    end
+    res
+end
+
+function part_1(input)
+    path_1 = build_path(input[1])
+    path_2 = build_path(input[2])
+    min_dist = Inf
+    for i = 2:length(path_1)
+        for j = 2:length(path_2)
+            min_cross = get_min_intersection(path_1[i - 1], path_1[i], path_2[j - 1], path_2[j])
+            if !isnothing(min_cross)
+                min_dist = min(min_dist, sum(abs.(min_cross)))
+            end
+        end
+    end
+    Int(min_dist)
+end
+
+function part_2(input)
+    path_1 = build_path(input[1])
+    path_2 = build_path(input[2])
+    steps_1 = build_steps(input[1])
+    steps_2 = build_steps(input[2])
+    min_steps = Inf
+    for i = 2:length(path_1)
+        for j = 2:length(path_2)
+            min_cross = get_min_intersection(path_1[i - 1], path_1[i], path_2[j - 1], path_2[j])
+            if !isnothing(min_cross)
+                step_1 = steps_1[i - 1] + sum(abs.(min_cross - path_1[i - 1]))
+                step_2 = steps_2[j - 1] + sum(abs.(min_cross - path_2[j - 1]))
+                min_steps = min(min_steps, step_1 + step_2)
+            end
+        end
+    end
+    Int(min_steps)
+end
+
+input = map(readlines(open("input.txt"))) do line
+    split(strip(line), ',')
+end
+
+println("Julia:")
+println("Part 1: ", part_1(input))
+println("Part 2: ", part_2(input))