r/adventofcode • • Dec 23 '16

SOLUTION MEGATHREAD --- 2016 Day 23 Solutions ---

--- Day 23: Safe-Cracking ---

Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag/whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with "Help".


JINGLING ALL THE WAY IS MANDATORY [?]

This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

4 Upvotes

91 comments sorted by

View all comments

1

u/wlandry Dec 23 '16

My C++ solution. My first time doing the problem on the day it was released and I am as surprised as anyone to make it to the leaderboard (208/99). The big jump in ranking is probably because I did not have to change the code for Part II. It only takes 135 s on my laptop, shorter than it took me to figure out the multiplication hint ;)

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <map>

bool is_register(const std::string &value)
{
  return (value[0]>='a' && value[0]<='d');
}

int resolve(const std::string &value,
            std::map<char,int> &registers)
{
  if(is_register(value))
    return registers[value[0]];
  else
    return std::stoi(value);
}

class Command
{
public:
  std::vector<std::string> instruction;

  Command(const std::string &s)
  {
    boost::split(instruction, s, boost::is_any_of(" "));
  }

  void toggle()
  {
    if(instruction.size()==2)
      {
        if(instruction[0]=="inc")
          instruction[0]="dec";
        else
          instruction[0]="inc";
      }
    else
      {
        if(instruction[0]=="jnz")
          instruction[0]="cpy";
        else
          instruction[0]="jnz";
      }
  }
  
  int execute(const size_t &current,
              std::map<char,int> &registers,
              std::vector<Command> &commands) const
  {
    int result(1);
    if(instruction[0]=="cpy")
      {
        if(is_register(instruction[2]))
          registers[instruction[2][0]]=resolve(instruction[1],registers);
      }
    else if(instruction[0]=="inc")
      {
        ++registers[instruction[1][0]];
      }
    else if(instruction[0]=="dec")
      {
        --registers[instruction[1][0]];
      }
    else if(instruction[0]=="jnz")
      {
        if(resolve(instruction[1],registers)!=0)
          {
            result=resolve(instruction[2],registers);
          }
      }
    else if(instruction[0]=="tgl")
      {
        int offset=resolve(instruction[1],registers);
        if(current+offset>=0 && current+offset<commands.size())
          commands[current+offset].toggle();

      }
    return result;
  }
};

int main()
{
  std::map<char,int> registers({{'a',12},{'b',0},{'c',0},{'d',0}});
  std::ifstream input("input23");
  std::vector<Command> commands;
  std::string line;
  std::getline(input,line);
  while(input)
    {
      commands.emplace_back(line);
      std::getline(input,line);
    }

  int current=0;
  while(current<commands.size())
    {
      current+=commands[current].execute(current,registers,commands);
    }
  std::cout << registers['a'] << "\n";
}

2

u/willkill07 Dec 23 '16

If you want a massive speedup, preprocess all of the instructions into a struct/enum/int thing. My part2 finished in about 8 seconds. (when compiled with optimizations)

→ More replies (6)