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