C#์„ ํ†ตํ•œ Advent of Code 2022 | ANDREA ANGELLA

์˜ค ์ด๋Ÿฐ ๊ฒƒ์ด ์žˆ์—ˆ๊ตฐ์š”.

https://adventofcode.com/

1๋ฒˆ ๋ถ€ํ„ฐ 25๋ฒˆ๊นŒ์ง€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๊ฐ€ ์—ด๋ฆฌ๋ฉฐ ์ง€๊ธˆ์€ 14๋ฒˆ์งธ ๋ฌธ์ œ๊ฐ€ ๊ฒŒ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ANDREA ANGELLA๋‹˜์ด C#์„ ์ด์šฉํ•ด Advent of Code 2022 ๋ฌธ์ œ๋ฅผ ํ’€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!


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

์ €์˜ Day1 ๋ฌธ์ œ ํ’€์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒˆ๋กœ ์—ด๋ฆฝ๋‹ˆ๋‹ค. ๊ณ ์ „์ ์œผ๋กœ ํ’€์—ˆ์Šต๋‹ˆ๋‹ค.

var lines = File.ReadAllLines("day1_input.txt");
var (max, sum) = (0, 0);
foreach (var line in lines)
{
    if (line is "")
    {
        if (sum > max)
            max = sum;
        sum = 0;

        continue;
    }

    sum += int.Parse(line);
}

Console.WriteLine(max);
2๊ฐœ์˜ ์ข‹์•„์š”

Day1์˜ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด ์‘์šฉํ•˜๋Š” ๋‘ ๋ฒˆ์งธ ๋ฌธ์ œ๊ฐ€ ์—ด๋ฆฌ๋Š”๋ฐ ์ƒ์œ„ 3๊ฐœ์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šฌ์Šฌ LINQ๋กœ ํ• ๊ป„ ์•ฝ๊ฐ„์˜ ํ›„ํšŒ๋ฅผ ํ•˜๊ฒŒ ๋˜๋„ค์š” ^^;

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

์œ„์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ LINQ๋กœ๋„ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

var max = File.ReadAllText("day1_input.txt")
    .Split(Environment.NewLine + Environment.NewLine)
    .Select(x =>
         x.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)
        .Sum(y => int.Parse(y))
    )
    .Max();

Console.WriteLine(max);
2๊ฐœ์˜ ์ข‹์•„์š”

๊ฐ€๋…์„ฑ์€? ๊ธ€์Ž„์š”โ€ฆ ์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ๊ฐ€ ์ข‹์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

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

Day1์˜ ๋‘๋ฒˆ์งธ ๋ฌธ์ œ์˜ ํ’€์ด์ž…๋‹ˆ๋‹ค. LINQ๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฏ€๋กœ ์ •๋ ฌ์„ ํ•œ ํ›„ ์ƒ์œ„ 3๊ฐœ์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ’€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var max = File.ReadAllText("day1_input.txt")
    .Split(Environment.NewLine + Environment.NewLine)
    .Select(x =>
        x.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)
        .Sum(y => int.Parse(y))
    )
    .OrderByDescending(x => x)
    .Take(3)
    .Sum();

Console.WriteLine(max);
2๊ฐœ์˜ ์ข‹์•„์š”

