From e7614c20da8168140d0e34307f60474102d4541d Mon Sep 17 00:00:00 2001 From: Brian Chu Date: Sat, 19 Feb 2022 11:14:27 -0800 Subject: solution for day 16 --- day16.fsx | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 day16.fsx diff --git a/day16.fsx b/day16.fsx new file mode 100644 index 0000000..6b6de0c --- /dev/null +++ b/day16.fsx @@ -0,0 +1,60 @@ +open System.IO +open System.Text.RegularExpressions + +type Move = + | Spin of offset: int + | Exchange of first: int * second: int + | Partner of first: char * second: char + +let (|MoveRegex|_|) pattern input= + let m = Regex(pattern).Match(input) + if m.Success then Some(List.tail [for x in m.Groups -> x.Value]) + else None + +let parseMove str = + match str with + | MoveRegex "s(\d+)" [x] -> Spin(int x) + | MoveRegex "x(\d+)/(\d+)" [x; y] -> Exchange(int x, int y) + | MoveRegex "p(\w)/(\w)" [x; y] -> Partner(char x, char y) + | _ -> failwith "invalid input" + +let swapPos x y (chars: char array) = + chars |> Array.mapi (fun i v -> + match i with + | _ when i = x -> chars.[y] + | _ when i = y -> chars.[x] + | _ -> v) + +let swapLetter x y (chars: char array) = + let indexOf elem = chars |> Array.findIndex((=) elem) + swapPos (indexOf x) (indexOf y) chars + +let spinChars steps (str: char array) = + let startIndex = str.Length - steps + let first, last = str[..startIndex - 1], str[startIndex..] + Array.append last first + +let executeMove chars move = + match move with + | Spin x -> spinChars x chars + | Exchange (x, y) -> swapPos x y chars + | Partner (x, y) -> swapLetter x y chars + +let rec executeMoves state moves seen = + let newState = Array.fold executeMove state moves + if List.contains newState seen then + let r = List.rev seen + let l = List.length seen + let m = 1000000000 % l + r.[m] + else + executeMoves newState moves (newState :: seen) + +let () = + let moves = (File.ReadAllText "day16.txt").Trim().Split(',') |> Array.map parseMove + let initialState = ("abcdefghijklmnop" |> Array.ofSeq) + let finalState = Array.fold executeMove initialState moves + // part 1 + finalState |> Array.map string |> String.concat "" |> printfn "%s" + // part 2 + executeMoves initialState moves [initialState] |> Array.map string |> String.concat "" |> printfn "%s" -- cgit 1.4.1-2-gfad0