day 20 aoc: the cupid shuffle

https://youtube.com/watch?v=h24_zoqu4_Q

to the right to the right to the right

to the left to the left to the left

post your aoc solutions for day 20 or smth, all checks notes 5+ of you

42
Jump in the discussion.

No email address required.

Instead of just using some form of doubly linked list, i just made my own list that goes around in a circle. Kinda sketchy and instead of just removing the element and puttign it where it should go, i just swap the content of 2 adjacent nodes, until the node is in the right location.


#include <iostream>
#include <memory>
#include <fstream>
#include <string>
#include <vector>

template<typename T>
class Node {
public:
	std::unique_ptr<Node<T>> next;
	Node<T>* prev;
	size_t id;
	T value;

	Node(size_t id, T value) {
		this->id = id;
		this->value = value;
		prev = nullptr;
		next = nullptr;
	}

	static void swap(Node* n1, Node* n2) {
		std::swap(n1->id, n2->id);
		std::swap(n1->value, n2->value);
	}
};

template<typename T>
class CircularList {
private:
	void move_prev(Node<T>* node, int64_t steps) {
		steps = steps % (size - 1);
		Node<T>* current = node;
		while (steps > 0) {
			Node<T>::swap(current, current->prev);
			current = current->prev;
			steps--;
		}
	}
	void move_next(Node<T>* node, int64_t steps) {
		steps = steps % (size - 1);
		auto current = node;
		while (steps > 0) {
			Node<T>::swap(current, current->next.get());
			current = current->next.get();
			steps--;
		}
	}
public:
	Node<T>* start = nullptr;
	size_t size{ 0 };

	~CircularList() {
		start->next = nullptr;
	}

	void push(size_t id, T value) {
		++size;
		if (start == nullptr) {
			start = new Node<T>(id, value);
			start->prev = start;
			start->next = std::unique_ptr<Node<T>>(start);
		}
		else {
			Node<T>* node = new Node<T>(id, value);
			node->prev = start->prev;
			node->next = std::move(start->prev->next);

			start->prev->next = std::unique_ptr<Node<T>>(node);
			start->prev = node;
		}
	}

	void move(Node<T>* node, int64_t steps) {
		if (steps < 0) move_prev(node, -steps);
		else if (steps > 0) move_next(node, steps);
	}

	void print() {
		auto current = start;
		do {
			std::cout << "{" << current->id << ", " << current->value << "}, ";
			//std::cout << current->value << ", ";
			current = current->next.get();
		} while (current->id != start->id);
		std::cout << '\n';
	}

	Node<T>* find(size_t id) {
		auto current = start;
		while (current->id != id) current = current->next.get();
		return current;
	}

	std::vector<Node<T>*> findByValue(int64_t value) {
		std::vector<Node<T>*> out;
		auto current = start;
		do {
			if (current->value == value) out.push_back(current);
			current = current->next.get();
		} while (current->id != start->id);
		return out;
	}
};

int64_t run(bool p1 = true)
{
	CircularList<int64_t> circle_list;

	std::fstream file("input.txt");
	std::vector<size_t> tracker;

	int64_t number;
	size_t id{ 1 };
	while (file >> number) {
		if (!p1) number = number * 811589153;
		circle_list.push(id, number);
		tracker.push_back(id);
		id++;
	}
	
	int runs = 1;
	if (!p1) runs = 10;

	for (int run{ 0 }; run < runs; ++run) {
		for (size_t t_id : tracker) {
			auto node = circle_list.find(t_id);
			circle_list.mp4e(node, node->value);
		}
	}

	auto start = circle_list.findByValue(0)[0];
	int to_find_a{ 1000 };
	int to_find_b{ 2000 };
	int to_find_c{ 3000 };
	int i{ 0 };

	int64_t result{ 0 };

	while (i <= to_find_c) {
		++i;
		start = start->next.get();
		if (i == to_find_a) result += start->value;
		if (i == to_find_b) result += start->value;
		if (i == to_find_c) result += start->value;
	}
	return result;
}

int main() {
	auto partOne = run(true);
	std::cout << "Part One: " << partOne << '\n';
	auto partTwo = run(false);
	std::cout << "Part Two: " << partTwo << '\n';
}

Jump in the discussion.

No email address required.

No, don't reply like this, please do another wall of unhinged rant please.

Jump in the discussion.

No email address required.

Link copied to clipboard
Action successful!
Error, please refresh the page and try again.