Day2 ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.
์ดํ•ดํ•˜๋ฉด ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์ธ๋ฐ ์˜์–ด๋ผ ์ฒ˜์Œ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ๋„ค์š”.

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

    internal class Day2
    {
        /// <summary>
        /// ๊ฐ€์œ„๋ฐ”์œ„๋ณด ๊ฒŒ์ž„์—์„œ ์Šน๋ฆฌํ•˜์ž
        /// </summary>
        public static void Solve1()
        {
            var lines = File.ReadAllLines("day2_input.txt");

            var sum = 0;
            foreach (var line in lines)
            {
                var temp = line.Split();
                var y = temp[0] switch { "A" => Kind.๋ฐ”์œ„, "B" => Kind.๋ณด, "C" => Kind.๊ฐ€์œ„, _ => throw new InvalidOperationException() };
                var i = temp[1] switch { "X" => Kind.๋ฐ”์œ„, "Y" => Kind.๋ณด, "Z" => Kind.๊ฐ€์œ„, _ => throw new InvalidOperationException() };

                var score = (int)i;

                // ์ด๊ธด ๊ฒฝ์šฐ
                if ((i, y) is (Kind.๋ฐ”์œ„, Kind.๊ฐ€์œ„) ||
                    (i, y) is (Kind.๋ณด, Kind.๋ฐ”์œ„) ||
                    (i, y) is (Kind.๊ฐ€์œ„, Kind.๋ณด))
                    score += 6;
                // ๋น„๊ธด ๊ฒฝ์šฐ
                else if (i == y)
                    score += 3;

                sum += score;
            }

            Console.WriteLine(sum);
        }
    }

    internal enum  Kind
    {
        ๋ฐ”์œ„ = 1,
        ๋ณด = 2,
        ๊ฐ€์œ„ = 3
    }
1๊ฐœ์˜ ์ข‹์•„์š”

๋งŒ๋“ค๊ณ  ๋‚˜๋‹ˆ ์˜ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ธด ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ํŒจํ„ด์„ ์ข€ ๋” ๋ถ„์„ํ•œ ํ›„ ๋‹ค์Œ์˜ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

var lines = File.ReadAllLines("day2_input.txt");

var sum = 0;
foreach (var line in lines)
{
    var y = line[0] - 'A';
    var i = line[2] - 'X';

    var score = 0;
    // ๋น„๊ธด๊ฒฝ์šฐ
    if (i == y)
        score = 3;
    // ์ด๊ธด๊ฒฝ์šฐ
    else if (i == (y + 1) % 3)
        score = 6;

    sum += score + i + 1;
}

Console.WriteLine(sum);
2๊ฐœ์˜ ์ข‹์•„์š”

Day2์˜ ์‹ฌํ™” ๋ฌธ์ œ๋„ ๋น„์Šทํ•œ ํŒจํ„ด์œผ๋กœ ํ’€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var lines = File.ReadAllLines("day2_input.txt");

var sum = 0;
foreach (var line in lines)
{
    var y = line[0] - 'A';  // 0:๋ฐ”์œ„, 1:๋ณด, 2:๊ฐ€์œ„
    var r = line[2] - 'X';  // 0:์ง, 1:๋น„๊น€, 2:์ด๊น€

    // 0, 0 : ๋ฐ”์œ„, i = 2
    // 0, 1 : ๋ฐ”์œ„, i = 0
    // 0, 2 : ๋ฐ”์œ„, i = 1
    // 1, 0 : ๋ณด, i = 0
    // 1, 1 : ๋ณด, i = 1
    // 1, 2 : ๋ณด, i = 2
    // 2, 0 : ๊ฐ€์œ„, i = 1
    // 2, 1 : ๊ฐ€์œ„, i = 2
    // 2, 2 : ๊ฐ€์œ„, i = 0

    var i = (y + r + 2) % 3;
    sum += r * 3 + i + 1;
}

Console.WriteLine(sum);

๊ทธ๋Ÿฐ๋ฐ ์ฝ”๋“œ๋Š” ๊ฐ„๊ฒฐํ•ด ์กŒ์ง€๋งŒ ๊ฐ€๋…์„ฑ์€ ๋–จ์–ด์ง€๋Š”๊ตฐ์š”.

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

Day3 ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋ดค์Šต๋‹ˆ๋‹ค.

vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

