01020304050607080910111213141516171819202122232425

Advent of Code

2019/22

Slam Shuffle

in C#

by encse

There isn't much to do while you wait for the droids to repair your ship. At least you're drifting in the right direction. You decide to practice a new card shuffle you've been working on.

Digging through the ship's storage, you find a deck of space cards! Just like any deck of space cards, there are 10007 cards in the deck numbered 0 through 10006. The deck must be new - they're still in factory order, with 0 on the top, then 1, then 2, and so on, all the way through to 10006 on the bottom.

Read the full puzzle.

using System;
using System.Numerics;
using System.Text.RegularExpressions;

namespace AdventOfCode.Y2019.Day22;

[ProblemName("Slam Shuffle")]
class Solution : Solver {

    public object PartOne(string input) {
        var m = 10007;
        var iter = 1;
        var (a, b) = Parse(input, m, iter);
        return Mod(a * 2019 + b, m);
    }

    public object PartTwo(string input) {
        var m = 119315717514047;
        var iter = 101741582076661;
        var (a, b) = Parse(input, m, iter);

        return Mod(ModInv(a, m) * (2020 - b), m);
    }

    BigInteger Mod(BigInteger a, BigInteger m) => ((a % m) + m) % m;
    BigInteger ModInv(BigInteger a, BigInteger m) => BigInteger.ModPow(a, m - 2, m);

    (BigInteger a, BigInteger big) Parse(string input, long m, long n) {
        var a = new BigInteger(1);
        var b = new BigInteger(0);

        foreach (var line in input.Split('\n')) {
            if (line.Contains("into new stack")) {
                a = -a;
                b = m - b - 1;
            } else if (line.Contains("cut")) {
                var i = long.Parse(Regex.Match(line, @"-?\d+").Value);
                b = m + b - i;
            } else if (line.Contains("increment")) {
                var i = long.Parse(Regex.Match(line, @"-?\d+").Value);
                a *= i;
                b *= i;
            } else {
                throw new Exception();
            }
        }

        var resA = BigInteger.One;
        var resB = BigInteger.Zero;

        // resA = a^n
        resA = BigInteger.ModPow(a, n, m);
        // resB = b * (1 + a + a^2 + ... a^n) = b * (a^n - 1) / (a - 1);
        resB = b * (BigInteger.ModPow(a, n, m) - 1) * ModInv(a - 1, m) % m;

        return (resA, resB);
    }
}

Please ☆ my repo if you like it!

© 2025 Advent of Code is a registered trademark in the US Images provided by Bing image creator