AoC 2022 - slog

Advent Of Code 2022 ํผ์ฆ์„ ์™„๋ฃŒํ•˜๊ธฐ ์œ„ํ•œ ์Šฌ๋กœ๊ทธ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋ชฉ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํ’€์ด์— ์ ํ•ฉํ•œ LINQ ์‚ฌ์šฉ๋ฒ• ์ˆ™๋‹ฌ
  • ํ’€์ด ํ›„ ๋‹ค๋ฅธ ๋ถ„์˜ ํ’€์ด๋ฅผ ์‚ดํŽด๋ณด๋ฉฐ ์ข€ ๋” ํšจ๊ณผ์ ์ธ ์ฝ”๋“œ ์Šต๋“

์ฐธ๊ณ  ํ’€์ด

2๊ฐœ์˜ ์ข‹์•„์š”

์ด์ „ ํ’€์ด ์ด๋ ฅ

1๊ฐœ์˜ ์ข‹์•„์š”

AoC ๋ฌธ์ œ์˜ ํฅ๋ฏธ๋กœ์šด ํŠน์ง•์€ ๋ฌธ์ œ์˜ ํ‘œํ˜„์ด ๊ฐœ์กฐ์‹์ด ์•„๋‹Œ ์„œ์ˆ ์‹ ์ด๋ฉฐ ์Šคํ† ๋ฆฌ๊ฐ€ ์žˆ์–ด์„œ ๋งˆ์น˜ ์šฐ๋ฆฌ๊ฐ€ ํ’€์–ด์•ผ ํ•˜๋Š” ์ผ์ƒ ์ƒํ™œ์˜ ๋ฌธ์ œ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ† ๋ฆฌ๊ฐ€ ์žˆ์–ด์„œ ์–ด๋–ค ๋ฉด์—์„œ๋Š” ๋ถˆํ•„์š”ํ•ด ๋ณด์ด๋Š” ๋ฌธ์žฅ๋„ ์žˆ์–ด ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์˜ˆ์‹œ์™€ ๊ทธ ๋‹ต์„ ์•Œ๋ ค์ค˜์„œ ์ œ๋Œ€๋กœ ํ’€๊ณ  ์žˆ๋Š”์ง€ ๊ฒ€ํ†  ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋ฌธ์ œ๋ฅผ ๋‚ด๋Š” ์ด์œ ๋Š” ์•„๋งˆ๋„ ์ผ์ƒ์ƒํ™œ์—์„œ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ผ์ง€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ ์•ˆ์—์„œ ํŒจํ„ด์„ ์ฐพ๊ณ  ํŒจํ„ด์˜ ๊ทœ์น™์„ฑ์—์„œ ๊ณต์‹์„ ์ฐพ์€ ํ›„ ๊ทธ ๊ณต์‹์œผ๋กœ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ๋ฉ๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

Day6

๋ฌธ์ž์—ด ์ค‘ ์—ฐ์†๋œ 4๊ฐœ์˜ ๋ฌธ์ž๊ฐ€ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์œ„์น˜๋ฅผ ์ฐพ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

โ€œbvwbjplbgvbhsrlpgdmjqwftvnczโ€

  • bvwb ์—์„œ b๊ฐ€ ์ค‘๋ณต๋˜๋ฏ€๋กœ ๋‹ค์Œ์œผ๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.
  • vwbj ๋Š” ์ค‘๋ณต๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ j์˜ ์œ„์น˜์ธ 5๊ฐ€ ๋‹ต์ž…๋‹ˆ๋‹ค.

โ€œnppdvjthqldpwncqszvftbrmjlhgโ€

  • nppd๋Š” p ์ค‘๋ณต
  • ppdv p ์ค‘๋ณต
  • pdvj ์ค‘๋ณต๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ j์˜ ์œ„์น˜์ธ 6์ด ๋‹ต์ž…๋‹ˆ๋‹ค.

โ€ฆ

๋‹ค์Œ์€ ํ’€์ด์ž…๋‹ˆ๋‹ค.

public static string Solve1(string input)
{
    for (var i = 0; i < input.Length; i++)
    {
        // ์ด 4๊ฐœ์˜ ๋ฌธ์ž๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Œ
        if (i < 4)
            continue;

        var packet = input[(i - 4)..i];
        if (IsMarker(packet) is true)
            return i.ToString();
    }

    return (-1).ToString();

    bool IsMarker(string packet)
    {
        return packet.Distinct().SequenceEqual(packet);
    }
}

์‹ฌํ™” ๋ฌธ์ œ

ํŒจํ‚ท ์‹œ์ž‘ ๋งˆ์ปค๊ฐ€ ์•„๋‹Œ ๋ฉ”์‹œ์ง€ ํŒจํ‚ท ๋งˆ์ปค๋ฅผ ์ฐป๋Š” ๋ฌธ์ œ๋กœ 4๊ฐœ๊ฐ€ ์•„๋‹Œ 14๊ฐœ์˜ ์—ฐ์†๋œ ๊ฐœ๋ณ„๋ฌธ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ ์•ฝ๊ฐ„์˜ ์ˆ˜์ •์œผ๋กœ ๋‹ต์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public static string Solve2(string input)
{
    for (var i = 0; i < input.Length; i++)
    {
        // ์ด 14๊ฐœ์˜ ๋ฌธ์ž๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Œ
        if (i < 14)
            continue;

        var packet = input[(i - 14)..i];
        if (IsMarker(packet) is true)
            return i.ToString();
    }

    return (-1).ToString();

    bool IsMarker(string packet)
    {
        return packet.Distinct().SequenceEqual(packet);
    }
}
1๊ฐœ์˜ ์ข‹์•„์š”

