Advent of Code 2019 - Day 2

Good idea. I have edited the first post.

I went pretty naive with my solution: https://github.com/sb8244/advent-of-code-2019/blob/master/lib/two.ex

I’m going for speed to solve (124 pt 2), so end up with whatever popped in my head first. I am surprised with whatever I did that caused part 2 to solve in < 500ms though, given what I’ve heard about others taking 2s. The speed difference may have to do with my use of maps rather than lists. I learned last year that, essentially, I should always use Map for these problems.

I fully expect this solution to evolve significantly in future challenges—as the problem statement hinted at. In particular, I expect this to quickly evolve into an interpreter that supports loops and conditionals, which is where they’ll throw in performance doozies.

1 Like

My solution, in Erlang:

7 Likes

Thanks for sharing your solutions here :slight_smile: I got part 2 down to about 50ms on my machine after removing a stupid misstake where I was executing the ā€œprogramā€ twice for every multiplication…

I came up with more or less the same solution as you guys did :slight_smile:

I need to look at some of the other solutions posted but my first go at it is at https://github.com/simon-wolf/advent-of-code-2019/tree/master/day_02

As ever I tend to veer towards verbosity but hopefully readability.

I still have an awful lot to learn about constructing efficient algorithms.

1 Like

Usually I just hack some code together, hopefully fast enough to fit lunchtime, only if it’s taking longer than a couple of seconds on the computer I’m doing the exercises on, I try to optimise in the afternoon after office hours and when the kids are in bed.

But the primary goal is just to get those 2 stars…

3 Likes

Hi there! Here is my repo with day1 and day2 solutions :slight_smile:

This looks like a good opportunity to study some code!

I’m solving advent of code using elixir for the fifth year in a row now :open_mouth:
Here’s my day 2 solution.


I generally try to minimise nesting and stick to pipes when possible. That went fine today :+1:

I’m thinking about (prematurely) optimize to use maps in preparation for a future puzzle that might reuse this code. @martin mentioned on slack that he got it 3x faster by switching to a map.

1 Like

You could use throw to early return like @cblavier https://github.com/cblavier/advent-2019/blob/master/lib/day2/part2.ex#L14-18 Or use a stream like Sasa showed: Advent of Code 2019 - Day 2

1 Like

My solution.

2 Likes

I’m continuing to write really ugly Gleam code - but it works so far :man_shrugging:

4 Likes

Thanks for sharing! Watching the entire progress is such enjoyment and I learned a lot from the video. There were several times I stop and check the things I didn’t know before. And the way you debug is even more worthy to watch. Please share more when available! :smile:

2 Likes

My solution is here… https://github.com/evantravers/adventofcode/tree/master/2019/elixir/lib/day02

I’m sure my computer code looks really similar to everyone else’s, but I was really pleased with breaking out of the comprehension using the throw catch syntax:

  def p2(input) do
    try do
      for noun <- 0..99, verb <- 0..99 do
        result =
          input
          |> Map.put(1, noun)
          |> Map.put(2, verb)
          |> Intcode.run

        if result == 19690720 do
          throw({:break, (100 * noun + verb)})
        end
      end
    catch
      {:break, result} -> result
    end
  end

Not sure my solution is idomatic but it works pretty well and I had fun writing it. Any tips?

defmodule Solutions.Day2 do
  @opcode_add 1
  @opcode_multiply 2

  def execute_intcode(ints, pos_ptr \\ 0) do
    # take 4, [operator, first value, second value, save register]
    case Enum.slice(ints, pos_ptr, 4) do
      [@opcode_add, first, second, register] ->
        result = Enum.fetch!(ints, first) + Enum.fetch!(ints, second)
        execute_intcode(List.replace_at(ints, register, result), pos_ptr + 4)

      [@opcode_multiply, first, second, register] ->
        result = Enum.fetch!(ints, first) * Enum.fetch!(ints, second)
        execute_intcode(List.replace_at(ints, register, result), pos_ptr + 4)

      [99 | _] ->
        ints
    end
  end

  def patch_intcode(ints, pos_one, pos_two) do
    ints
    |> List.replace_at(1, pos_one)
    |> List.replace_at(2, pos_two)
  end

  def result(intcode, pos_one, pos_two) do
    [result | _] =
      intcode
      |> patch_intcode(pos_one, pos_two)
      |> execute_intcode

    result
  end

  def part_1(intcode) do
    result(intcode, 12, 2)
  end

  def part_2(intcode) do
    answer = []
    valid_inputs = for noun <- 0..99,
      verb <- 0..99,
      result(intcode, noun, verb) == 19690720,
      do: {noun, verb}

    {noun, verb} = hd valid_inputs

    100 * noun + verb
  end

  def answer(input) do
    list = String.split(input, ",")

    int_list =
      Enum.map(
        list,
        fn el -> String.to_integer(el) end
      )

    IO.puts(part_1(int_list))
    IO.puts(part_2(int_list))
  end

  def answer do
    contents = File.read!("priv/day_2_input.txt")
    answer(String.trim(contents))
  end
end

My solution to Day 2

My solution for day 2

My solution here: https://github.com/trbngr/advent_of_code/blob/master/lib/advent_of_code/2019/day02.ex

I’m really surprised that I seem to be one of the few people that used structs by following the directions pretty dang literally. lol

I’m sure my use of List functions slow this down quite a bit. But I spent way more time that I had planned to and I’m spent.

My solution for day 2

The part2 solution that I use rand.uniform/1 to generate the candidate pairs.

I’m somewhat late to the party, but here’s one in Gleam!

1 Like