day_2.jl (2457B)
1 #!/usr/bin/env julia 2 # https://adventofcode.com/2022/day/2 3 using AdventOfCode 4 using DataFrames 5 6 example = split(""" 7 A Y 8 B X 9 C Z""", "\n") 10 input = readlines("data/day_2.txt") 11 12 # Note that this rearranges the input rows. Not sure if that will be a problem. 13 # Maybe leftjoin needs to be told not to do that? IDK. I don't know if this is 14 # idiomatic Julia at all, I'm basically hacking dplyr into Julia and it's 15 # pretty ugly IMO. 16 function parse_input(input) 17 scores = DataFrame( 18 a = ['A', 'B', 'C'], 19 b = ['X', 'Y', 'Z'], 20 score = 0:2 21 ) 22 input |> 23 x->DataFrame(a = first.(x), b = last.(x)) |> 24 x->leftjoin(x, select(scores, "a", "score" => "score_a"), 25 on = :a) |> 26 x->leftjoin(x, select(scores, "b", "score" => "score_b"), 27 on = :b) |> 28 x->transform(x, 29 [:score_a, :score_b] => 30 ByRow((a, b) -> mod(b-a+1, 3)) => 31 :win_score) |> 32 x->transform(x, 33 [:score_b, :win_score] => 34 ByRow((a, b) -> a + 1 + 3 * b) => 35 :round_score) 36 end 37 38 function part_1(input) 39 sum(parse_input(input)[:, :round_score]) 40 end 41 @assert part_1(example) == 15 42 @info part_1(input) 43 44 # Now that I know what part 2 wants, I'm going to do what I should've done for 45 # part 1 and approach this more efficiently. I'm still going to (over)use data 46 # frames as I get a handle on DataFrames.jl 47 function parse_input_2(input) 48 scores = DataFrame( 49 a = ['A', 'B', 'C'], 50 b = ['X', 'Y', 'Z'], 51 score = 0:2 52 ) 53 input |> 54 x->DataFrame(a = first.(x), b = last.(x)) |> 55 x->groupby(x, [:a, :b]) |> 56 x->combine(x, nrow) |> 57 x->leftjoin(x, select(scores, "a", "score" => "score_a"), 58 on = :a) |> 59 x->leftjoin(x, select(scores, "b", "score" => "score_b"), 60 on = :b) |> 61 x->transform(x, 62 [:score_a, :score_b] => 63 ByRow((a,b)->mod(a+b-1, 3)) => 64 :shape_score) |> 65 x->transform(x, 66 [:nrow, :shape_score, :score_b] => 67 ByRow((a, b, c) -> a * ((b + 1) + 3 * c)) => 68 :round_score) 69 end 70 71 function part_2(input) 72 sum(parse_input_2(input)[:, :round_score]) 73 end 74 @assert part_2(example) == 12 75 @info part_2(input)