๊ฐ ๋ฌธ์ž์—ด์„ ์ ˆ๋ฐ˜์œผ๋กœ ์ž๋ฅธ ํ›„ ์™ผ์ชฝ ๋ฌธ์ž์—ด๊ณผ ์˜ค๋ฅธ์ชฝ ๋ฌธ์ž์—ด ์ค‘ ๊ฐ™์€ ์ฒซ ๋ฌธ์ž๋ฅผ ์šฐ์„ ์ˆœ์œ„ ๊ฐ’์œผ๋กœ ์น˜ํ™˜ํ•ด์„œ ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•˜๋ฉด ํ’€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var lines = File.ReadAllLines("day3_input.txt");
//var lines = new[]
//{
//    "vJrwpWtwJgWrhcsFMMfFFhFp",
//    "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
//    "PmmdzqPrVvPwwTWBwg",
//    "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
//    "ttgJtRGJQctTZtZT",
//    "CrZsJsPPZsGzwwsLwLmpwMDw",
//};
var sum = 0;
foreach (var line in lines)
{
    var rucksackSize = line.Length / 2;
    var aList = line[..rucksackSize];
    var bList = line[rucksackSize..];

    //var result = from a in aList
    //             join b in bList
    //             on a equals b
    //             select a;
    //var c = result.FirstOrDefault();
    var c = aList
            .Join(bList, x => x, y => y, (x, y) => x)
            .FirstOrDefault();
    var priority = GetPriorityNumber(c);
    sum += priority;
}

Console.WriteLine(sum);

static int GetPriorityNumber(char c) => c switch
{
    >= 'a' and <= 'z' => c - 'a' + 1,
    >= 'A' and <= 'Z' => c - 'A' + 27,
    _ => 0
};

LINQ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํ’€๋ฆฌ๋Š” ๋ฌธ์ œ๋„ค์š”.

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

Join() ๋Œ€์‹  Intersect()๋กœ ์ข€ ๋” ๊ฐ„๋‹จํžˆ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

                var c = aList
                    .Intersect(bList)
                    .FirstOrDefault();
1๊ฐœ์˜ ์ข‹์•„์š”

Day3์˜ ์‹ฌํ™” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์‹ฌํ™” ๋ฌธ์ œ๋Š” 3์ค„์— ๊ณตํ†ต์œผ๋กœ ๋“ค์–ด๊ฐ„ ๋ฌธ์ž๋ฅผ ์ฐพ์•„ ์šฐ์„ ์ˆœ์œ„ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ ๊ทธ ํ•ฉ๊ณ„๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋Š” LINQ๋ฅผ ์ด์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํ’€๋ฆฝ๋‹ˆ๋‹ค.

var lines = File.ReadAllLines("day3_input.txt");
//var lines = new[]
//{
//    "vJrwpWtwJgWrhcsFMMfFFhFp",
//    "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
//    "PmmdzqPrVvPwwTWBwg",
//    "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
//    "ttgJtRGJQctTZtZT",
//    "CrZsJsPPZsGzwwsLwLmpwMDw",
//};

var sum = lines.Chunk(3)
    .Select(x => x[0].Intersect(x[1]).Intersect(x[2]).FirstOrDefault())
    .Sum(x => GetPriorityNumber(x));

Console.WriteLine(sum);


static int GetPriorityNumber(char c) => c switch
{
    >= 'a' and <= 'z' => c - 'a' + 1,
    >= 'A' and <= 'Z' => c - 'A' + 27,
    _ => 0
};
1๊ฐœ์˜ ์ข‹์•„์š”

Day4์˜ ๋ฌธ์ œ๋Š” ๋‘ ๊ฐœ์˜ ๋ฒ”์œ„ ์ค‘ ํฌํ•จ๋˜๋Š” ๋ฒ”์œ„์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

