forked from Bananymous/banan-os
				
			AOC2023: Implement day24 part1
This commit is contained in:
		
							parent
							
								
									910a57089b
								
							
						
					
					
						commit
						d87fa1a7ea
					
				| 
						 | 
					@ -25,6 +25,7 @@ set(AOC2023_PROJECTS
 | 
				
			||||||
	day20
 | 
						day20
 | 
				
			||||||
	day21
 | 
						day21
 | 
				
			||||||
	day23
 | 
						day23
 | 
				
			||||||
 | 
						day24
 | 
				
			||||||
	full
 | 
						full
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.26)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					project(aoc2023_day24 CXX)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(SOURCES
 | 
				
			||||||
 | 
						main.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(aoc2023_day24 ${SOURCES})
 | 
				
			||||||
 | 
					target_compile_options(aoc2023_day24 PUBLIC -O2 -g)
 | 
				
			||||||
 | 
					target_link_libraries(aoc2023_day24 PUBLIC libc ban)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_dependencies(aoc2023_day24 libc-install ban-install)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_custom_target(aoc2023_day24-install
 | 
				
			||||||
 | 
						COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/aoc2023_day24 ${BANAN_AOC2023_BIN}/day24
 | 
				
			||||||
 | 
						DEPENDS aoc2023_day24
 | 
				
			||||||
 | 
						DEPENDS aoc2023_always
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_dependencies(aoc2023 aoc2023_day24)
 | 
				
			||||||
 | 
					add_dependencies(aoc2023-install aoc2023_day24-install)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,138 @@
 | 
				
			||||||
 | 
					#include <BAN/Vector.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using i8  = int8_t;
 | 
				
			||||||
 | 
					using i16 = int16_t;
 | 
				
			||||||
 | 
					using i32 = int32_t;
 | 
				
			||||||
 | 
					using i64 = int64_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using u8  = uint8_t;
 | 
				
			||||||
 | 
					using u16 = uint16_t;
 | 
				
			||||||
 | 
					using u32 = uint32_t;
 | 
				
			||||||
 | 
					using u64 = uint64_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Hailstone
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						double px, py, pz;
 | 
				
			||||||
 | 
						double vx, vy, vz;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i64 parse_i64(BAN::StringView str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (isspace(str.front()))
 | 
				
			||||||
 | 
							str = str.substring(1);
 | 
				
			||||||
 | 
						bool negative = str.front() == '-';
 | 
				
			||||||
 | 
						if (negative)
 | 
				
			||||||
 | 
							str = str.substring(1);
 | 
				
			||||||
 | 
						i64 result = 0;
 | 
				
			||||||
 | 
						for (char c : str)
 | 
				
			||||||
 | 
							if (isdigit(c))
 | 
				
			||||||
 | 
								result = (result * 10) + (c - '0');
 | 
				
			||||||
 | 
						return negative ? -result : result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BAN::Vector<Hailstone> parse_hailstones(FILE* fp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BAN::Vector<Hailstone> hailstones;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char buffer[128];
 | 
				
			||||||
 | 
						while (fgets(buffer, sizeof(buffer), fp))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							BAN::StringView line(buffer);
 | 
				
			||||||
 | 
							ASSERT(line.back() == '\n');
 | 
				
			||||||
 | 
							line = line.substring(0, line.size() - 1);
 | 
				
			||||||
 | 
							if (line.empty())
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							auto position_velocity_strs = MUST(line.split('@'));
 | 
				
			||||||
 | 
							ASSERT(position_velocity_strs.size() == 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Hailstone hailstone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto position_strs = MUST(position_velocity_strs[0].split(','));
 | 
				
			||||||
 | 
							ASSERT(position_strs.size() == 3);
 | 
				
			||||||
 | 
							hailstone.px = parse_i64(position_strs[0]);
 | 
				
			||||||
 | 
							hailstone.py = parse_i64(position_strs[1]);
 | 
				
			||||||
 | 
							hailstone.pz = parse_i64(position_strs[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto velocity_strs = MUST(position_velocity_strs[1].split(','));
 | 
				
			||||||
 | 
							ASSERT(velocity_strs.size() == 3);
 | 
				
			||||||
 | 
							hailstone.vx = parse_i64(velocity_strs[0]);
 | 
				
			||||||
 | 
							hailstone.vy = parse_i64(velocity_strs[1]);
 | 
				
			||||||
 | 
							hailstone.vz = parse_i64(velocity_strs[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							MUST(hailstones.push_back(hailstone));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return hailstones;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i64 puzzle1(FILE* fp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						auto hailstones = parse_hailstones(fp);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						i64 result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < hailstones.size(); i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (size_t j = i + 1; j < hailstones.size(); j++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								const auto& h1 = hailstones[i];
 | 
				
			||||||
 | 
								const auto& h2 = hailstones[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// skip parallel lines
 | 
				
			||||||
 | 
								if (h1.vy * h2.vx == h2.vy * h1.vx)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const double t2 = ((h2.py - h1.py) * h1.vx - (h2.px - h1.px) * h1.vy) / (h2.vx * h1.vy - h1.vx * h2.vy);
 | 
				
			||||||
 | 
								if (t2 < 0.0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const double t1 = ((h2.py - h1.py) + t2 * h2.vy) / h1.vy;
 | 
				
			||||||
 | 
								if (t1 < 0.0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const double x = h2.px + t2 * h2.vx;
 | 
				
			||||||
 | 
								const double y = h2.py + t2 * h2.vy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								constexpr double min = 200000000000000.0;
 | 
				
			||||||
 | 
								constexpr double max = 400000000000000.0;
 | 
				
			||||||
 | 
								if ((min <= x && x <= max) && (min <= y && y <= max))
 | 
				
			||||||
 | 
									result++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i64 puzzle2(FILE* fp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void)fp;
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char* file_path = "/usr/share/aoc2023/day24_input.txt";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc >= 2)
 | 
				
			||||||
 | 
							file_path = argv[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FILE* fp = fopen(file_path, "r");
 | 
				
			||||||
 | 
						if (fp == nullptr)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							perror("fopen");
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("puzzle1: %" PRId64 "\n", puzzle1(fp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fseek(fp, 0, SEEK_SET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("puzzle2: %" PRId64 "\n", puzzle2(fp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fclose(fp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main()
 | 
					int main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	for (int i = 1; i <= 23; i++)
 | 
						for (int i = 1; i <= 24; i++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (i == 22)
 | 
							if (i == 22)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue