01020304050607080910111213141516171819202122232425

Advent of Code

2016/8

Two-Factor Authentication

in C#

by encse

You come across a door implementing what you can only assume is an implementation of two-factor authentication after a long game of requirements telephone.

To get past the door, you first swipe a keycard (no problem; there was one on a nearby desk). Then, it displays a code on a little screen, and you type that code on a keypad. Then, presumably, the door unlocks.

Read the full puzzle.

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace AdventOfCode.Y2016.Day08;

[ProblemName("Two-Factor Authentication")]
class Solution : Solver {

    public object PartOne(string input) {
        var mtx = Execute(input);
        return (
            from irow in Enumerable.Range(0, mtx.GetLength(0))
            from icol in Enumerable.Range(0, mtx.GetLength(1))
            where mtx[irow, icol]
            select 1
        ).Count();
    }

    public object PartTwo(string input) {
        var mtx = Execute(input);
        var res = "";
        foreach (var irow in Enumerable.Range(0, mtx.GetLength(0))) {
            foreach (var icol in Enumerable.Range(0, mtx.GetLength(1))) {
                res += mtx[irow, icol] ? "#" : " ";
            }
            res += "\n";
        }
        return res.Ocr();
    }

    bool[,] Execute(string input) {
        var (crow, ccol) = (6, 50);
        var mtx = new bool[crow, ccol];
        foreach (var line in input.Split('\n')) {
            if (Match(line, @"rect (\d+)x(\d+)", out var m)) {
                var (ccolT, crowT) = (int.Parse(m[0]), int.Parse(m[1]));
                for (var irow = 0; irow < crowT; irow++) {
                    for (var icol = 0; icol < ccolT; icol++) {
                        mtx[irow, icol] = true;
                    }
                }
            } else if (Match(line, @"rotate row y=(\d+) by (\d+)", out m)) {
                var (irow, d) = (int.Parse(m[0]), int.Parse(m[1]));
                for (int i = 0; i < d; i++) {
                    var t = mtx[irow, ccol - 1];
                    for (var icol = ccol - 1; icol >= 1; icol--) {
                        mtx[irow, icol] = mtx[irow, icol - 1];
                    }
                    mtx[irow, 0] = t;
                }
            } else if (Match(line, @"rotate column x=(\d+) by (\d+)", out m)) {
                var (icol, d) = (int.Parse(m[0]), int.Parse(m[1]));
                for (int i = 0; i < d; i++) {
                    var t = mtx[crow - 1, icol];
                    for (var irow = crow - 1; irow >= 1; irow--) {
                        mtx[irow, icol] = mtx[irow - 1, icol];
                    }
                    mtx[0, icol] = t;
                }
            }
        }
        return mtx;
    }

    bool Match(string stm, string pattern, out string[] m) {
        var match = Regex.Match(stm, pattern);
        m = null;
        if (match.Success) {
            m = match.Groups.Cast<Group>().Skip(1).Select(g => g.Value).ToArray();
            return true;
        } else {
            return false;
        }
    }
}

Please ☆ my repo if you like it!

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