advent_of_code_2022

My (attempted) solutions to the 2022 Advent of Code
git clone https://git.eamoncaddigan.net/advent_of_code_2022.git
Log | Files | Refs | README

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)