๋‹ค๋ฅธ ๋ถ„๋“ค์˜ ํ’€์ด๊ฐ€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

Andrea Angella๋‹˜์˜ ํ’€์ด์ž…๋‹ˆ๋‹ค. ์ €๋ž‘ ๊ฐ™์€ ํ’€์ด์™€ ํ•œ๊ฐ€์ง€ ๋” a-z ๋งŒํผ์˜ int ๋ฐฐ์—ด์„ ๋งŒ๋“ค๊ณ  ๊ฐ ์ž๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ด์œผ๋กœ์จ ๋งˆ์ปค์— ์ค‘๋ณต๋œ ๋ฌธ์ž๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ์ฒดํฌํ•˜๋Š” ์ฝ”๋“œ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    [TestCase(4, 1578)]
    [TestCase(14, 2178)]
    public void Test(int n, int expected)
    {
        var input = File.ReadAllText("Input.txt");

        for (var i = n; i < input.Length; i++)
        {
            var sequence = input[(i - n)..i];

            if (sequence.Distinct().SequenceEqual(sequence))
            {
                Assert.That(i, Is.EqualTo(expected));
                return;
            }
        }

        Assert.Fail();
    }

    [TestCase(4, 1578)]
    [TestCase(14, 2178)]
    public void TestWithArray(int n, int expected)
    {
        var letters = new int[26];
        var input = File.ReadAllText("Input.txt");

        for (var i = 0; i < input.Length; i++)
        {
            if (i >= n) letters[input[i-n]-'a']--;
            letters[input[i]-'a']++;

            if (letters.Sum() == n && letters.All(x => x <= 1))
            {
                Assert.That(i + 1, Is.EqualTo(expected));
                return;
            }
        }

        Assert.Fail();
    }

Sound Code์˜ Mark Heath๋‹˜์˜ ์ฝ”๋“œ๋Š” ์‚ฌ๋ญ‡ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

    public (string, string) ExpectedResult => ("1892", "2313");

    public int FindMarkerPosition(string input, int distinct) =>
        input.Window(distinct).TakeUntil(w => w.ToHashSet().Count == distinct).Count() + distinct - 1;

    public (string, string) Solve(string[] input)
    {
        return ($"{Part1(input)}", $"{Part2(input)}");
    }

    long Part1(IEnumerable<string> input) => FindMarkerPosition(input.First(), 4);
    long Part2(IEnumerable<string> input) => FindMarkerPosition(input.First(), 14);

SuperLinq๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์™„์ „ํ•œ LINQ ์Šคํƒ€์ผ๋กœ ๋ฌธ์ œ๋ฅผ ํ‘ธ์…จ๋„ค์š”.

1๊ฐœ์˜ ์ข‹์•„์š”

Mark Heath๋‹˜์˜ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด SuperLINQ(MoreLINQ๋กœ๋„ ๊ฐ€๋Šฅ)๋ฅผ ์ด์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์žฌ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

public static string Solve1_LINQ(string input)
{
    var markerSize = 4;
    var result = input.Window(markerSize)
        .TakeUntil(x => x.ToHashSet().Count == markerSize)
        .Count() + markerSize - 1;

    return result.ToString();
}
  • Window(windowSize)๋Š” ์œˆ๋„์šฐ ์‚ฌ์ด์ฆˆ ๋งŒํผ ๋ชฉ๋ก์„ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
    ์˜ˆ๋ฅผ ๋“ค์–ด ๋ชฉ๋ก์ด [โ€˜aโ€™, โ€˜bโ€™, โ€˜cโ€™, โ€˜dโ€™, โ€˜eโ€™, โ€˜fโ€™]์ผ ๊ฒฝ์šฐ ์œˆ๋„์šฐ ์‚ฌ์ด์ฆˆ๊ฐ€ 3์ผ ๋•Œ,
    [โ€˜aโ€™, โ€˜bโ€™, โ€˜cโ€™],
    [โ€˜bโ€™, โ€˜cโ€™, โ€˜dโ€™],
    [โ€˜cโ€™, โ€˜dโ€™, โ€˜eโ€™],
    [โ€˜dโ€™, โ€˜eโ€™, โ€˜fโ€™]
    ์ด ๋ฉ๋‹ˆ๋‹ค.
  • TakeUntil()๋Š” ์กฐ๊ฑด์ด ์ฐธ์ผ๋•Œ๊นŒ์ง€ ๋ชฉ๋ก์„ ์–ป์Šต๋‹ˆ๋‹ค.
  • ToHashSet()์œผ๋กœ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ง‘ํ•ฉ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
1๊ฐœ์˜ ์ข‹์•„์š”

@dimohy ๋‹˜ ์Šฌ๋กœ๊ทธ๋ฅผ ๋ณด๊ณ  ์ €๋„ ๋”ฐ๋ผ์„œ ํ’€์–ด๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค ๋…„ 12์›”์„ ์‹ฌ์‹ฌํ•˜์ง€ ์•Š๊ฒŒ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”. ์ข‹์€ ์ •๋ณด ๊ณ ๋ง™์Šต๋‹ˆ๋‹ค~

2๊ฐœ์˜ ์ข‹์•„์š”

Day 7

