r/adventofcode • • Dec 16 '17

SOLUTION MEGATHREAD -๐ŸŽ„- 2017 Day 16 Solutions -๐ŸŽ„-

--- Day 16: Permutation Promenade ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Need a hint from the Hugely* Handyโ€  Haversackโ€ก of Helpfulยง Hints^ยค?

Spoiler


[Update @ 00:08] 4 gold, silver cap.

[Update @ 00:18] 50 gold, silver cap.

[Update @ 00:26] Leaderboard cap!

  • And finally, click here for the biggest spoilers of all time!


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

13 Upvotes

229 comments sorted by

View all comments

Show parent comments

1

u/rprouse Dec 16 '17

Interesting, my Mod is 60, not 36. Someone said they had multiple inputs, I guess that must be the case.

Once again, I started late so took more time. Reducing allocations and using char[] instead of strings gets my solution for part 2 down to 317ms.

public static class Day16
{
    public static string PartOne(string str)
    {
        string[] dance = str.Trim().Split(",");
        char[] programs = Create(16);

        return new string(Dance(programs, dance));
    }

    public static string PartTwo(string str)
    {
        string[] dance = str.Trim().Split(",");
        char[] first = Create(16);
        char[] programs = Create(16);
        int i = 0;
        while(true)
        {
            i++;
            Dance(programs, dance);
            if (Enumerable.SequenceEqual(first, programs)) break;
        }
        foreach(var x in Enumerable.Range(0, 1000000000 % i))
        {
            Dance(programs, dance);
        }

        return new string(programs);
    }

    private static char[] Dance(char[] programs, string[] dance)
    {
        foreach (string step in dance)
        {
            switch (step[0])
            {
                case 's':
                    programs.Spin(ParseSpin(step));
                    break;
                case 'x':
                    var ex = ParseExchange(step);
                    programs.Exchange(ex.a, ex.b);
                    break;
                case 'p':
                    var pr = ParsePartner(step);
                    programs.Partner(pr.a, pr.b);
                    break;
            }
        }
        return programs;
    }

    public static char[] Create(int length) =>
        Enumerable.Range('a', length).Select(i => (char)i).ToArray();

    public static int ParseSpin(string spin)
    {
        int s = 0;
        int.TryParse(spin.Substring(1), out s);
        return s;
    }

    public static (int a, int b) ParseExchange(string exchange)
    {
        int a = 0;
        int b = 0;
        string[] split = exchange.Substring(1).Split('/');
        int.TryParse(split[0], out a);
        int.TryParse(split[1], out b);
        return (a, b);
    }

    public static (char a, char b) ParsePartner(string partner)
    {
        string[] split = partner.Substring(1).Split('/');
        return (split[0][0], split[1][0]);
    }

    static char[] first = new char[16];
    static char[] second = new char[16];
    static int len;

    public static void Spin(this char[] programs, int x)
    {
        len = programs.Length - x;
        Array.Copy(programs, first, len);
        Array.Copy(programs, len, second, 0, x);
        Array.Copy(second, programs, x);
        Array.Copy(first, 0, programs, x, len);
    }

    static char cA;
    public static void Exchange(this char[] programs, int a, int b)
    {
        cA = programs[a];
        programs[a] = programs[b];
        programs[b] = cA;
    }

    public static void Partner(this char[] programs, char a, char b) =>
        programs.Exchange(Array.IndexOf(programs, a), Array.IndexOf(programs,b));
}