Untitled
unknown
fsharp
3 years ago
4.5 kB
2
Indexable
Never
module AdventOfCode2021.day08.part2 open System open Microsoft.FSharp.Core let readInput = let path = $@"{__SOURCE_DIRECTORY__}\input.txt" System.IO.File.ReadAllLines path |> Array.toList let testInput = "be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce" let splitByLines (input: string) = input.Split("\n") |> List.ofSeq |> List.distinct let getOutputSegs (s: string) = s.Split(" | ").[1].Split(" ") |> List.ofSeq |> List.map (fun x -> x.Trim()) let getInputSegs (s: string) = s.Split(" | ").[0].Split(" ") |> List.ofSeq |> List.map (fun x -> x.Trim()) let combined = splitByLines testInput |> List.map (fun x -> let ip = getInputSegs x let second = getOutputSegs x (ip, second)) let combinedInput = readInput |> List.map (fun x -> let ip = getInputSegs x let second = getOutputSegs x (ip, second)) let uniqueSegs (sl: string list) (length: int) = sl |> List.find (fun x -> x.Length = length) let multipleSegs (sl: string list) (length: int) = sl |> List.filter (fun x -> x.Length = length) let toChars (s: string) = Seq.toList s let removeChars (s: string) (s2: string) = // Segment - Segment2 toChars s |> List.filter (fun x -> toChars s2 |> List.contains x |> not) let containsAll (cl: char list) (cl2: char list) = // first charlist contains all from second cl2 |> List.forall (fun x -> cl |> List.contains x) let toString (cl: char list) = cl |> Array.ofList |> String let rec findInpOutMatch (sl: string list) (os: string) = match sl with | [] -> failwith "Should not happen" | [ x ] -> x | x :: xs -> if (String.length x) = (String.length os) && (containsAll (toChars x) (toChars os)) then x else findInpOutMatch xs os // Number: Segment length. {1: 2}, {4: 4}, {7: 3}, {8: 7} let figureOutNumbers (inp: string list, out: string list) = let one = uniqueSegs inp 2 let four = uniqueSegs inp 4 let seven = uniqueSegs inp 3 let eight = uniqueSegs inp 7 let three = multipleSegs inp 5 |> List.map toChars |> List.filter (fun x -> containsAll x (toChars one)) |> List.head let five = multipleSegs inp 5 |> List.map toChars |> List.filter (fun x -> containsAll x (removeChars four one)) |> List.head let two = multipleSegs inp 5 |> List.map toChars |> List.filter (fun x -> [ three; five ] |> List.contains x |> not) |> List.head let six = multipleSegs inp 6 |> List.map toChars |> List.filter (fun x -> containsAll x (toChars one) |> not) |> List.head let nine = multipleSegs inp 6 |> List.map toChars |> List.filter (fun x -> containsAll x (toChars one)) |> List.filter (fun x -> containsAll x (toChars four)) |> List.head let zero = multipleSegs inp 6 |> List.map toChars |> List.except [ nine; six ] |> List.head let asList = [ toString zero one toString two toString three four toString five toString six seven eight toString nine ] let numbers = [ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9 ] let mappi = List.zip asList numbers |> Map.ofList out |> List.map (findInpOutMatch asList) |> List.map (fun x -> mappi |> Map.find x) |> List.map string |> String.concat "" |> int let res = combinedInput |> List.map figureOutNumbers |> List.reduce (+)