์ฃผ์–ด์ง„ ๋ช…๋ น์–ด์™€ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด 100000 ๋ณด๋‹ค ์ž‘์€ ๋””๋ ‰ํ† ๋ฆฌ ์‚ฌ์ด์ฆˆ์˜ ์ดํ•ฉ์„ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

์ œ ์ฝ”๋”ฉ ์‹ค๋ ฅ์œผ๋กœ๋Š” ์งง์€ ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋ฐ์š”,

public static string Solve1(string input)
{
    var lines = input.Split(Environment.NewLine);
    var root = Parse(lines);

    var result = root.SearchDirectories()
        .Where(x => x.Size < 100000)
        .Sum(x => x.Size);
    return result.ToString();
}

static DirectoryNode Parse(string[] lines)
{
    var root = new DirectoryNode(null, "/");
    DirectoryNode? currentDirectory = null;
    foreach (var line in lines)
    {
        // ๋ช…๋ น์–ด์˜ ๊ฒฝ์šฐ ๋ช…๋ น ์ฒ˜๋ฆฌ
        if (line.StartsWith("$") is true)
        {
            var tokens = line.Split(' ');
            if (tokens[1] is "cd")
            {
                if (tokens[2] is "/")
                    currentDirectory = root;
                else if (tokens[2] is "..")
                {
                    currentDirectory = currentDirectory?.Parent;
                }
                else
                {
                    var dictionaryName = tokens[2];
                    currentDirectory = currentDirectory?.Nodes.FirstOrDefault(x => x is DirectoryNode && x.Name == dictionaryName) as DirectoryNode;
                }
            }
            else if (tokens[1] is "ls")
                continue;
            else
            {
                throw new InvalidOperationException();
            }
        }
        // ์•„๋‹Œ ๊ฒฝ์šฐ ํŒŒ์ผ ์‚ฌ์ด์ฆˆ ์ทจํ•ฉ
        else
        {
            var tokens = line.Split(' ');

            // ๋””๋ ‰ํ† ๋ฆฌ
            if (tokens[0] is "dir")
            {
                var newDirectory = new DirectoryNode(currentDirectory, tokens[1]);
                currentDirectory?.AddNode(newDirectory);
            }
            // ํŒŒ์ผ
            else
            {
                var newFile = new FileNode(tokens[1], long.Parse(tokens[0]));
                currentDirectory?.AddNode(newFile);
            }
        }
    }

    return root;
}


abstract record Node(string Name)
{
    public abstract long Size { get; }
}
record DirectoryNode(DirectoryNode? Parent, string Name) : Node(Name)
{
    public IEnumerable<Node> Nodes { get; } = new List<Node>();

    public override long Size
    {
        get
        {
            var totals = 0L;
            foreach (var node in Nodes)
                totals += node.Size;
            return totals;
        }
    }

    public IEnumerable<DirectoryNode> SearchDirectories()
    {
        foreach (var node in Nodes)
        {
            if (node is DirectoryNode directory)
            {
                yield return directory;
                foreach (var subDirectory in directory.SearchDirectories())
                    yield return subDirectory;
            }
        }
    }

    public void AddNode(Node node) => (Nodes as List<Node>)!.Add(node);
}
record FileNode(string Name, long FileSize) : Node(Name)
{
    public override long Size => FileSize;
}

์‹ฌํ™” ๋ฌธ์ œ

ํŒŒ์ผ์‹œ์Šคํ…œ์˜ ์ด ์‚ฌ์ด์ฆˆ๋Š” 70000000์ด๊ณ  ๋‚จ์€ ์šฉ๋Ÿ‰์ด 30000000์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
ํ•œ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์‚ญ์ œ ํ–ˆ์„ ๋•Œ ํ•„์š”ํ•œ ๋‚จ์€ ์šฉ๋Ÿ‰์„ ํ™•๋ณดํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ธฐ์ค€์— ๋ถ€ํ•ฉํ•˜๋ฉด์„œ ๊ทธ์ค‘์— ๊ฐ€์žฅ ์ž‘์€ ๋””๋ ‰ํ† ๋ฆฌ์˜ ์‚ฌ์ด์ฆˆ๋ฅผ ๊ตฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

public static string Solve2(string input)
{
    var lines = input.Split(Environment.NewLine);
    var root = Parse(lines);

    var usedSize = root.Size;
    var mustDeleteSize = 30000000 - (70000000 - usedSize);

    var result = root.SearchDirectories()
        .Where(x => x.Size > mustDeleteSize)
        .OrderBy(x => x.Size)
        .Select(x => x.Size)
        .First();
    return result.ToString();
}

๋‹ค๋ฅธ ๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์–ด ๋ณด์ž…๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

์•ˆ์ ค๋ผ ๋‹˜์€ ์ €๋ž‘ ์œ ์‚ฌํ•˜๊ฒŒ ์งฐ์Šต๋‹ˆ๋‹ค.

๋งˆํฌํžˆ์Šค๋‹˜๋„โ€ฆ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”
public IEnumerable<DirectoryNode> SearchDirectories()
{
    foreach (var node in Nodes)
    {
        if (node is DirectoryNode directory)
        {
            yield return directory;
            foreach (var subDirectory in directory.SearchDirectories())
                yield return subDirectory;
        }
    }
}

