MENU

December 8, 2021

2021 Advent of Code Day 6 Solution

Introduction

Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language in numerous different ways. In this post I will be outlining the solutions I wrote for the Day 6 problems, called "Lanternfish", written in C++ so that others may learn from this post based on my code as well as find help in creating their own solutions to the issue and grasping the concepts of what the code is doing to reach the end goal.

Part 1

The problem states:

Although you know nothing about this specific species of lanternfish, you make some guesses about their attributes. Surely, each lanternfish creates a new lanternfish once every 7 days.

However, this process isn't necessarily synchronized between every lanternfish - one lanternfish might have 2 days left until it creates another lanternfish, while another might have 4. So, you can model each fish as a single number that represents the number of days until it creates a new lanternfish.

Furthermore, you reason, a new lanternfish would surely need slightly longer before it's capable of producing more lanternfish: two more days for its first cycle.

So, suppose you have a lanternfish with an internal timer value of 3:

  • After one day, its internal timer would become 2.
  • After another day, its internal timer would become 1.
  • After another day, its internal timer would become 0.
  • After another day, its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8.
  • After another day, the first lanternfish would have an internal timer of 5, and the second lanternfish would have an internal timer of 7.
  • A lanternfish that creates a new fish resets its timer to 6, not 7 (because 0 is included as a valid timer value). The new lanternfish starts with an internal timer of 8 and does not start counting down until the next day.

Realizing what you're trying to do, the submarine automatically produces a list of the ages of several hundred nearby lanternfish (your puzzle input). For example, suppose you were given the following list:

3,4,3,1,2
This list means that the first fish has an internal timer of 3, the second fish has an internal timer of 4, and so on until the fifth fish, which has an internal timer of 2. Simulating these fish over several days would proceed as follows:

Initial state: 3,4,3,1,2
After  1 day:  2,3,2,0,1
After  2 days: 1,2,1,6,0,8
After  3 days: 0,1,0,5,6,7,8
After  4 days: 6,0,6,4,5,6,7,8,8
After  5 days: 5,6,5,3,4,5,6,7,7,8
After  6 days: 4,5,4,2,3,4,5,6,6,7
After  7 days: 3,4,3,1,2,3,4,5,5,6
After  8 days: 2,3,2,0,1,2,3,4,4,5
After  9 days: 1,2,1,6,0,1,2,3,3,4,8
After 10 days: 0,1,0,5,6,0,1,2,2,3,7,8
After 11 days: 6,0,6,4,5,6,0,1,1,2,6,7,8,8,8
After 12 days: 5,6,5,3,4,5,6,0,0,1,5,6,7,7,7,8,8
After 13 days: 4,5,4,2,3,4,5,6,6,0,4,5,6,6,6,7,7,8,8
After 14 days: 3,4,3,1,2,3,4,5,5,6,3,4,5,5,5,6,6,7,7,8
After 15 days: 2,3,2,0,1,2,3,4,4,5,2,3,4,4,4,5,5,6,6,7
After 16 days: 1,2,1,6,0,1,2,3,3,4,1,2,3,3,3,4,4,5,5,6,8
After 17 days: 0,1,0,5,6,0,1,2,2,3,0,1,2,2,2,3,3,4,4,5,7,8
After 18 days: 6,0,6,4,5,6,0,1,1,2,6,0,1,1,1,2,2,3,3,4,6,7,8,8,8,8

Each day, a 0 becomes a 6 and adds a new 8 to the end of the list, while each other number decreases by 1 if it was present at the start of the day.

In this example, after 18 days, there are a total of 26 fish. After 80 days, there would be a total of 5934.

Find a way to simulate lanternfish. How many lanternfish would there be after 80 days?

The input provided by Advent of Code is different for each participant in order to keep the solution unique for each person. For this problem, it is a single line of code that has 300 single digit numbers separated by commas on it. For this solution fstream was utilized after putting the text into a .txt file that can be reached by the program.

Here is the code:


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

//function prototypes
void SplitString(string, vector<string>&);
void PrintVector(vector<string>);
void PrintIntVector(vector<int>);

int main(){
  vector<int> fish;
  vector<string> list;

  ifstream fin("text.txt");
  string line;
  while(fin >> line) {
	replace(line.begin(), line.end(), ',', ' ');
	cout << "Line: \n" << line << endl;
  }
  SplitString(line, list);
  for(int i=0;i<list.size();i++){
	int x=stoi(list[i]);
	fish.push_back(x);
  }
  cout << "LIST:" << endl;
  PrintVector(list);
  cout << "FISH:" << endl;
  PrintIntVector(fish);
  cout << "Initial lanternfish: " << fish.size() << endl;

  for(int days = 1; days<=80;days++){
	int tempSize = 0;
	tempSize=fish.size();
	for(int i=0;i<tempSize;i++){
		if(fish[i]==0){
			fish.push_back(8);
			//PrintIntVector(fish);
			fish[i]=6;
		}else{
			fish[i]--;
		}
	}
	cout << "Lanternfish after " << days << " day(s): " << fish.size() << endl;
  }
  return 0;
}

void SplitString(string s, vector<string> &v){
  string temp = "";
  for(int i=0;i<s.length();++i){
	if(s[i]==' '){
		v.push_back(temp);
		temp = "";
	}
	else{
		temp.push_back(s[i]);
	}
  }
  v.push_back(temp);
}

void PrintVector(vector<string> v){
  for(int i=0;i<v.size();++i)
	cout<<v[i] << " ";
  cout<<"\n";
}

void PrintIntVector(vector<int> v){
  for(int i=0;i<v.size();++i)
	cout<<v[i] << " ";
  cout<<"\n";
}

After receiving the input from the single line from the text file, it replaces all the commas between the numbers with a blank space instead.

This code utilizes a function called SplitString to then split each number from the string of the input into a vector of string type to house each number within it's own memory location accessible through list[i]. Then immediately after, the vector of string type list then has it's values pushed into the stack of a vector of int type, fish, after converting each value one by one from a string into an int type.

Afterwards, the program then prints the initial size of the vector fish, or in terms of the problem, the amount of Lanternfish at the start of the cycle. The program then enters a for loop that increments 80 times from day 1 through day 80. The variable tempSize is then declared and initialized to the amount of fish at the start of each day. Then, for each fish, that was present since the start of the day, in the vector is then checked for the value of 0 and for each fish with the value of 0, a new fish of the value of 8 is pushed onto the end of the vector stack. The variable tempSize is utilized for the purpose of not checking the new fish because it would be redundant.

Proceeding forth within the same for loop that affects only the fish present at the beginning of the day, the program then sets any value of 0 to 6. Every other value that isn't 0 and isn't a new fish of value 8 added the same day is then decremented by one. The program then prints the amount of fish at the end of each day before starting the new day, or the next increment in the for loop.

At the end of the for loop, meaning after 80 days, the amount of fish is the desired result for the question.

Part 2

Part 2 of the problem states:

Suppose the lanternfish live forever and have unlimited food and space. Would they take over the entire ocean?

After 256 days in the example above, there would be a total of 26984457539 lanternfish!

How many lanternfish would there be after 256 days?

The solution to this problem is the same as part 1 with the 80 in this line changed to a 256:

for(int days = 1; days<=80;days++){ ... } //change the 80 to a 256

This solution provided is most certainly not the most optimized solution though. So this second part of the problem with the above solution will utilize a lot of RAM and take a decently lengthy period of time to retrieve the desired answer, but nonetheless, is a viable option and is the solution I utilized for the second part of my question by dedicating further RAM to my IDE.

Loading

Zach
Author
About Me
Privacy Policy
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram