Skip to content

Commit

Permalink
d24 pt 1 done
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed-dash committed Dec 28, 2023
1 parent 859771e commit 1c2e104
Showing 1 changed file with 87 additions and 12 deletions.
99 changes: 87 additions & 12 deletions src/AoC_2023/Dazbo's_Advent_of_Code_2023.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -9231,7 +9231,13 @@
"\n",
"(I'm already scared about Part 2.)\n",
"\n",
"**Considering only the X and Y axes, check all pairs of hailstones' future paths for intersections. How many of these intersections occur within the test area?**\n"
"**Considering only the X and Y axes, check all pairs of hailstones' future paths for intersections. How many of these intersections occur within the test area?**\n",
"\n",
"**My solution:**\n",
"\n",
"This feels like a `y = mx + c` problem.\n",
"\n",
"For each line, we can obtain two `(x,y)` points, i.e. `(x,y)` at `t=0`, and `(x,y)`at `t=1`."
]
},
{
Expand All @@ -9242,10 +9248,61 @@
"source": [
"@dataclass\n",
"class Hailstone():\n",
" posn: tuple[int, ...]\n",
" \"\"\" Represent the position of the stone at t=0, and the velocity \"\"\"\n",
" posn: tuple[float, ...]\n",
" velocity: tuple[int, ...]\n",
" \n",
"def parse_stones(data):\n",
" def posn_at_t(self, t: int) -> tuple[float, ...]:\n",
" \"\"\" Return the position at time t \"\"\"\n",
" new_axis_vals = []\n",
" for axis, axix_val in enumerate(self.posn):\n",
" new_axis_vals.append(axix_val + t*self.velocity[axis])\n",
" \n",
" return tuple(new_axis_vals)\n",
" \n",
" @property\n",
" def gradient(self) -> float:\n",
" \"\"\" \n",
" Determine the gradient as given by (y velocity) / (x velocity)\n",
" Raises ValueError if the x velocity is 0, then the gradient is infinite\n",
" \"\"\"\n",
" if self.velocity[0] == 0:\n",
" raise ValueError(\"Infinite gradient\")\n",
" \n",
" return self.velocity[1] / self.velocity[0]\n",
" \n",
" @property\n",
" def y_intercept(self) -> float:\n",
" \"\"\" \n",
" Determine the c value of y = mx + c \n",
" c = y - mx \n",
" \"\"\"\n",
" return self.posn[1] - self.gradient*self.posn[0]\n",
" \n",
" def intersects_with(self, other: Hailstone) -> tuple[float, ...]:\n",
" \"\"\" \n",
" For y = mx + c\n",
" x = (c2-c1) / (m1-m2)\n",
" \"\"\"\n",
" if self.gradient == other.gradient:\n",
" raise ValueError(\"Parallel paths\")\n",
" \n",
" x = (other.y_intercept - self.y_intercept) / (self.gradient - other.gradient)\n",
" y = self.gradient*x + self.y_intercept\n",
" \n",
" return (x,y)\n",
" \n",
" def time_at_posn(self, posn: tuple[float, ...]) -> float:\n",
" \"\"\" \n",
" Determine the time that this stone was at this position.\n",
" t = (xi - x0) / vx\n",
" where xi is the x coord at a given location\n",
" x0 is the original x coord\n",
" vx is the velocity in the x direction\n",
" \"\"\"\n",
" return (posn[0] - self.posn[0]) / self.velocity[0]\n",
" \n",
"def parse_stones(data) -> list[Hailstone]:\n",
" stones = []\n",
" for row in data:\n",
" posn, velocity = row.split(\"@\")\n",
Expand All @@ -9261,12 +9318,28 @@
"metadata": {},
"outputs": [],
"source": [
"def solve_part1(data: list[str], coord_min: int, coord_max: int):\n",
"def solve_part1(data: list[str], coord_min: int, coord_max: int) -> int:\n",
" \"\"\" \n",
" Detect any intersection of paths within the specified x,y area\n",
" and where the time that this hailstone occupies this location is not in the past. \n",
" \"\"\"\n",
" stones = parse_stones(data)\n",
" logger.debug(stones)\n",
"\n",
"\n",
" "
" \n",
" intersections = 0\n",
" for stone_a, stone_b in combinations(stones, 2):\n",
" try:\n",
" intersect = stone_a.intersects_with(stone_b)\n",
" t_a = stone_a.time_at_posn(intersect)\n",
" t_b = stone_b.time_at_posn(intersect)\n",
" if (coord_min <= intersect[0] <= coord_max \n",
" and coord_min <= intersect[1] <= coord_max\n",
" and t_a >= 0 and t_b >= 0):\n",
" intersections += 1\n",
" # logger.debug(f\"{intersect} at {t_a=}, {t_b=}\")\n",
" except ValueError as e:\n",
" logger.debug(e) # e.g. parallel lines\n",
" \n",
" return intersections\n"
]
},
{
Expand All @@ -9290,7 +9363,7 @@
"\n",
"logger.info(\"Tests passed!\")\n",
"\n",
"soln = solve_part1(input_data)\n",
"soln = solve_part1(input_data, 200000000000000, 400000000000000)\n",
"logger.info(f\"Part 1 soln={soln}\")"
]
},
Expand All @@ -9300,7 +9373,10 @@
"source": [
"### Day 24 Part 2\n",
"\n",
"Overview..."
"We can throw a rock that can reach any integer location and with any integer velocity. We want the rock to collide with EVERY hailstone. The rock itself won't change position or velocity when it hits a hailstone.\n",
"\n",
"**Determine the exact position and velocity the rock needs to have at time 0 so that it perfectly collides with every hailstone. What do you get if you add up the X, Y, and Z coordinates of that initial position?**\n",
"\n"
]
},
{
Expand All @@ -9320,8 +9396,7 @@
"outputs": [],
"source": [
"%%time\n",
"sample_inputs = [\"abcdef\"]\n",
"sample_answers = [\"uvwxyz\"]\n",
"sample_answers = [47]\n",
"\n",
"for curr_input, curr_ans in zip(sample_inputs, sample_answers):\n",
" validate(solve_part2(curr_input), curr_ans) # test with sample data\n",
Expand Down

0 comments on commit 1c2e104

Please sign in to comment.