์ด ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ์‹ถ์€๋ฐ์š”, ๋‹น์žฅ์€ ๋”ฑํžˆ ์•„์ด๋””์–ด๊ฐ€ ๋– ์˜ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”
public IEnumerable<DirectoryNode> SearchDirectories()
{
    foreach (var node in Nodes)
    {
        if (node is DirectoryNode directory)
        {
            yield return directory;
            foreach (var subDirectory in directory.SearchDirectories())
                yield return subDirectory;
        }
    }
}

์ด ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋‹ต๊ธ€์„ ๋‚จ๊ฒจ์•ผ๊ฒ ๋‹ค๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉฐ ์ฝ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ์—ญ์‹œ ๊ฐ™์€ ์ƒ๊ฐ์ด์—ˆ๋„ค์š” ใ…Žใ…Ž

์ด์ „ ๊ธ€์—์„œ LINQ๋กœ ํ’€๊ณ  ์‹ถ๋‹ค๊ณ  ํ•˜์…”์„œ ์ €๋Š” ์ด๋ ‡๊ฒŒ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค

public IEnumerable<DirectoryNode> SearchDirectories()
{
    return Nodes.OfType<DirectoryNode>()
                .SelectMany(directoryNode => directoryNode.SearchDirectories());
}
2๊ฐœ์˜ ์ข‹์•„์š”

๊ตฟ์ž…๋‹ˆ๋‹ค. ๋‹ต์€ ๊ทธ๊ณณ์— ์žˆ์—ˆ๊ตฐ์š”!

2๊ฐœ์˜ ์ข‹์•„์š”

Day 8

30373
25512
65332
33549
35390

์ˆซ์ž๋Š” ํ•œ์ž๋ฆฌ์˜ ์ขŒํ‘œ์ด๋ฉฐ ๋‚˜๋ฌด์˜ ๋†’์ด๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 0์€ ๊ฐ€์žฅ ๋‚ฎ๊ณ  9๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๋‚˜๋ฌด์ž…๋‹ˆ๋‹ค.

์ผ๋ฐ˜: ์กด ๋ฐ–์—์„œ ์ƒ, ํ•˜, ์ขŒ, ์šฐ ์ด ์ง€์—ญ์„ ๊ด€์ฐฐํ•˜๋ฉด์„œ ๋ณด์ด๋Š” ๋‚˜๋ฌด์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
์‹ฌํ™”: ๊ฒฝ์น˜๊ฐ€ ์ข‹์€ ์œ„์น˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ง€์ ์—์„œ ์ƒ, ํ•˜, ์ขŒ, ์šฐ์˜ ๋‚˜๋ฌด๊ฐ€ ๋งŽ์ด ๋ณด์ผ ์ˆ˜๋ก ์ข‹์€ ์œ„์น˜์ด๋ฉฐ ์ ์ˆ˜๋Š” ๋ณด์ด๋Š” ๋‚˜๋ฌด ๊ฐฏ์ˆ˜๋งŒ๋” (์ƒ ๋‚˜๋ฌด * ํ•˜ ๋‚˜๋ฌด * ์ขŒ ๋‚˜๋ฌด * ์šฐ ๋‚˜๋ฌด)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์„ธ๋ จ๋˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด ๋ฐ”๋กœ ๋– ์˜ค๋ฅด์ง€ ์•Š์•„ ์ผ๋ฐ˜์ ์œผ๋กœ ์ฝ”๋”ฉ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ถ„๋“ค์˜ ์ฝ”๋“œ๊ฐ€ ๊ถ๊ธˆํ•œ ์‹œ์ ์ด๊ตฐ์š”.

public static string Solve1(string input)
{
    var map = MakeMap(input);
    var check = new bool[map.GetLength(0), map.GetLength(1)];

    for (var y = 0; y < map.GetLength(1); y++)
        ScanH(y);
    for (var x = 0; x < map.GetLength(0); x++)
        ScanV(x);

    var sum = 0;
    for (var y = 0; y < check.GetLength(1); y++)
        for (var x = 0; x < check.GetLength(0); x++)
            sum += check[x, y] is true ? 1 : 0;

    return sum.ToString();

    void ScanH(int y)
    {
        var high1 = -1;
        var high2 = -1;
        var length = map.GetLength(0);
        for (var x = 0; x < length; x++)
        {
            if (map[x, y] > high1)
            {
                high1 = map[x, y];
                check[x, y] = true;
            }
            if (map[length - x - 1, y] > high2)
            {
                high2 = map[length - x - 1, y];
                check[length - x - 1, y] = true;
            }
        }
    }

    void ScanV(int x)
    {
        var high1 = -1;
        var high2 = -1;
        var length = map.GetLength(1);
        for (var y = 0; y < length; y++)
        {
            if (map[x, y] > high1)
            {
                high1 = map[x, y];
                check[x, y] = true;
            }
            if (map[x, length - y - 1] > high2)
            {
                high2 = map[x, length - y - 1];
                check[x, length - y - 1] = true;
            }
        }
    }
}

static int[,] MakeMap(string input)
{
    var lines = input.Split(Environment.NewLine);

    var map = new int[lines[0].Length, lines.Length];
    for (var y = 0; y < lines.Length; y++)
    {
        var line = lines[y];
        for (var x = 0; x < line.Length; x++)
        {
            map[x, y] = int.Parse(line[x].ToString());
        }
    }

    return map;
}