public static void Solve1()
{
var lines = File.ReadAllLines("day4_input.txt");
//var lines = new[]
//{
//    "2-4,6-8",
//    "2-3,4-5",
//    "5-7,7-9",
//    "2-8,3-7",
//    "6-6,4-6",
//    "2-6,4-8",
//};

var count = lines.Select(x => x.Split(','))
    .Select(x => new
    {
        A = x[0].Split('-').Select(y => int.Parse(y)).ToArray(),
        B = x[1].Split('-').Select(y => int.Parse(y)).ToArray()
    })
    .Count(x => IsInclude(x.A, x.B));

Console.WriteLine(count);


static bool IsInclude(int[] r1, int[] r2) => (r1, r2) switch
{
    _ when r1[0] <= r2[0] && r1[1] >= r2[1] => true,
    _ when r2[0] <= r1[0] && r2[1] >= r1[1] => true,
    _ => false
};

๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋ฉด ํ‰๊ท ์€ ํ•˜๋Š” ๊ฒƒ์ด๊ฒ ์ง€๋งŒ ANDREA ANGELLA๋‹˜์˜ ํ’€์ด๋„ ๊ถ๊ธˆํ•ด์ง€๋Š”๊ตฐ์š”.

var assignments = File.ReadAllLines("Input.txt")
                          .Select(pair => pair.Split(","))
                          .Select(x => (Assignment.Parse(x[0]), Assignment.Parse(x[1])));

var fullyContainedAssignments = assignments.Where(a => a.First.FullyContains(a.Second) || a.Second.FullyContains(a.First));

Assert.That(fullyContainedAssignments.Count(), Is.EqualTo(518));

private record Assignment(int Start, int End)
{
    public bool Overlap(Assignment a) => End < a.Start || Start > a.End;
    public bool FullyContains(Assignment a) => Start <= a.Start && End >= a.End;
    public static Assignment Parse(string a) => new(int.Parse(a.Split("-")[0]), int.Parse(a.Split("-")[1]));
}

๊น”๋”ํ•˜๊ตฐ์š”.

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

Day4์˜ ์‘์šฉ๋ฌธ์ œ๋Š” ๋‘๊ฐœ์˜ ๋ฒ”์œ„๊ฐ€ ๊ฒน์น  ๊ฒฝ์šฐ๋ฅผ ์นด์šดํŠธ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ํ’€์ด๊ฐ€ ์žˆ๊ฒ ์ง€๋งŒ ์ด๋ฒˆ์—๋Š” ์ข€ ๋” ๋ฌด์‹ํ•˜๊ฒŒ ์งœ๋ดค์Šต๋‹ˆ๋‹ค.

public static void Solve2()
{
    var lines = File.ReadAllLines("day4_input.txt");
    //var lines = new[]
    //{
    //    "2-4,6-8",
    //    "2-3,4-5",
    //    "5-7,7-9",
    //    "2-8,3-7",
    //    "6-6,4-6",
    //    "2-6,4-8",
    //};

    var count = lines.Select(x => x.Split(','))
        .Select(x => new
        {
            A = x[0].Split('-').Select(y => int.Parse(y)).ToArray(),
            B = x[1].Split('-').Select(y => int.Parse(y)).ToArray()
        })
        .Count(x => IsOverlap(x.A, x.B));

    Console.WriteLine(count);


    static bool IsOverlap(int[] r1, int[] r2)
    {
        var r1List = Enumerable.Range(r1[0], r1[1] - r1[0] + 1);
        var r2List = Enumerable.Range(r2[0], r2[1] - r2[0] + 1);

        return r1List.Intersect(r2List).Any();
    }    
}
1๊ฐœ์˜ ์ข‹์•„์š”

Day5 ๋ฌธ์ œ๋Š” ํ…์ŠคํŠธ ์ •๋ณด์—์„œ ์Šคํƒ ๋ชฉ๋ก์„ ๋งŒ๋“ค๊ณ  ์ด๋™ ๋ช…๋ น์„ ํ•ด์„ํ•ด์„œ ์Šคํƒ์„ ์กฐ์ •ํ•œ ๋’ค ์Šคํƒ์— ์Œ“์ธ ๊ฐ€์žฅ ์œ„์˜ ๋ฌผ๊ฑด์„ ์–ป๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

    [D]    
[N] [C]    
[Z] [M] [P]
 1   2   3 

move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

์ตœ๋Œ€ํ•œ LINQ๋กœ ํ’€๋ ค๊ณ  ๋…ธ๋ ฅํ•ด๋ดค๊ณ  ์•„๋Š” LINQ ๋ช…๋ น์ด ๋งŽ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค. ์ €์—๊ฒŒ AoC ๋ฌธ์ œ๋Š” LINQ์— ์ข€ ๋” ์ต์ˆ™ํ•ด์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฒฝํ—˜์ด ๋˜๊ณ˜๊ตฐ์š”.

public static void Solve1()
{
    var lines = File.ReadAllText("day5_input.txt");
    //var lines = """
    //        [D]    
    //    [N] [C]    
    //    [Z] [M] [P]
    //     1   2   3 

    //    move 1 from 2 to 1
    //    move 3 from 1 to 3
    //    move 2 from 2 to 1
    //    move 1 from 1 to 2
    //    """;

    // ์Šคํƒ๋ถ€์™€ ๋ช…๋ น๋ถ€ ๋ผ์ธ ์–ป์Œ
    var (stacksLines, commandLines) = lines
        .Split(Environment.NewLine + Environment.NewLine)
        .Chunk(2)
        .Select(x =>
            (x[0].Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries),
            x[1].Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)))
        .First();

    // ์Šคํƒ๋ถ€์—์„œ ๋ฐ•์Šค ์ •๋ณด ์–ป์Œ
    var stackBoxes = stacksLines
        .Select(x => x
            .Chunk(4)
            .Select((y, i) => (Number: i + 1, Box: y[1]))
            .Where(x => x.Box is not ' ') // ๋นˆ ์Šฌ๋กฏ ์ œ์™ธ
        )
        .SkipLast(1) // ๋งˆ์ง€๋ง‰ ์ˆซ์ž๋ถ€ ์ œ์™ธ
        .SelectMany(x => x)
        .Reverse(); // ์•„๋ž˜๋ถ€ํ„ฐ ๋‹ด์•„์•ผ ํ•˜๋ฏ€๋กœ ๋ฐ˜์ „

    var stackCount = stackBoxes.Max(x => x.Number);

    // ๋ฐ•์Šค๋ฅผ ์Šคํƒ์— ๋‹ด์Œ
    var stacks = new Stack<char>[stackCount];
    foreach (var stackBox in stackBoxes)
    {
        ref var stack = ref stacks[stackBox.Number - 1];
        if (stack is null)
            stack = new Stack<char>();

        stack.Push(stackBox.Box);
    }

    // ๋ช…๋ น๋ถ€ ์ฒ˜๋ฆฌ
    foreach (var commandLine in commandLines)
    {
        var (moves, from, to) = commandLine.Split(' ')
            .Chunk(6)
            .Select(x => (int.Parse(x[1]), int.Parse(x[3]), int.Parse(x[5])))
            .First();

        foreach (var count in Enumerable.Range(1, moves))
        {
            var stack = stacks[from - 1].Pop();
            stacks[to - 1].Push(stack);
        }
    }

    var result = string.Concat(stacks.Select(x => x.First().ToString()));
    Console.WriteLine(result);
}

