Files
org_roam/output/20241210001150-aoc_notes.html
2025-12-28 20:41:18 +00:00

1861 lines
62 KiB
HTML
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2025-12-28 Sun 20:37 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AOC Notes</title>
<meta name="generator" content="Org Mode" />
<style type="text/css">
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { }
</style>
<link rel="stylesheet" href="/assets/styles/style.css" />
<link rel="stylesheet" href="/assets/styles/bigger-picture.min.css" />
<link rel="stylesheet" href="/assets/styles/media.css" />
<script src="/assets/scripts/script.js" defer></script>
<script src="/assets/scripts/search.js" defer></script>
<script src="/assets/scripts/bigger-picture.min.js" defer></script>
<script src="/assets/scripts/svg-pan-zoom.min.js" defer></script>
<script src="/assets/scripts/gallery-init.js" defer></script>
</head>
<body>
<div id="preamble" class="status">
<div class="banner-header">
<div class="banner-left">
<a href="/20241210233721-brain_moc.html"> <img src="/assets/gr.png" alt="Site Logo" class="banner-logo" /> </a>
<div id="updated">Updated: 2025-12-28 Sun 19:48</div>
</div>
<div class="banner-search">
<input id="search-box"
type="search"
placeholder="Search notes…"
aria-label="Search notes"
autocomplete="off" />
<div id="search-results"></div>
</div>
<button id="close-all">Close All</button>
</div>
</div>
<div id="stack-root">
<div class="stack-track">
<article class="stack-pane pane-root" data-url="/20241210001150-aoc_notes.html">
<div id="content" class="content">
<div class="title-section">
<div class="title-controls">
<button class="pane-fullscreen" aria-label="Fullscreen">F</button>
<button class="pane-edit" aria-label="Edit pane">E</button>
<button class="pane-close" aria-label="Close pane">×</button>
</div>
<h1 class="title">AOC Notes</h1>
<div class="title-metadata">
<span class="metadata-item">
<span class="metadata-label">planted:</span>
<span class="metadata-value">2024-12-10</span>
</span>
<span class="metadata-item">
<span class="metadata-label">last tended to:</span>
<span class="metadata-value">2025-12-28</span>
</span>
</div>
</div>
<p>
Here are the notes for the AOC (Advent Of Code) for the year 2024.
Workspace:
</p>
<div class="org-src-container">
<pre class="src src-haskell">import System.Process (callCommand)
main :: IO ()
main = do
putStrLn "Launching IntelliJ in gnome-terminal with zsh..."
_ &lt;- callCommand "gnome-terminal -- zsh -c 'idea /home/zaine/Documents/projects/advent_of_code'"
putStrLn "Terminal launched."
</pre>
</div>
<div id="outline-container-org934a7c9" class="outline-2">
<h2 id="org934a7c9"><a href="#org934a7c9">Day 3</a></h2>
<div class="outline-text-2" id="text-org934a7c9">
</div>
<div id="outline-container-org4744122" class="outline-3">
<h3 id="org4744122"><a href="#org4744122">point 1</a></h3>
<div class="outline-text-3" id="text-org4744122">
<p>
A lot of basic string and numeric manipulation was tested.
When you have a input string, and want to test weather there contains a substring, you can use
</p>
<div class="org-src-container">
<pre class="src src-java[[id:8fa3f476-6152-45f4-b618-50f1e4bce46c][Emacs">// input is the string
if (input.startsWith("mul(", i)) {
int endIndex = input.indexOf(")", i);
if (endIndex != -1) {
String candidate = input.substring(i, endIndex + 1);
}
}
</pre>
</div>
<p>
Here we can see that through the loop, an if check is being done to check if the string starts with &ldquo;mul(&rdquo;, if so, it gets the endIndex of it too. Then it stores that &ldquo;candidate&rdquo; value into a String, using the substring method.
</p>
</div>
</div>
<div id="outline-container-org3399ad8" class="outline-3">
<h3 id="org3399ad8"><a href="#org3399ad8">point 2</a></h3>
<div class="outline-text-3" id="text-org3399ad8">
<p>
some regex below: this checks if the input is of the correct format.
</p>
<div class="org-src-container">
<pre class="src src-java">public static boolean isValidMul(String input) {
// Regex to validate mul(X,Y) where X and Y are 1-3 digit numbers
return input.matches("mul\\(\\d{1,3},\\d{1,3}\\)");
}
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org40202d1" class="outline-2">
<h2 id="org40202d1"><a href="#org40202d1">Day 4</a></h2>
<div class="outline-text-2" id="text-org40202d1">
</div>
<div id="outline-container-org08e99ae" class="outline-3">
<h3 id="org08e99ae"><a href="#org08e99ae">part 1</a></h3>
<div class="outline-text-3" id="text-org08e99ae">
<p>
was extremely difficult. i had to load the input as a 2d array,
</p>
<div class="org-src-container">
<pre class="src src-java">int cols = lines.get(0).length(); //where lines is var
int cols = grid[0].length; // where grid is a 2d array
</pre>
</div>
<p>
this allows you to get the vertical length of the 2d array.
</p>
</div>
<div id="outline-container-org437738e" class="outline-4">
<h4 id="org437738e"><a href="#org437738e">countWordOccurrences Method</a></h4>
<div class="outline-text-4" id="text-org437738e">
<p>
Iterates through the grid to check for occurrences of the word &ldquo;XMAS&rdquo; in all possible directions (horizontal, vertical, and diagonal).
Directions: Defined by the directions array, which contains 8 possible ways to traverse:
{0, 1}: Right
{0, -1}: Left
{1, 0}: Down
{-1, 0}: Up
{1, 1}: Diagonal down-right
{1, -1}: Diagonal down-left
{-1, 1}: Diagonal up-right
{-1, -1}: Diagonal up-left
</p>
<p>
For each starting position (row, col) in the grid:
</p>
<p>
The program checks each direction by calling isWordFound.
</p>
</div>
</div>
<div id="outline-container-org4d97768" class="outline-4">
<h4 id="org4d97768"><a href="#org4d97768">Checking for the Word</a></h4>
<div class="outline-text-4" id="text-org4d97768">
<p>
isWordFound Method Validates if the word exists starting from a specific position (row, col) in the grid, moving in the specified direction (dx, dy).
For each character in the word:
</p>
<ul class="org-ul">
<li>compute the new position (newRow, newCol) based on the direction.</li>
<li>Check bounds to ensure the position is valid (not out of the grid).</li>
<li>Compare the character at the position with the corresponding character in the word.</li>
<li>If any check fails, return false.</li>
</ul>
<p>
If all characters match, the word is found, and the method returns true.
</p>
</div>
</div>
<div id="outline-container-org6b9eea9" class="outline-4">
<h4 id="org6b9eea9"><a href="#org6b9eea9">Counting Matches</a></h4>
<div class="outline-text-4" id="text-org6b9eea9">
<p>
For each occurrence of the word found by isWordFound, increment the count variable.
After scanning all positions and directions in the grid, the total count is returned.
</p>
</div>
</div>
</div>
<div id="outline-container-orge4bc797" class="outline-3">
<h3 id="orge4bc797"><a href="#orge4bc797">part 2</a></h3>
<div class="outline-text-3" id="text-orge4bc797">
<p>
was alot easier, i looped through the whole grid, and wherever there is the letter &rsquo;A&rsquo;, i want to check around it, it can be in the form:
</p>
<div class="org-src-container">
<pre class="src src-nil">M.S
.A.
M.S
</pre>
</div>
<p>
and this would count as one, as there is MAS twice (diagonally in the shape of an X)
</p>
</div>
</div>
</div>
<div id="outline-container-org67c7635" class="outline-2">
<h2 id="org67c7635"><a href="#org67c7635">Day 5</a></h2>
<div class="outline-text-2" id="text-org67c7635">
</div>
<div id="outline-container-org16407c3" class="outline-3">
<h3 id="org16407c3"><a href="#org16407c3">Part One: Identifying Correctly Ordered Updates</a></h3>
<div class="outline-text-3" id="text-org16407c3">
</div>
<div id="outline-container-org86466e6" class="outline-4">
<h4 id="org86466e6"><a href="#org86466e6">Splitting Input into Rules and Updates</a></h4>
<div class="outline-text-4" id="text-org86466e6">
<p>
Parsing the input file into two distinct sections (rules and updates) required identifying the empty line separator.
</p>
<div class="org-src-container">
<pre class="src src-java">for (String line : lines) {
if (line.trim().isEmpty()) {
emptyLineFound = true;
continue; // Skip the empty line itself
}
if (!emptyLineFound) {
firstList.add(line);
} else {
secondList.add(line);
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org9388ce5" class="outline-4">
<h4 id="org9388ce5"><a href="#org9388ce5">Dependency Graph Representation</a></h4>
<div class="outline-text-4" id="text-org9388ce5">
<p>
Representing the rules as a directed graph with each rule defining an edge (X|Y as X -&gt; Y). This graph maps each page to a list of pages that must follow it.
</p>
<div class="org-src-container">
<pre class="src src-java">Map&lt;Integer, List&lt;Integer&gt;&gt; graph = new HashMap&lt;&gt;();
graph.putIfAbsent(from, new ArrayList&lt;&gt;());
graph.get(from).add(to);
</pre>
</div>
</div>
</div>
<div id="outline-container-org07b05a3" class="outline-4">
<h4 id="org07b05a3"><a href="#org07b05a3">Checking Update Validity</a></h4>
<div class="outline-text-4" id="text-org07b05a3">
<p>
Verifying if an update follows the rules using a map of page positions for quick lookup.
</p>
<div class="org-src-container">
<pre class="src src-java">for (Map.Entry&lt;Integer, List&lt;Integer&gt;&gt; entry : graph.entrySet()) {
int from = entry.getKey();
for (int to : entry.getValue()) {
if (positions.get(from) &gt;= positions.get(to)) {
return false; // Rule violated
}
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org02bbc2b" class="outline-4">
<h4 id="org02bbc2b"><a href="#org02bbc2b">Finding the Middle Page</a></h4>
<div class="outline-text-4" id="text-org02bbc2b">
<p>
Calculating the middle page for each correctly ordered update using list indexing.
</p>
<div class="org-src-container">
<pre class="src src-java">int middlePage = pages.get(pages.size() / 2);
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgd117857" class="outline-3">
<h3 id="orgd117857"><a href="#orgd117857">Part Two: Reordering Incorrect Updates</a></h3>
<div class="outline-text-3" id="text-orgd117857">
</div>
<div id="outline-container-org03499b8" class="outline-4">
<h4 id="org03499b8"><a href="#org03499b8">Topological Sorting</a></h4>
<div class="outline-text-4" id="text-org03499b8">
<p>
Reordering pages required implementing a topological sort, which ensures all dependencies (rules) are respected.
</p>
<div class="org-src-container">
<pre class="src src-java">visiting.add(node);
for (int neighbor : graph.getOrDefault(node, Collections.emptyList())) {
if (!dfs(neighbor, graph, visited, visiting, sorted)) {
return false; // Cycle detected
}
}
visiting.remove(node);
visited.add(node);
sorted.add(node);
</pre>
</div>
</div>
</div>
<div id="outline-container-org412dab2" class="outline-4">
<h4 id="org412dab2"><a href="#org412dab2">Subgraph Creation</a></h4>
<div class="outline-text-4" id="text-org412dab2">
<p>
Only rules involving pages in the current update were considered. This required dynamically building a subgraph for each update.
</p>
<div class="org-src-container">
<pre class="src src-java">for (int page : pages) {
if (graph.containsKey(page)) {
for (int dependent : graph.get(page)) {
if (pages.contains(dependent)) {
subGraph.get(page).add(dependent);
}
}
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org1c24829" class="outline-4">
<h4 id="org1c24829"><a href="#org1c24829">Cycle Detection</a></h4>
<div class="outline-text-4" id="text-org1c24829">
<p>
Ensuring no cycles existed in the dependency graph was critical for valid sorting.
</p>
<div class="org-src-container">
<pre class="src src-java">if (visiting.contains(node)) {
return false; // Cycle detected
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org2ab1291" class="outline-4">
<h4 id="org2ab1291"><a href="#org2ab1291">Finding Middle Page After Reordering</a></h4>
<div class="outline-text-4" id="text-org2ab1291">
<p>
Same approach as in Part One but applied after sorting.
</p>
<div class="org-src-container">
<pre class="src src-java">int correctedMiddlePage = reorderedPages.get(reorderedPages.size() / 2);
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="outline-container-org6bbf4e0" class="outline-2">
<h2 id="org6bbf4e0"><a href="#org6bbf4e0">Day 6</a></h2>
<div class="outline-text-2" id="text-org6bbf4e0">
</div>
<div id="outline-container-org72470d2" class="outline-3">
<h3 id="org72470d2"><a href="#org72470d2">Part 1</a></h3>
<div class="outline-text-3" id="text-org72470d2">
</div>
<div id="outline-container-org7be7a52" class="outline-4">
<h4 id="org7be7a52"><a href="#org7be7a52">Input Parsing</a></h4>
<div class="outline-text-4" id="text-org7be7a52">
<div class="org-src-container">
<pre class="src src-java">List&lt;String&gt; input = Files.readAllLines(Paths.get("aoc_24/src/day_6/input"));
int rows = input.size();
int cols = input.get(0).length();
char[][] map = new char[rows][cols];
</pre>
</div>
</div>
</div>
<div id="outline-container-org420c018" class="outline-4">
<h4 id="org420c018"><a href="#org420c018">Guard Initialization</a></h4>
<div class="outline-text-4" id="text-org420c018">
<div class="org-src-container">
<pre class="src src-java">for (int r = 0; r &lt; rows; r++) {
for (int c = 0; c &lt; cols; c++) {
if ("^v&lt;&gt;".indexOf(map[r][c]) != -1) {
guardRow = r;
guardCol = c;
guardFacing = map[r][c];
map[r][c] = '.'; // Clear the guard's position
}
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org547ea8a" class="outline-4">
<h4 id="org547ea8a"><a href="#org547ea8a">Movement Directions</a></h4>
<div class="outline-text-4" id="text-org547ea8a">
<div class="org-src-container">
<pre class="src src-java">Map&lt;Character, int[]&gt; directions = Map.of(
'^', new int[] {-1, 0},
'v', new int[] {1, 0},
'&lt;', new int[] {0, -1},
'&gt;', new int[] {0, 1}
);
</pre>
</div>
</div>
</div>
<div id="outline-container-org2230dd3" class="outline-4">
<h4 id="org2230dd3"><a href="#org2230dd3">Turning Logic</a></h4>
<div class="outline-text-4" id="text-org2230dd3">
<div class="org-src-container">
<pre class="src src-java">Map&lt;Character, Character&gt; turnRight = Map.of(
'^', '&gt;',
'&gt;', 'v',
'v', '&lt;',
'&lt;', '^'
);
</pre>
</div>
</div>
</div>
<div id="outline-container-org8e012c9" class="outline-4">
<h4 id="org8e012c9"><a href="#org8e012c9">Visited Positions Tracking</a></h4>
<div class="outline-text-4" id="text-org8e012c9">
<div class="org-src-container">
<pre class="src src-java">Set&lt;String&gt; visited = new HashSet&lt;&gt;();
visited.add(guardRow + "," + guardCol);
</pre>
</div>
</div>
</div>
<div id="outline-container-orgad58c68" class="outline-4">
<h4 id="orgad58c68"><a href="#orgad58c68">Movement and Termination Logic</a></h4>
<div class="outline-text-4" id="text-orgad58c68">
<div class="org-src-container">
<pre class="src src-java">while (true) {
int[] move = directions.get(guardFacing);
int nextRow = guardRow + move[0];
int nextCol = guardCol + move[1];
if (nextRow &lt; 0 || nextRow &gt;= rows || nextCol &lt; 0 || nextCol &gt;= cols) {
break; // Guard leaves the map
}
if (map[nextRow][nextCol] == '#') {
guardFacing = turnRight.get(guardFacing); // Turn right
} else {
guardRow = nextRow;
guardCol = nextCol;
visited.add(guardRow + "," + guardCol);
}
}
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgf53dba6" class="outline-3">
<h3 id="orgf53dba6"><a href="#orgf53dba6">Part 2</a></h3>
<div class="outline-text-3" id="text-orgf53dba6">
</div>
<div id="outline-container-org687a886" class="outline-4">
<h4 id="org687a886"><a href="#org687a886">Input Parsing</a></h4>
<div class="outline-text-4" id="text-org687a886">
<div class="org-src-container">
<pre class="src src-java">List&lt;String&gt; input = Files.readAllLines(Paths.get("aoc_24/src/day_6/input"));
int rows = input.size();
int cols = input.get(0).length();
char[][] map = new char[rows][cols];
</pre>
</div>
</div>
</div>
<div id="outline-container-org81638e1" class="outline-4">
<h4 id="org81638e1"><a href="#org81638e1">Guard Initialization</a></h4>
<div class="outline-text-4" id="text-org81638e1">
<div class="org-src-container">
<pre class="src src-java">for (int r = 0; r &lt; rows; r++) {
for (int c = 0; c &lt; cols; c++) {
if ("^v&lt;&gt;".indexOf(map[r][c]) != -1) {
guardRow = r;
guardCol = c;
guardFacing = map[r][c];
map[r][c] = '.'; // Clear the guard's position
}
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orga44831c" class="outline-4">
<h4 id="orga44831c"><a href="#orga44831c">Movement Directions</a></h4>
<div class="outline-text-4" id="text-orga44831c">
<div class="org-src-container">
<pre class="src src-java">Map&lt;Character, int[]&gt; directions = Map.of(
'^', new int[] {-1, 0},
'v', new int[] {1, 0},
'&lt;', new int[] {0, -1},
'&gt;', new int[] {0, 1}
);
</pre>
</div>
</div>
</div>
<div id="outline-container-orgdcff4b8" class="outline-4">
<h4 id="orgdcff4b8"><a href="#orgdcff4b8">Turning Logic</a></h4>
<div class="outline-text-4" id="text-orgdcff4b8">
<div class="org-src-container">
<pre class="src src-java">Map&lt;Character, Character&gt; turnRight = Map.of(
'^', '&gt;',
'&gt;', 'v',
'v', '&lt;',
'&lt;', '^'
);
</pre>
</div>
</div>
</div>
<div id="outline-container-org3407043" class="outline-4">
<h4 id="org3407043"><a href="#org3407043">Valid Obstruction Positions</a></h4>
<div class="outline-text-4" id="text-org3407043">
<div class="org-src-container">
<pre class="src src-java">Set&lt;String&gt; validObstructions = new HashSet&lt;&gt;();
for (int r = 0; r &lt; rows; r++) {
for (int c = 0; c &lt; cols; c++) {
if (map[r][c] == '.' &amp;&amp; !(r == guardRow &amp;&amp; c == guardCol)) {
map[r][c] = '#'; // Temporarily place obstruction
if (causesLoop(map, guardRow, guardCol, guardFacing, directions, turnRight)) {
validObstructions.add(r + "," + c);
}
map[r][c] = '.'; // Remove obstruction
}
}
}
System.out.println("Number of valid obstruction positions: " + validObstructions.size());
</pre>
</div>
</div>
</div>
<div id="outline-container-org1f3e4da" class="outline-4">
<h4 id="org1f3e4da"><a href="#org1f3e4da">Loop Detection Helper Function</a></h4>
<div class="outline-text-4" id="text-org1f3e4da">
<div class="org-src-container">
<pre class="src src-java">private static boolean causesLoop(char[][] map, int guardRow, int guardCol, char guardFacing,
Map&lt;Character, int[]&gt; directions, Map&lt;Character, Character&gt; turnRight) {
Set&lt;String&gt; seenStates = new HashSet&lt;&gt;();
int rows = map.length;
int cols = map[0].length;
while (true) {
String state = guardRow + "," + guardCol + "," + guardFacing;
if (seenStates.contains(state)) {
return true; // Loop detected
}
seenStates.add(state);
int[] move = directions.get(guardFacing);
int nextRow = guardRow + move[0];
int nextCol = guardCol + move[1];
if (nextRow &lt; 0 || nextRow &gt;= rows || nextCol &lt; 0 || nextCol &gt;= cols) {
return false; // Guard leaves the map
}
if (map[nextRow][nextCol] == '#') {
guardFacing = turnRight.get(guardFacing); // Turn right
} else {
guardRow = nextRow;
guardCol = nextCol;
}
}
}
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="outline-container-org1d44d9d" class="outline-2">
<h2 id="org1d44d9d"><a href="#org1d44d9d">Day 7</a></h2>
<div class="outline-text-2" id="text-org1d44d9d">
</div>
<div id="outline-container-org1f85780" class="outline-3">
<h3 id="org1f85780"><a href="#org1f85780">Part 1</a></h3>
<div class="outline-text-3" id="text-org1f85780">
</div>
<div id="outline-container-org531103a" class="outline-4">
<h4 id="org531103a"><a href="#org531103a">Input Parsing</a></h4>
<div class="outline-text-4" id="text-org531103a">
<ul class="org-ul">
<li>Parse the input file, where each line is in the format `&lt;testValue&gt;: &lt;number1&gt; &lt;number2&gt; &#x2026;`</li>
<li>`testValue` is a target number, and we determine if it can be computed by combining the given numbers with `+` or `*`.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">List&lt;String&gt; input = Files.readAllLines(Paths.get("aoc_24/src/day_7/input"));
long totalCalibrationResult = 0;
for (String line : input) {
String[] parts = line.split(": ");
long testValue = Long.parseLong(parts[0]); // Target value
String[] numbers = parts[1].split(" ");
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org727d62b" class="outline-4">
<h4 id="org727d62b"><a href="#org727d62b">Validation Logic</a></h4>
<div class="outline-text-4" id="text-org727d62b">
<ul class="org-ul">
<li>The `isValidEquation` function checks if any combination of operators (`+` or `*`) between the numbers matches the `testValue`.</li>
<li>Evaluation is performed left-to-right.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">private static boolean isValidEquation(long testValue, String[] numbers) {
List&lt;String&gt; operators = Arrays.asList("+", "*");
List&lt;String[]&gt; operatorCombinations = generateOperatorCombinations(numbers.length - 1, operators);
for (String[] operatorCombination : operatorCombinations) {
long result = Long.parseLong(numbers[0]);
for (int i = 1; i &lt; numbers.length; i++) {
String operator = operatorCombination[i - 1];
long num = Long.parseLong(numbers[i]);
if (operator.equals("+")) {
result += num;
} else if (operator.equals("*")) {
result *= num;
}
}
if (result == testValue) {
return true; // Equation is valid
}
}
return false; // No valid equation found
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org5ae1a22" class="outline-4">
<h4 id="org5ae1a22"><a href="#org5ae1a22">Operator Combination Generator</a></h4>
<div class="outline-text-4" id="text-org5ae1a22">
<ul class="org-ul">
<li>Generate all possible combinations of `+` and `*` for `n-1` positions (where `n` is the number of numbers).</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">private static List&lt;String[]&gt; generateOperatorCombinations(int numOperators, List&lt;String&gt; operators) {
List&lt;String[]&gt; combinations = new ArrayList&lt;&gt;();
generateOperatorCombinationsRecursive(new String[numOperators], 0, operators, combinations);
return combinations;
}
private static void generateOperatorCombinationsRecursive(String[] current, int index, List&lt;String&gt; operators, List&lt;String[]&gt; combinations) {
if (index == current.length) {
combinations.add(current.clone());
return;
}
for (String operator : operators) {
current[index] = operator;
generateOperatorCombinationsRecursive(current, index + 1, operators, combinations);
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org94d96bd" class="outline-4">
<h4 id="org94d96bd"><a href="#org94d96bd">Main Logic</a></h4>
<div class="outline-text-4" id="text-org94d96bd">
<ul class="org-ul">
<li>Iterate over each line of input.</li>
<li>Parse `testValue` and numbers.</li>
<li>If a valid equation exists for the line, add the `testValue` to the total calibration result.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">for (String line : input) {
String[] parts = line.split(": ");
long testValue = Long.parseLong(parts[0]);
String[] numbers = parts[1].split(" ");
if (isValidEquation(testValue, numbers)) {
totalCalibrationResult += testValue;
}
}
System.out.println("Total Calibration Result: " + totalCalibrationResult);
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgaf81a83" class="outline-3">
<h3 id="orgaf81a83"><a href="#orgaf81a83">Part 2</a></h3>
<div class="outline-text-3" id="text-orgaf81a83">
</div>
<div id="outline-container-org20e50c9" class="outline-4">
<h4 id="org20e50c9"><a href="#org20e50c9">Input Parsing</a></h4>
<div class="outline-text-4" id="text-org20e50c9">
<ul class="org-ul">
<li>Reads an input file where each line is formatted as `&lt;testValue&gt;: &lt;number1&gt; &lt;number2&gt; &#x2026;`.</li>
<li>Parses `testValue` and the numbers to evaluate equations that could result in `testValue`.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">List&lt;String&gt; input = Files.readAllLines(Paths.get("aoc_24/src/day_7/input"));
long totalCalibrationResult = 0;
for (String line : input) {
String[] parts = line.split(": ");
long testValue = Long.parseLong(parts[0]); // Target value
String[] numbers = parts[1].split(" ");
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orgeb02ff8" class="outline-4">
<h4 id="orgeb02ff8"><a href="#orgeb02ff8">Validation Logic</a></h4>
<div class="outline-text-4" id="text-orgeb02ff8">
<ul class="org-ul">
<li>The `isValidEquation` function checks if any combination of operators (`+`, `*`, or `||`) between numbers can match the `testValue`.</li>
<li>Includes support for a new operator `||`:
<ul class="org-ul">
<li>Concatenates the current `result` and the next number as strings.</li>
<li>Converts the concatenated string back to `long` to update the result.</li>
</ul></li>
<li>Evaluation is performed left-to-right.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">private static boolean isValidEquation(long testValue, String[] numbers) {
List&lt;String&gt; operators = Arrays.asList("+", "*", "||");
List&lt;String[]&gt; operatorCombinations = generateOperatorCombinations(numbers.length - 1, operators);
for (String[] operatorCombination : operatorCombinations) {
long result = Long.parseLong(numbers[0]);
for (int i = 1; i &lt; numbers.length; i++) {
String operator = operatorCombination[i - 1];
long num = Long.parseLong(numbers[i]);
if (operator.equals("+")) {
result += num;
} else if (operator.equals("*")) {
result *= num;
} else if (operator.equals("||")) {
result = Long.parseLong(Long.toString(result) + Long.toString(num));
}
}
if (result == testValue) {
return true;
}
}
return false;
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org3c9e4dd" class="outline-4">
<h4 id="org3c9e4dd"><a href="#org3c9e4dd">Operator Combination Generator</a></h4>
<div class="outline-text-4" id="text-org3c9e4dd">
<ul class="org-ul">
<li>Generates all possible combinations of `+`, `*`, and `||` operators for `n-1` positions (where `n` is the number of numbers).</li>
<li>Recursively builds the combinations.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">private static List&lt;String[]&gt; generateOperatorCombinations(int numOperators, List&lt;String&gt; operators) {
List&lt;String[]&gt; combinations = new ArrayList&lt;&gt;();
generateOperatorCombinationsRecursive(new String[numOperators], 0, operators, combinations);
return combinations;
}
private static void generateOperatorCombinationsRecursive(String[] current, int index, List&lt;String&gt; operators, List&lt;String[]&gt; combinations) {
if (index == current.length) {
combinations.add(current.clone());
return;
}
for (String operator : operators) {
current[index] = operator;
generateOperatorCombinationsRecursive(current, index + 1, operators, combinations);
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orgf1d64f5" class="outline-4">
<h4 id="orgf1d64f5"><a href="#orgf1d64f5">Main Logic</a></h4>
<div class="outline-text-4" id="text-orgf1d64f5">
<ul class="org-ul">
<li>Iterates over each line of input.</li>
<li>Parses `testValue` and numbers.</li>
<li>Adds `testValue` to the total if a valid equation exists for the line.</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">for (String line : input) {
String[] parts = line.split(": ");
long testValue = Long.parseLong(parts[0]);
String[] numbers = parts[1].split(" ");
if (isValidEquation(testValue, numbers)) {
totalCalibrationResult += testValue;
}
}
System.out.println("Total Calibration Result: " + totalCalibrationResult);
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="outline-container-orga2ddf3e" class="outline-2">
<h2 id="orga2ddf3e"><a href="#orga2ddf3e">Day 8</a></h2>
<div class="outline-text-2" id="text-orga2ddf3e">
<p>
Resonant Collinearity
</p>
</div>
<div id="outline-container-orgd232702" class="outline-3">
<h3 id="orgd232702"><a href="#orgd232702">Part One</a></h3>
<div class="outline-text-3" id="text-orgd232702">
<ul class="org-ul">
<li>Objective: Identify unique antinode locations within a map, considering two antennas of the same frequency in a specific configuration.</li>
<li>Key Condition: Antinode occurs if two antennas of the same frequency are aligned such that one is twice as far from the antinode as the other.</li>
<li>Steps:
<ol class="org-ol">
<li>Parse the input map to locate antennas grouped by their frequency.</li>
<li>For each frequency group, iterate through all antenna pairs.</li>
<li>Calculate potential antinode positions based on the defined condition.</li>
<li>Use a Set to store unique antinode positions.</li>
<li>Return the size of the Set as the total unique antinode count.</li>
</ol></li>
<li>Code Snippet:</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">for (int i = 0; i &lt; locations.size(); i++) {
for (int j = i + 1; j &lt; locations.size(); j++) {
int[] a = locations.get(i);
int[] b = locations.get(j);
// Calculate midpoints and validate conditions
if ((b[0] - a[0]) % 2 == 0 &amp;&amp; (b[1] - a[1]) % 2 == 0) {
int midRow = (a[0] + b[0]) / 2;
int midCol = (a[1] + b[1]) / 2;
antinodes.add(midRow + "," + midCol);
}
}
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orgf551b98" class="outline-3">
<h3 id="orgf551b98"><a href="#orgf551b98">Part Two</a></h3>
<div class="outline-text-3" id="text-orgf551b98">
<ul class="org-ul">
<li>Objective: Update the model to include all positions perfectly aligned with at least two antennas of the same frequency.</li>
<li>Key Changes:
<ul class="org-ul">
<li>Antinodes occur at all positions along the straight line between antennas of the same frequency.</li>
<li>Antennas themselves are also antinodes unless they are the only instance of their frequency.</li>
</ul></li>
<li>Steps:
<ol class="org-ol">
<li>Parse the input map and group antennas by frequency.</li>
<li>For each pair of antennas of the same frequency:
<ul class="org-ul">
<li>Calculate direction vectors (reduced using GCD).</li>
<li>Traverse along the direction vector in both forward and backward directions, marking all valid positions as antinodes.</li>
</ul></li>
<li>Add each antenna location directly to the set of antinodes.</li>
<li>Return the size of the unique antinode set.</li>
</ol></li>
<li>Code Snippet:</li>
</ul>
<div class="org-src-container">
<pre class="src src-java">int dr = b[0] - a[0];
int dc = b[1] - a[1];
int gcd = gcd(Math.abs(dr), Math.abs(dc));
dr /= gcd;
dc /= gcd;
// Traverse along the line
int row = a[0], col = a[1];
while (isWithinBounds(row, col, rows, cols)) {
antinodes.add(row + "," + col);
row += dr;
col += dc;
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orga5b5db3" class="outline-3">
<h3 id="orga5b5db3"><a href="#orga5b5db3">Notes on Implementation</a></h3>
<div class="outline-text-3" id="text-orga5b5db3">
<ul class="org-ul">
<li>Data Structures:
<ul class="org-ul">
<li>Map&lt;Character, List&lt;int[]&gt;&gt;: Stores antenna positions by frequency.</li>
<li>Set&lt;String&gt;: Tracks unique antinode positions.</li>
</ul></li>
<li>Utility Functions:
<ul class="org-ul">
<li>isWithinBounds: Ensures coordinates are within map dimensions.</li>
<li>gcd: Simplifies direction vectors to avoid redundant calculations.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org537add5" class="outline-2">
<h2 id="org537add5"><a href="#org537add5">Day 9</a></h2>
<div class="outline-text-2" id="text-org537add5">
</div>
<div id="outline-container-org74b3db0" class="outline-3">
<h3 id="org74b3db0"><a href="#org74b3db0">Part 1: Manipulating and Calculating Disk Placement</a></h3>
<div class="outline-text-3" id="text-org74b3db0">
<p>
Concept: Creating and manipulating a disk structure based on input.
Input is split into alternating &ldquo;id&rdquo; and &ldquo;space&rdquo; values.
Example of creating the disk:
</p>
<div class="org-src-container">
<pre class="src src-java">for (String character : lines.getFirst().split("")) {
int num = Integer.parseInt(character);
if (space) {
for (int i = 0; i &lt; num; i++) disk.add(-1);
} else {
for (int i = 0; i &lt; num; i++) disk.add(id);
id++;
}
space = !space;
}
</pre>
</div>
<ul class="org-ul">
<li>Key Learning: Understanding alternating patterns in input and their translation to a data structure.</li>
<li>Problem Solving: Adjusting misplaced items.
<ul class="org-ul">
<li>Utilize a while loop to locate and correct misplaced &ldquo;-1&rdquo; values in the disk.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">if (disk.get(i) == -1) {
int val = -1;
while (val == -1) {
val = disk.removeLast();
}
disk.add(i, val);
}
</pre>
</div></li>
</ul></li>
<li>Final Calculation: Using BigInteger for large numbers.
<ul class="org-ul">
<li>Formula: index * value for each position in the disk.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">BigInteger count = BigInteger.ZERO;
for (int i = 0; i &lt; disk.size(); i++) {
count = count.add(BigInteger.valueOf(i).multiply(BigInteger.valueOf(disk.get(i))));
}
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-org6f3ce00" class="outline-3">
<h3 id="org6f3ce00"><a href="#org6f3ce00">Part 2: Advanced Disk Rearrangement with Blocks</a></h3>
<div class="outline-text-3" id="text-org6f3ce00">
<ul class="org-ul">
<li>Concept: Representing disk as a list of Block objects.
<ul class="org-ul">
<li>Block stores size and id.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">public static class Block {
private int size;
private int id;
public Block(int size, int id) {
this.size = size;
this.id = id;
}
}
</pre>
</div></li>
</ul></li>
<li>Key Learning: Encapsulating logic into objects improves clarity and scalability.</li>
<li>Space Management: Finding and fitting blocks into available spaces.
<ul class="org-ul">
<li>Utilize a fit method to split or match blocks.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">public List&lt;Block&gt; fit(Block work) {
if (work.size &gt; this.size) return null;
List&lt;Block&gt; newList = new ArrayList&lt;&gt;();
newList.add(work);
if (work.size &lt; this.size) {
newList.add(new Block(this.size - work.size, -1));
}
return newList;
}
</pre>
</div></li>
</ul></li>
<li>Problem Solving: Iterating backward through the disk to find and rearrange blocks into spaces.
<ul class="org-ul">
<li>Restart loop when a fit is found to ensure proper placement.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">for (int i = 0; i &lt; diskPlace; i++) {
Block possibleSpace = disk.get(i);
if (possibleSpace.getId() == -1) {
List&lt;Block&gt; blocks = possibleSpace.fit(work);
if (blocks != null) {
disk.remove(diskPlace);
disk.add(diskPlace, new Block(work.getSize(), -1));
for (int j = blocks.size() - 1; j &gt;= 0; j--) {
disk.add(i, blocks.get(j));
}
break;
}
}
}
</pre>
</div></li>
</ul></li>
<li>Final Calculation: Summing placements using block properties.
<ul class="org-ul">
<li>Ensure large calculations are done efficiently with BigInteger.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">BigInteger count = BigInteger.ZERO;
int placement = 0;
for (Block block : disk) {
if (block.getId() != -1) {
for (int j = 0; j &lt; block.getSize(); j++) {
count = count.add(BigInteger.valueOf(placement).multiply(BigInteger.valueOf(block.getId())));
placement++;
}
} else {
placement += block.getSize();
}
}
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org2a148d7" class="outline-2">
<h2 id="org2a148d7"><a href="#org2a148d7">Day 10</a></h2>
<div class="outline-text-2" id="text-org2a148d7">
</div>
<div id="outline-container-org4757749" class="outline-3">
<h3 id="org4757749"><a href="#org4757749">Part 1: Counting Trails in a 2D Grid</a></h3>
<div class="outline-text-3" id="text-org4757749">
<ul class="org-ul">
<li>Concept: Navigating and processing a 2D grid based on specific rules.
<ul class="org-ul">
<li>Input is parsed into a 2D map from a list of strings.</li>
<li><p>
Conversion logic for parsing:
</p>
<div class="org-src-container">
<pre class="src src-java">int[] map = new int[width * height];
int i = 0;
for (String line : lines) {
if (line.isBlank()) continue;
for (String character : line.trim().split("")) {
map[i] = Integer.parseInt(character);
i++;
}
}
</pre>
</div></li>
</ul></li>
<li>Recursive Approach: Traversing paths with a helper function countTrails.
<ul class="org-ul">
<li>Recursion halts on boundaries, invalid values, or when a sequence completes.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">private static Set&lt;Point&gt; countTrails(int[] map, int x, int y, int width, int height, int val) {
if (x &gt;= width || y &gt;= height || x &lt; 0 || y &lt; 0 || map[y * width + x] != val) return new HashSet&lt;&gt;();
if (val == 9) return Set.of(new Point(9, x, y));
Set&lt;Point&gt; result = new HashSet&lt;&gt;();
result.addAll(countTrails(map, x + 1, y, width, height, val + 1));
result.addAll(countTrails(map, x - 1, y, width, height, val + 1));
result.addAll(countTrails(map, x, y + 1, width, height, val + 1));
result.addAll(countTrails(map, x, y - 1, width, height, val + 1));
return result;
}
</pre>
</div></li>
</ul></li>
<li>Key Learning: Recursive exploration of a grid with stateful logic for trail validity.</li>
<li>Result Calculation: Sum the size of all unique trail sets.
<ul class="org-ul">
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">long count = 0;
for (int y = 0; y &lt; height; y++) {
for (int x = 0; x &lt; width; x++) {
Set&lt;Point&gt; set = countTrails(map, x, y, width, height, 0);
count += set.size();
}
}
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgc7adbf6" class="outline-3">
<h3 id="orgc7adbf6"><a href="#orgc7adbf6">Part 2: Enhanced Trail Counting with Weighted Points</a></h3>
<div class="outline-text-3" id="text-orgc7adbf6">
<ul class="org-ul">
<li>Concept: Counting trails with weights using a Map&lt;Point, Integer&gt; for aggregation.
<ul class="org-ul">
<li>Modified helper function countTrails2 tracks weights for each point.</li>
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">private static Map&lt;Point, Integer&gt; countTrails2(int[] map, int x, int y, int width, int height, int val) {
if (x &gt;= width || y &gt;= height || x &lt; 0 || y &lt; 0 || map[y * width + x] != val) return new HashMap&lt;&gt;();
if (val == 9) return Map.of(new Point(1, x, y), 1);
Map&lt;Point, Integer&gt; result = new HashMap&lt;&gt;();
checkDirection(map, x + 1, y, width, height, val, result);
checkDirection(map, x - 1, y, width, height, val, result);
checkDirection(map, x, y + 1, width, height, val, result);
checkDirection(map, x, y - 1, width, height, val, result);
return result;
}
</pre>
</div></li>
</ul></li>
<li>Helper Method: checkDirection facilitates merging results for trail continuity.
<ul class="org-ul">
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">private static void checkDirection(int[] map, int x, int y, int width, int height, int val, Map&lt;Point, Integer&gt; result) {
Map&lt;Point, Integer&gt; res = countTrails2(map, x, y, width, height, val + 1);
for (Point p : res.keySet()) {
result.merge(p, res.get(p), Integer::sum);
}
}
</pre>
</div></li>
</ul></li>
<li>Key Learning: Using a Map to manage complex trail state and weights for precise calculations.</li>
<li>Result Calculation: Sum weighted trail counts.
<ul class="org-ul">
<li><p>
Example:
</p>
<div class="org-src-container">
<pre class="src src-java">long count = 0;
for (int y = 0; y &lt; height; y++) {
for (int x = 0; x &lt; width; x++) {
Map&lt;Point, Integer&gt; res = countTrails2(map, x, y, width, height, 0);
for (int value : res.values()) {
count += value;
}
}
}
</pre>
</div></li>
</ul></li>
<li>Encapsulation of grid points as objects (Point) simplifies hash-based operations and improves code clarity.</li>
<li>Using collections like Set and Map effectively is crucial for aggregating results in a structured way.</li>
</ul>
<p>
Would you like to make any adjustments or add further examples?
</p>
</div>
</div>
</div>
<div id="outline-container-orgf810444" class="outline-2">
<h2 id="orgf810444"><a href="#orgf810444">Day 12</a></h2>
<div class="outline-text-2" id="text-orgf810444">
</div>
<div id="outline-container-org15b04d1" class="outline-3">
<h3 id="org15b04d1"><a href="#org15b04d1">Core Logic and Functionality</a></h3>
<div class="outline-text-3" id="text-org15b04d1">
<ol class="org-ol">
<li>Coordinates Mapping:
<ul class="org-ul">
<li><p>
A map (coords) stores coordinates of each character from the input. For each character, all the coordinates where it appears are stored as Point objects.
</p>
<div class="org-src-container">
<pre class="src src-java">for (int i = 0; i &lt; in.size(); i++) {
for (int j = 0; j &lt; in.get(i).length(); j++) {
coords.putIfAbsent(in.get(i).charAt(j), new ArrayList&lt;&gt;());
coords.get(in.get(i).charAt(j)).add(new Point(i, j));
}
}
</pre>
</div></li>
</ul></li>
<li>Flood Fill Algorithm with Stack:
<ul class="org-ul">
<li><p>
A flood-fill algorithm is used to explore areas connected by the same character. The algorithm uses a stack to explore adjacent points recursively.
</p>
<div class="org-src-container">
<pre class="src src-java">ArrayDeque&lt;Point&gt; stack = new ArrayDeque&lt;&gt;();
stack.push(co);
while (!stack.isEmpty()) {
var cur = stack.pop();
// explore neighbors
}
</pre>
</div></li>
</ul></li>
<li>Fence Counting:
<ul class="org-ul">
<li><p>
For each region, the number of &ldquo;fences&rdquo; (edges where the character changes) is counted. The algorithm checks for boundaries or differing characters adjacent to each point.
</p>
<div class="org-src-container">
<pre class="src src-java">if (nd.x &lt; 0 || nd.y &lt; 0 || nd.x &gt;= in.size() || nd.y &gt;= in.get(0).length()) {
fence++;
} else if (in.get(nd.x).charAt(nd.y) != ch) {
fence++;
}
</pre>
</div></li>
</ul></li>
<li>Side Fetching Logic:
<ul class="org-ul">
<li><p>
The fetchSides() method computes the number of &ldquo;sides&rdquo; based on the placement of fences, counting how the fences are arranged along rows and columns.
</p>
<div class="org-src-container">
<pre class="src src-java">for (var xx : cols.keySet()) {
var xl = cols.get(xx);
Collections.sort(xl);
// logic for sorting and counting sides
}
</pre>
</div></li>
</ul></li>
<li>Area and Fence Calculations:
<ul class="org-ul">
<li><p>
For each character, the area (number of connected points) and the number of fences are calculated. The result is a product of area and fence count.
</p>
<div class="org-src-container">
<pre class="src src-java">ret += area * fence;
p2 += area * fetchSides(fences);
</pre>
</div></li>
</ul></li>
</ol>
</div>
<div id="outline-container-org954dfa1" class="outline-4">
<h4 id="org954dfa1"><a href="#org954dfa1">Core Logic and Functionality</a></h4>
<div class="outline-text-4" id="text-org954dfa1">
<ul class="org-ul">
<li>Coordinates mapping using a Map&lt;Character, List&lt;Point&gt;&gt; to track character positions.</li>
<li>Flood-fill algorithm using a stack to explore regions of connected characters.</li>
<li>Fence counting logic to identify boundaries and different characters.</li>
<li>Side fetching logic to count the number of fences arranged along rows and columns.</li>
<li>Area and fence calculations for each region to compute the final result.</li>
</ul>
</div>
</div>
</div>
</div>
<div id="outline-container-org7b92c80" class="outline-2">
<h2 id="org7b92c80"><a href="#org7b92c80">Day 13</a></h2>
<div class="outline-text-2" id="text-org7b92c80">
</div>
<div id="outline-container-org7d32a65" class="outline-3">
<h3 id="org7d32a65"><a href="#org7d32a65">Part 1: Parsing Input and Solving Simultaneous Equations</a></h3>
<div class="outline-text-3" id="text-org7d32a65">
<ul class="org-ul">
<li>Goal: Parse input, extract button coefficients and prize values, solve simultaneous equations to find valid token costs.</li>
<li>Key Concepts:
<ul class="org-ul">
<li>Input parsing using BufferedReader.</li>
<li>Using determinants to solve simultaneous equations.</li>
<li>Validating solutions for constraints (non-negative integers, valid m/n).</li>
</ul></li>
<li>Code Snippets:
<ul class="org-ul">
<li><p>
Parsing Input:
</p>
<div class="org-src-container">
<pre class="src src-java">if (line.startsWith("Button A:")) {
String[] parts = line.split(":")[1].split(",");
current = new ButtonPrize();
current.buttonAX = Integer.parseInt(parts[0].trim().split("\\+")[1]);
current.buttonAY = Integer.parseInt(parts[1].trim().split("\\+")[1]);
}
</pre>
</div></li>
<li><p>
Solving Simultaneous Equations:
</p>
<div class="org-src-container">
<pre class="src src-java">int determinant = buttonAX * buttonBY - buttonBX * buttonAY;
if (determinant == 0) return 0; // No solution
long mNumerator = prizeX * buttonBY - prizeY * buttonBX;
long nNumerator = prizeY * buttonAX - prizeX * buttonAY;
if (mNumerator % determinant != 0 || nNumerator % determinant != 0) return 0;
long m = mNumerator / determinant;
long n = nNumerator / determinant;
return (m &lt; 0 || n &lt; 0) ? 0 : m * 3 + n; // Calculate token costs
</pre>
</div></li>
</ul></li>
<li>Challenges Faced:
<ul class="org-ul">
<li>Edge cases with determinant = 0 or invalid input format.</li>
<li>Ensuring no negative values for m/n.</li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgdd31489" class="outline-3">
<h3 id="orgdd31489"><a href="#orgdd31489">Part 2: Transforming Input Data</a></h3>
<div class="outline-text-3" id="text-orgdd31489">
<ul class="org-ul">
<li>Goal: Modify prize values with a fixed offset before calculations.</li>
<li>Key Concepts:
<ul class="org-ul">
<li>Transforming input data programmatically.</li>
<li>Reusing the existing calculation logic after transformation.</li>
</ul></li>
<li>Code Snippets:
<ul class="org-ul">
<li><p>
Prepending Offset to Prize Values:
</p>
<div class="org-src-container">
<pre class="src src-java">private void prependZeroes(ButtonPrize bp) {
bp.setPrizeX(bp.getPrizeX() + 10000000000000L);
bp.setPrizeY(bp.getPrizeY() + 10000000000000L);
}
</pre>
</div></li>
<li><p>
Reusing Logic:
</p>
<div class="org-src-container">
<pre class="src src-java">for (ButtonPrize bp : data) {
prependZeroes(bp);
count_part2 += calculateSimultaneousEquations(bp.getButtonAX(), bp.getButtonAY(),
bp.getButtonBX(), bp.getButtonBY(),
bp.getPrizeX(), bp.getPrizeY());
}
</pre>
</div></li>
</ul></li>
<li>Challenges Faced:
<ul class="org-ul">
<li>Avoiding modification of original input logic while adding transformations.</li>
<li>Maintaining readability and modularity.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-org244fadc" class="outline-2">
<h2 id="org244fadc"><a href="#org244fadc">Day 14</a></h2>
<div class="outline-text-2" id="text-org244fadc">
</div>
<div id="outline-container-orgf3e9f5e" class="outline-3">
<h3 id="orgf3e9f5e"><a href="#orgf3e9f5e">Part 1: Simulating Robot Movement</a></h3>
<div class="outline-text-3" id="text-orgf3e9f5e">
<ul class="org-ul">
<li>Concept: Simulating the movement of robots on a grid, wrapping their positions around the edges.
<ul class="org-ul">
<li>The grid has dimensions 101x103, and the robot positions wrap around when they move out of bounds.</li>
<li><p>
Wrapping is implemented using a helper method:
</p>
<div class="org-src-container">
<pre class="src src-java">public static int wrap(int value, int max) {
return ((value % max) + max) % max;
}
</pre>
</div></li>
</ul></li>
<li>Key Learning: Efficiently handling movement on a toroidal grid (wrap-around behavior).</li>
<li>Quadrant Assignment:
<ul class="org-ul">
<li>Robots are excluded from the middle row and column (x=50, y=51).</li>
<li><p>
Quadrant assignments are based on the x and y positions:
</p>
<div class="org-src-container">
<pre class="src src-java">if (x &lt; 50 &amp;&amp; y &lt; 51) {
quadrantCounts[0]++; // Top-left
} else if (x &gt;= 50 &amp;&amp; y &lt; 51) {
quadrantCounts[1]++; // Top-right
} else if (x &lt; 50 &amp;&amp; y &gt;= 51) {
quadrantCounts[2]++; // Bottom-left
} else if (x &gt;= 50 &amp;&amp; y &gt;= 51) {
quadrantCounts[3]++; // Bottom-right
}
</pre>
</div></li>
</ul></li>
<li>Safety Factor Calculation:
<ul class="org-ul">
<li><p>
The safety factor is the product of the number of robots in each quadrant:
</p>
<div class="org-src-container">
<pre class="src src-java">int safetyFactor = 1;
for (int count : quadrantCounts) {
safetyFactor *= count;
}
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orga90279e" class="outline-3">
<h3 id="orga90279e"><a href="#orga90279e">Part 2: Identifying Patterns in Robot Positions</a></h3>
<div class="outline-text-3" id="text-orga90279e">
<ul class="org-ul">
<li>Concept: Simulating grid states to find a specific pattern of robot alignment.
<ul class="org-ul">
<li>Robots move based on their initial velocity, and their positions are updated iteratively.</li>
<li>A grid is used to track robot positions, and columns are checked for specific patterns.</li>
</ul></li>
<li>Key Learning: Efficiently detecting consecutive robot positions in a grid column.</li>
<li>Grid Initialization:
<ul class="org-ul">
<li><p>
A helper method initializes a 2D grid with given dimensions:
</p>
<div class="org-src-container">
<pre class="src src-java">private int[][] initializeGrid(int rows, int cols) {
return new int[rows][cols];
}
</pre>
</div></li>
</ul></li>
<li>Position Calculation:
<ul class="org-ul">
<li><p>
New positions are computed using the robot&rsquo;s velocity and current step, with wrapping:
</p>
<div class="org-src-container">
<pre class="src src-java">private int[] calculateNewPosition(int[] position, int[] velocity, int step, int[] tileDimensions) {
return new int[] {
(position[0] + step * (tileDimensions[0] + velocity[0])) % tileDimensions[0],
(position[1] + step * (tileDimensions[1] + velocity[1])) % tileDimensions[1]
};
}
</pre>
</div></li>
</ul></li>
<li>Pattern Detection:
<ul class="org-ul">
<li><p>
A helper method checks for consecutive robots in a column:
</p>
<div class="org-src-container">
<pre class="src src-java">private boolean hasConsecutiveInRow(List&lt;Integer&gt; positions, int requiredConsecutive) {
Collections.sort(positions);
int consecutiveCount = 0;
for (int i = 1; i &lt; positions.size(); i++) {
if (positions.get(i) - positions.get(i - 1) == 1) {
consecutiveCount++;
if (consecutiveCount &gt;= requiredConsecutive) {
return true;
}
} else {
consecutiveCount = 0;
}
}
return false;
}
</pre>
</div></li>
</ul></li>
<li>Stopping Condition:
<ul class="org-ul">
<li>Simulation stops when a column has at least requiredConsecutive robots aligned.</li>
</ul></li>
</ul>
<p>
&#x2014;
</p>
<p>
### Supporting Components
</p>
<ul class="org-ul">
<li>Data Representation:
<ul class="org-ul">
<li><p>
PointAndVelocity encapsulates robot data, including position (PX, PY) and velocity (VX, VY):
</p>
<div class="org-src-container">
<pre class="src src-java">public static class PointAndVelocity {
private int PX;
private int PY;
private int VX;
private int VY;
// Getters and setters
public int getVX() { return VX; }
public void setVX(int vX) { VX = vX; }
public int getVY() { return VY; }
public void setVY(int vY) { VY = vY; }
public int getPX() { return PX; }
public void setPX(int pX) { PX = pX; }
public int getPY() { return PY; }
public void setPY(int pY) { PY = pY; }
}
</pre>
</div></li>
</ul></li>
<li>Input Parsing:
<ul class="org-ul">
<li><p>
Robot data is parsed from a file or input list. Each robot&rsquo;s position and velocity are extracted:
</p>
<div class="org-src-container">
<pre class="src src-java">private List&lt;PointAndVelocity&gt; getPointAndVelocities() {
List&lt;PointAndVelocity&gt; pvs = new ArrayList&lt;&gt;();
try (BufferedReader reader = new BufferedReader(new FileReader(fetchFilePath()))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" ");
PointAndVelocity pav = new PointAndVelocity();
pav.setPX(Integer.parseInt(parts[0].split(",")[0].replace("p=", "")));
pav.setPY(Integer.parseInt(parts[0].split(",")[1].replace("p=", "")));
pav.setVX(Integer.parseInt(parts[1].split(",")[0].replace("v=", "")));
pav.setVY(Integer.parseInt(parts[1].split(",")[1].replace("v=", "")));
pvs.add(pav);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return pvs;
}
</pre>
</div></li>
</ul></li>
<li>Simulation Control:
<ul class="org-ul">
<li>Part 1 iterates for 100 steps, while Part 2 continues until a pattern is found or the maximum steps are reached.</li>
</ul></li>
</ul>
</div>
</div>
</div>
<div id="outline-container-orga02de05" class="outline-2">
<h2 id="orga02de05"><a href="#orga02de05"></a></h2>
<div class="outline-text-2" id="text-orga02de05">
<p class="backlinks-section" id="backlinks">
Backlinks
</p>
<ul class="org-ul backlinks-list">
<li><a href="20241210001045-technical.html#ID-2f285f04-fcf4-4ade-a1ac-2c50b43d529a">Technical MOC</a></li>
</ul>
</div>
</div>
</div>
</div></article></div></div>
<div id="postamble" class="status">
<footer>
<div class="copyright-container">
<div class="copyright">
Copyright &copy; 2022-2025 Zaine Qayyum. All rights reserved unless otherwise noted.</div></div>
<div class="generated">
Created with <a href="https://www.gnu.org/software/emacs/">Emacs</a> 30.2 (<a href="https://orgmode.org">Org</a> mode 9.7.11) on <a href="https://www.archlinux.org/">Arch</a> <a href="https://www.gnu.org">GNU</a>/<a href="https://www.kernel.org/">Linux</a>
</div>
</footer>
</div>
</body>
</html>