public static string Solve2(string input)
{
    var map = MakeMap(input);

    var maxScore = 0;
    for (var y = 0; y < map.GetLength(1); y++)
    {
        for (var x = 0; x < map.GetLength(0); x++)
        {
            var score = ScanScore(x, y);
            if (score > maxScore)
                maxScore = score;
        }
    }

    return maxScore.ToString();

    int ScanScore(int x, int y)
    {
        var xLength = map.GetLength(0);
        var yLength = map.GetLength(1);

        var score = 1;
        var center = map[x, y];

        // ์™ผ์ชฝ ํƒ์ƒ‰
        var (sx, sy) = (x - 1, y);
        var high = -1;
        while (sx >= 0)
        {
            var another = map[sx, sy];
            if (another > center && another <= high)
                break;
            if (another < center && center <= high)
                break;

            if (another > high)
                high = another;

            sx--;
        }
        score *= x - (sx + 1);

        // ์˜ค๋ฅธ์ชฝ ํƒ์ƒ‰
        (sx, sy) = (x + 1, y);
        high = -1;
        while (sx < xLength)
        {
            var another = map[sx, sy];
            if (another > center && another <= high)
                break;
            if (another < center && center <= high)
                break;

            if (another > high)
                high = another;

            sx++;
        }
        score *= (sx - 1) - x;

        // ์œ„ ํƒ์ƒ‰
        (sx, sy) = (x, y - 1);
        high = -1;
        while (sy >= 0)
        {
            var another = map[sx, sy];
            if (another > center && another <= high)
                break;
            if (another < center && center <= high)
                break;

            if (another > high)
                high = another;

            sy--;
        }
        score *= y - (sy + 1);

        // ์•„๋ž˜ ํƒ์ƒ‰
        (sx, sy) = (x, y + 1);
        high = -1;
        while (sy < yLength)
        {
            var another = map[sx, sy];
            if (another > center && another <= high)
                break;
            if (another < center && center <= high)
                break;

            if (another > high)
                high = another;

            sy++;
        }
        score *= (sy - 1) - y;

        return score;
    }
}
1๊ฐœ์˜ ์ข‹์•„์š”

ํ  ์•ˆ์ ค๋ผ๋‹˜์˜ ํ’€์ด๋Š” ์ €๋ž‘ ์‚ฌ๋ญ‡ ๋‹ค๋ฅด๊ตฐ์š”. ๋ฐฐ์šธ ์ ์€, LINQ๋กœ 2์ฐจ์› ๋ฐฐ์—ด์„ ๋งŒ๋“ค์—ˆ๋‹ค๋Š” ๊ฒƒ. (๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ!)

๋งˆํฌํžˆ์Šค์˜ ํ’€์ด๋Š” ๋†€๋ž„ ๋…ธ์ž์ด๊ตฐ์š”. LINQ ์Šคํƒ€์ผ๋กœ ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•  ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด ๊ฐ€์žฅ ์•„๋ฆ„๋‹ค์šด ์ฝ”๋“œ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

public class Day8 : ISolver
{
    public (string, string) ExpectedResult => ("1832", "157320");

    private static readonly Coord[] dirs = new Coord[] { (0, 1), (1, 0), (0, -1), (-1, 0) };

    public (string, string) Solve(string[] input)
    {
        var g = Grid<int>.ParseToGrid(input, c => c - '0');        
        return ($"{Part1(g)}", $"{Part2(g)}");
    }

    private long Part1(Grid<int> g)
            => g.AllPositions().Count(p =>  dirs.Any(d => g.LineOut(p,d).All(n => g[p] > g[n])));


    public long ScenicScore(Grid<int> g, Coord p)
        => dirs.Select(d => g.LineOut(p, d)
                            .TakeUntil(n => g[p] <= g[n]).Count())
               .Aggregate((a, b) => a * b);

    public long Part2(Grid<int> g)
        => g.AllPositions().Max(p => ScenicScore(g, p));
}

๋งˆํฌํžˆ์Šค๋‹˜์€ ์ขŒํ‘œ๊ณ„๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ Grid<T> ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ดํ›„ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ‘ธ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

2์ฐจ์› ํƒ์ƒ‰ํ•  ๋•Œ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ ธ์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด์ฃ ~
์˜ค๋žœ๋งŒ์— ๋ณด๋‹ˆ ๋ฐ˜๊ฐ‘๋„ค์š” :slight_smile:

2๊ฐœ์˜ ์ข‹์•„์š”

Day9

๊ฐˆ์ˆ˜๋ก ๋ฌธ์ œ๊ฐ€ ์–ด๋ ค์›Œ์ง€๋Š”๊ตฐ์š”โ€ฆ