๋ฌธ์ œ๋ฅผ ๊ณ„์† ํ’€์–ด๊ฐ€๋‹ค ๋ณด๋ฉด ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•ด ๋ฌธ์ œ๋ฅผ ์—ฐ์†๋œ ์ •๋ณด - Stream์œผ๋กœ ๋ณด๊ณ  ํ’€์–ด๊ฐ€๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ข€ ๋” ์ต์ˆ™ํ•ด์ง€์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•ด๋ด…๋‹ˆ๋‹ค.

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

Day5์˜ ์‹ฌํ™” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด์ œ๋Š” ์ƒ์ž๋ฅผ ํ•˜๋‚˜์”ฉ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š” ์ƒ์ž๋ฅผ ๋™์‹œ์— ์˜ฎ๊ฒผ์„ ๋•Œ ์ตœ์ข… ๊ตฌ์„ฑ๋œ ์Šคํƒ์—์„œ ์ƒ๋‹จ์— ๋†“์ง„ ๋ฐ•์Šค๋“ค์„ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋”์ด์ƒ ์Šคํƒ์ด ํ•„์š” ์—†์œผ๋ฏ€๋กœ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ๋Š” List<T>๋กœ ์ปฌ๋ ‰์…˜์„ ๋ณ€๊ฒฝํ•˜๊ณ  ๋ช…๋ น ์ฒ˜๋ฆฌ ํ›„ ์ตœ์ข… ์Šคํƒ ์ƒ๋‹จ์˜ ๋ฐ•์Šค๋ฅผ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ์„ string.Concat() ๋Œ€์‹  LINQ Aggregate()๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

