<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>adventofcode &amp;mdash; may0x0</title>
    <link>https://blog.0x0.sk/may/tag:adventofcode</link>
    <description>🌸🐈 (MayMeow)</description>
    <pubDate>Thu, 30 Apr 2026 04:29:22 +0000</pubDate>
    <item>
      <title>🎄 Advent of Code &#39;25 Day 1: Secret Entrance</title>
      <link>https://blog.0x0.sk/may/advent-of-code-25-day-1-secret-entrance</link>
      <description>&lt;![CDATA[For Day 1 I had to open a safe with a dial numbered 0–99. Here’s how both halves of the puzzle fell.&#xA;&#xA;!--more--&#xA;&#xA;Part 1 – Counting end-of-rotation zeros&#xA;The dial starts at 50 and each instruction looks like L68 or R48. I only needed to know how many times the dial ended on 0 after finishing each rotation.&#xA;&#xA;Implementation notes:&#xA;Parse every instruction once.&#xA;Track the current dial position; rotate by converting L to negative steps and R to positive steps.&#xA;Apply the delta with (position + delta) mod 100 keeping values non-negative.&#xA;Increment the answer whenever the resulting position equals 0.&#xA;&#xA;This runs in O(n) with n rotations and needs only a handful of integers.&#xA;&#xA;const fs = require(&#39;fs&#39;);&#xA;const path = require(&#39;path&#39;);&#xA;&#xA;const DIALSIZE = 100;&#xA;const STARTPOSITION = 50;&#xA;&#xA;const inputPath = process.argv[2] ?? path.join(_dirname, &#39;input.txt&#39;);&#xA;&#xA;function readLines(filePath) {&#xA;    try {&#xA;        const raw = fs.readFileSync(filePath, &#39;utf8&#39;);&#xA;        return raw&#xA;        .split(/\r?\n/)&#xA;        .map((line) =  line.trim())&#xA;        .filter((line) =  line.length   0);&#xA;    } catch (error) {&#xA;        throw new Error(Unable to read input file: ${filePath});&#xA;    }&#xA;}&#xA;&#xA;function rotate(position, instruction) {&#xA;    const direction = instruction[0];&#xA;    const distance = Number(instruction.slice(1));&#xA;&#xA;    if (!Number.isFinite(distance)) {&#xA;        throw new Error(Invalid distance in instruction: ${instruction});&#xA;    }&#xA;&#xA;    if (direction !== &#39;L&#39; &amp;&amp; direction !== &#39;R&#39;) {&#xA;        throw new Error(Invalid direction in instruction: ${instruction});&#xA;    }&#xA;&#xA;    const delta = direction === &#39;L&#39; ? -distance : distance;&#xA;    const next = (position + delta) % DIALSIZE;&#xA;    return (next + DIALSIZE) % DIALSIZE; // ensure non-negative&#xA;}&#xA;&#xA;function countZeroStops(instructions) {&#xA;    let position = STARTPOSITION;&#xA;    let zeroCount = 0;&#xA;&#xA;    for (const instruction of instructions) {&#xA;        position = rotate(position, instruction);&#xA;        if (position === 0) {&#xA;        zeroCount += 1;&#xA;        }&#xA;    }&#xA;&#xA;    return zeroCount;&#xA;}&#xA;&#xA;function main() {&#xA;    const instructions = readLines(inputPath);&#xA;    if (instructions.length === 0) {&#xA;        console.log(&#39;0&#39;);&#xA;        return;&#xA;    }&#xA;&#xA;    const result = countZeroStops(instructions);&#xA;    console.log(result.toString());&#xA;}&#xA;&#xA;main();&#xA;&#xA;Part 2 – Counting every click that lands on zero&#xA;The “method 0x434C49434B” twist meant counting every individual click that passes through 0, even mid-rotation. A rotation of R1000 from 50 hits 0 ten times. I handled this with simple arithmetic:&#xA;&#xA;Given the current position and direction, compute how many clicks it takes to reach the next zero (stepsUntilZero).&#xA;If the rotation distance is shorter, no zeros occur; otherwise count one for that first hit plus an additional floor((distance - firstHit)/100) for every full revolution afterwards.&#xA;Sum those counts and still update the final position with the same rotation logic from Part 1.&#xA;&#xA;The whole solver stays O(n) but now also detects long runs efficiently without simulating each click.&#xA;&#xA;const fs = require(&#39;fs&#39;);&#xA;const path = require(&#39;path&#39;);&#xA;&#xA;const DIALSIZE = 100;&#xA;const STARTPOSITION = 50;&#xA;&#xA;const inputPath = process.argv[2] ?? path.join(dirname, &#39;input.txt&#39;);&#xA;&#xA;function readLines(filePath) {&#xA;    try {&#xA;        const raw = fs.readFileSync(filePath, &#39;utf8&#39;);&#xA;        return raw&#xA;        .split(/\r?\n/)&#xA;        .map((line) =  line.trim())&#xA;        .filter((line) =  line.length   0);&#xA;    } catch (error) {&#xA;        throw new Error(Unable to read input file: ${filePath});&#xA;    }&#xA;}&#xA;&#xA;function rotate(position, instruction) {&#xA;    const direction = instruction[0];&#xA;    const distance = Number(instruction.slice(1));&#xA;&#xA;    if (!Number.isFinite(distance)) {&#xA;        throw new Error(Invalid distance in instruction: ${instruction});&#xA;    }&#xA;&#xA;    if (direction !== &#39;L&#39; &amp;&amp; direction !== &#39;R&#39;) {&#xA;        throw new Error(Invalid direction in instruction: ${instruction});&#xA;    }&#xA;&#xA;    const delta = direction === &#39;L&#39; ? -distance : distance;&#xA;    const next = (position + delta) % DIALSIZE;&#xA;    return (next + DIALSIZE) % DIALSIZE;&#xA;}&#xA;&#xA;function positiveMod(value, mod) {&#xA;    return ((value % mod) + mod) % mod;&#xA;}&#xA;&#xA;function stepsUntilZero(position, direction) {&#xA;    const remainder = positiveMod(position, DIALSIZE);&#xA;    if (remainder === 0) {&#xA;        return DIALSIZE;&#xA;    }&#xA;    if (direction === &#39;R&#39;) {&#xA;        return DIALSIZE - remainder;&#xA;    }&#xA;    return remainder;&#xA;}&#xA;&#xA;function countZeroClicksForRotation(position, direction, distance) {&#xA;    if (distance &lt;= 0) {&#xA;        return 0;&#xA;    }&#xA;&#xA;    const firstHit = stepsUntilZero(position, direction);&#xA;    if (firstHit   distance) {&#xA;        return 0;&#xA;    }&#xA;&#xA;    return 1 + Math.floor((distance - firstHit) / DIALSIZE);&#xA;}&#xA;&#xA;function countZeroClicks(instructions) {&#xA;    let position = START_POSITION;&#xA;    let zeroCount = 0;&#xA;&#xA;    for (const instruction of instructions) {&#xA;        const direction = instruction[0];&#xA;        const distance = Number(instruction.slice(1));&#xA;&#xA;        zeroCount += countZeroClicksForRotation(position, direction, distance);&#xA;        position = rotate(position, instruction);&#xA;    }&#xA;&#xA;    return zeroCount;&#xA;}&#xA;&#xA;function main() {&#xA;    const instructions = readLines(inputPath);&#xA;    if (instructions.length === 0) {&#xA;        console.log(&#39;0&#39;);&#xA;        return;&#xA;    }&#xA;&#xA;    const result = countZeroClicks(instructions);&#xA;    console.log(result.toString());&#xA;}&#xA;&#xA;main();&#xA;&#xA;adventOfCode]]&gt;</description>
      <content:encoded><![CDATA[<p>For Day 1 I had to open a safe with a dial numbered 0–99. Here’s how both halves of the puzzle fell.</p>



<h2 id="part-1-counting-end-of-rotation-zeros">Part 1 – Counting end-of-rotation zeros</h2>

<p>The dial starts at 50 and each instruction looks like <code>L68</code> or <code>R48</code>. I only needed to know how many times the dial ended on 0 <strong>after finishing</strong> each rotation.</p>

<p>Implementation notes:
– Parse every instruction once.
– Track the current dial position; rotate by converting <code>L</code> to negative steps and <code>R</code> to positive steps.
– Apply the delta with <code>(position + delta) mod 100</code> keeping values non-negative.
– Increment the answer whenever the resulting position equals 0.</p>

<p>This runs in O(n) with n rotations and needs only a handful of integers.</p>

<pre><code class="language-js">const fs = require(&#39;fs&#39;);
const path = require(&#39;path&#39;);

const DIAL_SIZE = 100;
const START_POSITION = 50;

const inputPath = process.argv[2] ?? path.join(__dirname, &#39;input.txt&#39;);

function readLines(filePath) {
    try {
        const raw = fs.readFileSync(filePath, &#39;utf8&#39;);
        return raw
        .split(/\r?\n/)
        .map((line) =&gt; line.trim())
        .filter((line) =&gt; line.length &gt; 0);
    } catch (error) {
        throw new Error(`Unable to read input file: ${filePath}`);
    }
}

function rotate(position, instruction) {
    const direction = instruction[0];
    const distance = Number(instruction.slice(1));

    if (!Number.isFinite(distance)) {
        throw new Error(`Invalid distance in instruction: ${instruction}`);
    }

    if (direction !== &#39;L&#39; &amp;&amp; direction !== &#39;R&#39;) {
        throw new Error(`Invalid direction in instruction: ${instruction}`);
    }

    const delta = direction === &#39;L&#39; ? -distance : distance;
    const next = (position + delta) % DIAL_SIZE;
    return (next + DIAL_SIZE) % DIAL_SIZE; // ensure non-negative
}

function countZeroStops(instructions) {
    let position = START_POSITION;
    let zeroCount = 0;

    for (const instruction of instructions) {
        position = rotate(position, instruction);
        if (position === 0) {
        zeroCount += 1;
        }
    }

    return zeroCount;
}

function main() {
    const instructions = readLines(inputPath);
    if (instructions.length === 0) {
        console.log(&#39;0&#39;);
        return;
    }

    const result = countZeroStops(instructions);
    console.log(result.toString());
}

main();
</code></pre>

<h2 id="part-2-counting-every-click-that-lands-on-zero">Part 2 – Counting every click that lands on zero</h2>

<p>The “method 0x434C49434B” twist meant counting every individual click that passes through 0, even mid-rotation. A rotation of <code>R1000</code> from 50 hits 0 ten times. I handled this with simple arithmetic:</p>
<ol><li>Given the current position and direction, compute how many clicks it takes to reach the next zero (<code>stepsUntilZero</code>).</li>
<li>If the rotation distance is shorter, no zeros occur; otherwise count one for that first hit plus an additional <code>floor((distance - firstHit)/100)</code> for every full revolution afterwards.</li>
<li>Sum those counts and still update the final position with the same rotation logic from Part 1.</li></ol>

<p>The whole solver stays O(n) but now also detects long runs efficiently without simulating each click.</p>

<pre><code class="language-js">const fs = require(&#39;fs&#39;);
const path = require(&#39;path&#39;);

const DIAL_SIZE = 100;
const START_POSITION = 50;

const inputPath = process.argv[2] ?? path.join(__dirname, &#39;input.txt&#39;);

function readLines(filePath) {
    try {
        const raw = fs.readFileSync(filePath, &#39;utf8&#39;);
        return raw
        .split(/\r?\n/)
        .map((line) =&gt; line.trim())
        .filter((line) =&gt; line.length &gt; 0);
    } catch (error) {
        throw new Error(`Unable to read input file: ${filePath}`);
    }
}

function rotate(position, instruction) {
    const direction = instruction[0];
    const distance = Number(instruction.slice(1));

    if (!Number.isFinite(distance)) {
        throw new Error(`Invalid distance in instruction: ${instruction}`);
    }

    if (direction !== &#39;L&#39; &amp;&amp; direction !== &#39;R&#39;) {
        throw new Error(`Invalid direction in instruction: ${instruction}`);
    }

    const delta = direction === &#39;L&#39; ? -distance : distance;
    const next = (position + delta) % DIAL_SIZE;
    return (next + DIAL_SIZE) % DIAL_SIZE;
}

function positiveMod(value, mod) {
    return ((value % mod) + mod) % mod;
}

function stepsUntilZero(position, direction) {
    const remainder = positiveMod(position, DIAL_SIZE);
    if (remainder === 0) {
        return DIAL_SIZE;
    }
    if (direction === &#39;R&#39;) {
        return DIAL_SIZE - remainder;
    }
    return remainder;
}

function countZeroClicksForRotation(position, direction, distance) {
    if (distance &lt;= 0) {
        return 0;
    }

    const firstHit = stepsUntilZero(position, direction);
    if (firstHit &gt; distance) {
        return 0;
    }

    return 1 + Math.floor((distance - firstHit) / DIAL_SIZE);
}

function countZeroClicks(instructions) {
    let position = START_POSITION;
    let zeroCount = 0;

    for (const instruction of instructions) {
        const direction = instruction[0];
        const distance = Number(instruction.slice(1));

        zeroCount += countZeroClicksForRotation(position, direction, distance);
        position = rotate(position, instruction);
    }

    return zeroCount;
}

function main() {
    const instructions = readLines(inputPath);
    if (instructions.length === 0) {
        console.log(&#39;0&#39;);
        return;
    }

    const result = countZeroClicks(instructions);
    console.log(result.toString());
}

main();
</code></pre>

<p><a href="/may/tag:adventOfCode" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">adventOfCode</span></a></p>
]]></content:encoded>
      <guid>https://blog.0x0.sk/may/advent-of-code-25-day-1-secret-entrance</guid>
      <pubDate>Mon, 01 Dec 2025 10:02:54 +0000</pubDate>
    </item>
  </channel>
</rss>