์ผ๋ฐ˜: ๋งค๋“ญ์ด ์ด๋™ํ•  ๋•Œ ๊ผฌ๋ฆฌ์˜ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•ด ๊ทธ ๊ฒฝ๋กœ ์œ„์น˜์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋งค๋“ญ์˜ ๊ธธ์ด๋Š” 2์ž…๋‹ˆ๋‹ค.
์‹ฌํ™”: ์ด์ œ ๋งค๋“ญ์˜ ๊ธธ์ด๊ฐ€ 10์ด ๋ฉ๋‹ˆ๋‹ค. ๊ทœ์น™์— ์˜ํ•ด ์ด๋™๋œ ๋งค๋“ญ์˜ ๋งˆ์ง€๋ง‰ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•ด ๊ทธ ์œ„์น˜์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

    public static string Solve1(string input)
    {
        // ์ž…๋ ฅ์—์„œ ํ—ค๋“œ์˜ ์ด๋™ ์–ป๊ธฐ
        var headPoints = input
            .Split(Environment.NewLine)
            .Select(x => ParseHeadMove(x))
            .SelectMany(x => x)
            .Aggregate(Enumerable.Empty<Point>().Append(new Point(0, 0)), (items, item) => items.Append(items.Last() + item)) // ์ข€ ๋” ์ ์ ˆํ•œ LINQ ํ•จ์ˆ˜ ์ฐพ์•„์•ผ ํ•จ
            .ToArray();

        var tailPoints = new List<Point>() { new Point(0, 0) };
        Point beforeHeadPoint = headPoints.First();
        foreach (var headPoint in headPoints.Skip(1))
        {
            var lastTailPoint = tailPoints.Last();

            if (lastTailPoint.IsAdjacency(headPoint) is false)
                tailPoints.Add(beforeHeadPoint);

            beforeHeadPoint = headPoint;
        }

        return tailPoints.Distinct().Count().ToString();
    }

    static IEnumerable<Point> ParseHeadMove(string command)
    {
        var (cmd, move) = command.Split(' ')
            .Chunk(2)
            .Select(x => (x[0], int.Parse(x[1])))
            .First();

        var moving = cmd switch
        {
            "L" => new Point(-1, 0),
            "R" => new Point(1, 0),
            "U" => new Point(0, -1),
            "D" => new Point(0, 1),
            _ => throw new InvalidOperationException()
        };

        return Enumerable.Repeat(moving, move);
    }

    record struct Point(int X, int Y)
    {
        public static Point operator +(Point a, Point b) => new(a.X + b.X, a.Y + b.Y);
        public bool IsAdjacency(Point a) => Math.Abs(X - a.X) <= 1 && Math.Abs(Y - a.Y) <= 1;
        public Point GetNearest(Point to) => (to.X - X, to.Y - Y) switch
        {
            (< 0, < 0) => new(X - 1, Y - 1),
            (< 0, 0) => new(X - 1, Y),
            (< 0, > 0) => new(X - 1, Y + 1),
            (0, > 0) => new(X, Y + 1),
            (> 0, > 0) => new(X + 1, Y + 1),
            (> 0, 0) => new(X + 1, Y),
            (> 0, < 0) => new(X + 1, Y - 1),
            (0, < 0) => new(X, Y - 1),
            _ => throw new InvalidOperationException()
        };
    }

    static void Draw(IEnumerable<Point> points)
    {
        var xLeft = points.Min(x => x.X);
        var xRight = points.Max(x => x.X);
        var yTop = points.Min(x => x.Y);
        var yBottom = points.Max(x => x.Y);

        var map = new string[xRight - xLeft + 1, yBottom - yTop + 1];
        foreach (var point in points)
        {
            map[-xLeft + point.X, -yTop + point.Y] = "#";
        }
        for (var y = 0; y < map.GetLength(1); y++)
        {
            for (var x = 0; x < map.GetLength(0); x++)
            {
                if (map[x, y] == "#")
                    Console.Write("#");
                else
                    Console.Write(".");
            }
            Console.WriteLine();
        }

    }

    public static string Solve2(string input)
    {
        // ์ž…๋ ฅ์—์„œ ํ—ค๋“œ์˜ ์ด๋™ ์–ป๊ธฐ
        var headHistory = input
            .Split(Environment.NewLine)
            .Select(x => ParseHeadMove(x))
            .SelectMany(x => x)
            .Aggregate(Enumerable.Empty<Point>().Append(new Point(0, 0)), (items, item) => items.Append(items.Last() + item)) // ์ข€ ๋” ์ ์ ˆํ•œ LINQ ํ•จ์ˆ˜ ์ฐพ์•„์•ผ ํ•จ
            .ToArray();

        var tails = new List<Point>(Enumerable.Repeat(new Point(0, 0), 9));
        var tailHistory = new List<Point>(tails);

        foreach (var head in headHistory)
        {
            Point before = head;
            for (var i = 0; i < tails.Count; i++)
            {
                var tail = tails[i];

                if (tail.IsAdjacency(before) is false)
                {
                    tails[i] = tail = tail.GetNearest(before);
                        
                    if (i == tails.Count - 1)
                        tailHistory.Add(tail);
                }

                before = tail;
            }
        }

        //Draw(tailHistory);

        return tailHistory.Distinct().Count().ToString();
    }
}

๊ตฌํ˜„ํ•œ Draw()๋ฅผ ํ†ตํ•ด ์‹ฌํ™” ๋ฌธ์ œ์˜ ๊ถค์ ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”
image

๋‹ค๋ฅธ ๋ถ„๋“ค์˜ ํ’€์ด๊ฐ€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

Day10

noop๊ณผ addx๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฐ„๋‹จํ•œ ๊ธฐ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. noop์€ ํ•œ ์‚ฌ์ดํด์„ ์‰ฌ๊ณ  addx๋Š” 2 ์‚ฌ์ดํด์„ ์†Œ๋น„ํ•œ ํ›„ ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์— ๊ฐ’์„ ๋”ํ•ฉ๋‹ˆ๋‹ค.

noop
addx 3
addx -5