public static void Solve2()
{
    var lines = File.ReadAllText("day5_input.txt");
    //var lines = """
    //        [D]    
    //    [N] [C]    
    //    [Z] [M] [P]
    //     1   2   3 

    //    move 1 from 2 to 1
    //    move 3 from 1 to 3
    //    move 2 from 2 to 1
    //    move 1 from 1 to 2
    //    """;

    // ์Šคํƒ๋ถ€์™€ ๋ช…๋ น๋ถ€ ๋ผ์ธ ์–ป์Œ
    var (stacksLines, commandLines) = lines
        .Split(Environment.NewLine + Environment.NewLine)
        .Chunk(2)
        .Select(x =>
            (x[0].Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries),
            x[1].Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)))
        .First();

    // ์Šคํƒ๋ถ€์—์„œ ๋ฐ•์Šค ์ •๋ณด ์–ป์Œ
    var stackBoxes = stacksLines
        .Select(x => x
            .Chunk(4)
            .Select((y, i) => (Number: i + 1, Box: y[1]))
            .Where(x => x.Box is not ' ') // ๋นˆ ์Šฌ๋กฏ ์ œ์™ธ
        )
        .SkipLast(1) // ๋งˆ์ง€๋ง‰ ์ˆซ์ž๋ถ€ ์ œ์™ธ
        .SelectMany(x => x);

    var stackCount = stackBoxes.Max(x => x.Number);

    // ๋ฐ•์Šค๋ฅผ ์Šคํƒ์— ๋‹ด์Œ
    var stacks = new List<char>[stackCount];
    foreach (var stackBox in stackBoxes)
    {
        ref var stack = ref stacks[stackBox.Number - 1];
        if (stack is null)
            stack = new List<char>();

        stack.Add(stackBox.Box);
    }

    // ๋ช…๋ น๋ถ€ ์ฒ˜๋ฆฌ
    foreach (var commandLine in commandLines)
    {
        var (moves, from, to) = commandLine.Split(' ')
            .Chunk(6)
            .Select(x => (int.Parse(x[1]), int.Parse(x[3]), int.Parse(x[5])))
            .First();

        var fromStacks = stacks[from - 1];
        var toStacks = stacks[to - 1];

        var movingBoxes = fromStacks.GetRange(0, moves);
        fromStacks.RemoveRange(0, moves);
        toStacks.InsertRange(0, movingBoxes);
    }

    //var result = string.Concat(stacks.Select(x => x.First().ToString()));
    var result = stacks.Aggregate("", (x, stack) => x + stack.First());
    Console.WriteLine(result);
}

๋‹ค์Œ ๋ฌธ์ œ๋ถ€ํ„ฐ๋Š” ๋ฌธ์ œ๊ฐ€ ์œ ๋„ํ•˜๋Š” ์ทจ์ง€์— ๋งž๊ฒŒ ์œ ๋‹› ํ…Œ์ŠคํŠธ๋กœ ๊ตฌ์„ฑํ•ด์„œ ํ•ด๋ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.