๋ ˆ์ง€์Šคํ„ฐ ๊ธฐ๋ณธ ๊ฐ’: 1

  • noop - ํ•œ ์‚ฌ์ดํด์„ ์‰ฝ๋‹ˆ๋‹ค.
  • addx 3 - ๋‘ ์‚ฌ์ดํด ์†Œ๋น„ ํ›„ 1 + 3 = ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ 4๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • addx -5 - ๋‘ ์‚ฌ์ดํด ์†Œ๋น„ ํ›„ 4 + -5 = ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ -1๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ผ๋ฐ˜: 20, 60, 100, 140, 180, 220 ์‚ฌ์ดํด์— ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์„ ์‚ฌ์ดํด * ๊ฐ’์œผ๋กœ ๊ณ„์‚ฐํ•ด์„œ ์ด ํ•ฉ์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.
์‹ฌํ™”: ํŠน์ • ์กฐ๊ฑด์„ ํ†ตํ•ด ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋Š” ์‹œ๊ทธ๋„์ด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ์‹œ๊ทธ๋„์„ ์ด์šฉํ•ด ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

public static string Solve1(string input)
{
    var commands = input.Split(Environment.NewLine);
    var machine = new Machine();
    machine.Load(commands);
    var sum = machine.Run()
        .Take(220)
        .Where(x => x.Cycle is 20 or 60 or 100 or 140 or 180 or 220)
        .Select(x => x.Cycle * x.Value)
        .Sum();

    return sum.ToString();
}

public static string Solve2(string input)
{
    var commands = input.Split(Environment.NewLine);
    var machine = new Machine();
    machine.Load(commands);
            
    var sb = new StringBuilder();
    foreach (var (cycle, value) in machine.Run().Take(240))
    {
        var xOffset = (cycle - 1) % 40;

        if (xOffset >= value - 1 && xOffset <= value + 1)
            sb.Append('#');
        else
            sb.Append('.');

        if (xOffset is 39)
            sb.AppendLine();
    }

    return sb.ToString();
}

class Machine
{
    private int _rX = 1;
    private Command[]? _commands;

    public int RegisterX => _rX;

    public void Load(string[] commands)
    {
        _commands = commands.Select(Command.Parse).ToArray();
    }

    private IEnumerable<Command> NextCommand()
    {
        if (_commands is null || _commands.Length is 0)
            yield break;

        var index = 0;
        while (true)
        {
            var command = _commands[index % _commands.Length];
            yield return command;
                    
            index++;
        }
    }

    public IEnumerable<(int Cycle, int Value)> Run()
    {
        var rX = 1;
        var cycle = 0;

        foreach (var command in NextCommand())
        {
            foreach(var _ in Enumerable.Range(1, command.Cycles))
            {
                cycle++;

                yield return (cycle, rX);
            }

            if (command is AddxCommand addxCommand)
                rX += addxCommand.IncValue;
        }
    }
}

abstract record Command()
{
    public abstract int Cycles { get; }

    public static Command Parse(string input)
    {
        var tokens = input.Split(' ', StringSplitOptions.TrimEntries);
        if (tokens[0] is "noop")
            return new NoopCommand();
        else if (tokens[0] is "addx")
            return new AddxCommand(int.Parse(tokens[1]));

        throw new InvalidOperationException();
    }
}
record NoopCommand() : Command
{
    public override int Cycles => 1;
}
record AddxCommand(int IncValue) : Command
{
    public override int Cycles => 2;
}

image

1๊ฐœ์˜ ์ข‹์•„์š”

๋‹ค๋ฅธ ๋ถ„๋“ค์˜ ์ฝ”๋“œ๋„ ๋ถ„์„ํ•ด๋ด…์‹œ๋‹ค.

์—”์ ค๋ผ๋‹˜์˜ ์ฝ”๋“œ :

์œฝ. ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ตฐ์š”.

๋งˆํฌํžˆ์Šค๋‹˜ ์ฝ”๋“œ:

์—ญ์‹œ ๊ฐ„๊ฒฐํ•˜๊ตฐ์š”.

์–ด๋–ป๊ฒŒ ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์—†๋„ค์š”โ€ฆ ^^;

1๊ฐœ์˜ ์ข‹์•„์š”

Day 11

๋“œ์ด์–ด ๋ง‰ํžŒ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. Day 11์˜ ์ฒซ๋ฒˆ์จฐ ๋ฌธ์ œ๋Š” ๋ฌด๋‚œํžˆ ํ•ด๊ฒฐํ–ˆ๋Š”๋ฐ
๋‘๋ฒˆ์งธ ์‹ฌํ™” ๋ฌธ์ œ๋Š” ๊ฐ’์ด ๊ธฐํ•˜๊ธ‰์ˆ˜๋กœ ์ปค์ง€๋ฏ€๋กœ BigInteger๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋‚˜ ์—ญ๋ถ€์กฑ์ด์˜€์Šต๋‹ˆ๋‹ค.
โ€ฆ --;


ํ’€์—ˆ์Šต๋‹ˆ๋‹ค.

๋‘๋ฒˆ์งธ ์‹ฌํ™” ๋ฌธ์ œ๋Š” Operation ๊ฒฐ๊ณผ ๊ฐ’์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ์ œ๋Œ€๋กœ Test ๋  ์ˆ˜ ์žˆ๊ฒŒ ๋ชจ๋“  ์›์ˆญ์ด์˜ ํ…Œ์ŠคํŠธ ๋‚˜๋ˆ„๊ธฐ ๊ฐ’์„ ๊ณฑํ•œ ๊ฐ’์ด ์ตœ๋Œ€ ๊ฐ’์ด ๋˜๋„๋ก

mulDivition = 23 * 19 * 13 * 17 // 96577
newOperationResult = operationResult % MulDivition

ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Operation ๊ฒฐ๊ณผ ๊ฐ’์ด ๋ฌดํ•œํžˆ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public static string Solve1(string input)
{
    var monkeys = input.Split(Environment.NewLine)
        .Chunk(7)
        .Select(x => Monkey.Parse(x, 3))
        .ToArray();

    var targetRound = 20;

    foreach (var _ in Enumerable.Range(1, targetRound))
    {
        foreach (var monkey in monkeys)
        {
            monkey.Test((number, value) =>
            {
                var handingMonkey = monkeys.First(x => x.Number == number);
                handingMonkey.Has(value);
            });
        }
    }

    return monkeys
        .OrderByDescending(x => x.Times)
        .Take(2)
        .Aggregate(1, (multi, monkey) => multi * monkey.Times)
        .ToString();
}

public static string Solve2(string input)
{
    var monkeys = input.Split(Environment.NewLine)
        .Chunk(7)
        .Select(x => Monkey.Parse(x, 1))
        .ToArray();

    var mulDivision = monkeys.Aggregate(1UL, (multi, monkey) => multi * (ulong)monkey.TestDivision);

    var targetRound = 10000;

    foreach (var round in Enumerable.Range(1, targetRound))
    {
        //Console.WriteLine(round);
        foreach (var monkey in monkeys)
        {
            monkey.Test((number, value) =>
            {
                var handingMonkey = monkeys.First(x => x.Number == number);
                handingMonkey.Has(value % mulDivision);
            });
        }
    }

    return monkeys
        .OrderByDescending(x => x.Times)
        .Take(2)
        .Aggregate(1L, (multi, monkey) => multi * monkey.Times)
        .ToString();
}

class Monkey
{
    private Func<ulong, ulong> _operation;
    private Queue<ulong> _items;
    private int _ridiculousLevel;
    private int _testDivision;
    private int _divisibleTrueMonkeyNumber;
    private int _divisibleFalseMonkeyNumber;

    public int Number { get; }

    public int Times { get; private set; }

    public int TestDivision => _testDivision;


    private Monkey(int number, ulong[] items, Func<ulong, ulong> operation, int ridiculousLevel, int testDivision, int divisibleTrueMonkeyNumber, int divisibleFalseMonkeyNumber)
    {
        Number = number;
        _items = new Queue<ulong>(items);
        _operation = operation;
        _ridiculousLevel = ridiculousLevel;
        _testDivision = testDivision;
        _divisibleTrueMonkeyNumber = divisibleTrueMonkeyNumber;
        _divisibleFalseMonkeyNumber = divisibleFalseMonkeyNumber;
    }

    public void Test(Action<int, ulong> handingFunc)
    {
        var count = _items.Count;

        while (_items.Count > 0)
        {
            var item = _items.Dequeue();
            var result = _operation(item);
            var testResult = result / (ulong)_ridiculousLevel;
            if (testResult % (ulong)_testDivision == 0)
                handingFunc(_divisibleTrueMonkeyNumber, testResult);
            else
                handingFunc(_divisibleFalseMonkeyNumber, testResult);
        }

        Times += count;
    }

    public void Has(ulong value)
    {
        _items.Enqueue(value);
    }

    public static Monkey Parse(string[] strings, int ridiculousLevel)
    {
        var number = int.Parse(strings[0][7..8]);
            
        var items = strings[1][18..]
            .Split(',', StringSplitOptions.TrimEntries)
            .Select(ulong.Parse)
            .ToArray();
            
        var strOperation = strings[2][19..];
            
        var operation = (ulong x) => x;
        if (strOperation is "old * old")
            operation = x => x * x;
        else if (strOperation.StartsWith("old +") is true)
        {
            var value = ulong.Parse(strOperation[5..]);
            operation = x => x + value;
        }
        else if (strOperation.StartsWith("old *") is true)
        {
            var value = ulong.Parse(strOperation[5..]);
            operation = x => x * value;
        }
        else
            throw new InvalidOperationException();

        var testDivision = int.Parse(strings[3][21..]);
        var divisibleTrueMonkeyNumber = int.Parse(strings[4][29..]);
        var divisibleFalseMonkeyNumber = int.Parse(strings[5][30..]);

        return new Monkey(number, items, operation, ridiculousLevel, testDivision, divisibleTrueMonkeyNumber, divisibleFalseMonkeyNumber);
    }
}
1๊ฐœ์˜ ์ข‹์•„์š”

์ด๋ฒˆ AoC์˜ ์—ฌ์ •์€ LINQ ์Šต๋“๊ณผ ์ข€ ๋” ํšจ์œจ์ ์ธ (๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€๋…์„ฑ์€ ์œ ์ง€ํ•˜๋Š”) ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์—ฌ์ •์ž…๋‹ˆ๋‹ค. ๋‚˜์•„๊ฐ€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ์›์‹œ ๋ฌธ์ž์—ด๋กœ ์ธํ•ด ๊น”๋”ํ•˜๊ฒŒ ํŠน์„ฑ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์•˜์Šต๋‹ˆ๋‹ค.

    [TestCase("""
        Sabqponm
        abcryxxl
        accszExk
        acctuvwj
        abdefghi
        """, ExpectedResult = "31")]
    public string Day12_Test1(string input)
    {
        return Day12.Solve1(input);
    }
3๊ฐœ์˜ ์ข‹์•„์š”