# Untitled

unknown

fsharp

2 years ago

4.0 kB

2

Indexable

Never

^{}

open System open System.IO let input = File.ReadAllLines("./input.txt") |> Array.toList let cleanSplit (sep: string) (s: string) = s.Split( sep, (StringSplitOptions.TrimEntries ||| StringSplitOptions.TrimEntries) ) |> List.ofArray let parsed = input |> List.map (fun x -> let splat = x |> cleanSplit "|" let firstPart = splat.Item(0) |> cleanSplit " " |> List.map (fun (x: string) -> x |> Seq.toList |> List.map string) let secondPart = splat.Item(1) |> cleanSplit " " |> List.map (fun (x: string) -> x |> Seq.toList |> List.map string) (firstPart, secondPart)) let ans1 = parsed |> List.map snd |> List.map (fun xs -> let lens = xs |> List.map List.length lens |> List.filter (fun x -> List.contains x [ 2; 3; 4; 7 ]) |> List.length) |> List.sum printfn "%A" ans1 let segmentsToDigits xs = let sorted = List.sort xs match sorted with | [ 1; 2; 3; 5; 6; 7 ] -> 0 | [ 3; 6 ] -> 1 | [ 1; 3; 4; 5; 7 ] -> 2 | [ 1; 3; 4; 6; 7 ] -> 3 | [ 2; 3; 4; 6 ] -> 4 | [ 1; 2; 4; 6; 7 ] -> 5 | [ 1; 2; 4; 5; 6; 7 ] -> 6 | [ 1; 3; 6 ] -> 7 | [ 1; 2; 3; 4; 5; 6; 7 ] -> 8 | [ 1; 2; 3; 4; 6; 7 ] -> 9 | c -> failwithf $"invalid segments %A{c}" let figureItOut (xs: list<list<string>>, digits: list<list<string>>) = let getByLength ls (len: int) = ls |> List.filter (fun xxs -> List.length xxs = len) let getOneByLength ls (len: int) = getByLength ls len |> List.exactlyOne let diff xs ys = Set.difference (Set.ofList xs) (Set.ofList ys) |> Set.toList let intersection xs ys = Set.intersect (Set.ofList xs) (Set.ofList ys) |> Set.toList let exactlyN n xs = let len = List.length xs match len with | len when len = n -> xs | len -> failwithf $"tried getting exactly %A{len} from %A{xs}" let seven = getOneByLength xs 3 let one = getOneByLength xs 2 let four = getOneByLength xs 4 let segment1 = diff seven one |> List.exactlyOne let segments24 = diff four one |> exactlyN 2 let twoThreeAndFive = getByLength xs 5 let segments25 = twoThreeAndFive |> List.concat |> List.countBy id |> List.filter (fun x -> snd x = 1) |> List.map fst let segment2, segment5, segment4 = let s2 = intersection segments24 segments25 |> List.exactlyOne let s5 = diff segments25 [ s2 ] |> List.exactlyOne let s4 = diff segments24 [ s2 ] |> List.exactlyOne s2, s5, s4 let two = twoThreeAndFive |> List.filter (List.contains segment5) |> List.exactlyOne let segment3 = intersection one two |> List.exactlyOne let segment6 = diff seven [ segment1; segment3 ] |> List.exactlyOne let segment7 = diff two [ segment1 segment3 segment4 segment5 ] |> List.exactlyOne let segmentMap = Map [ (segment1, 1) (segment2, 2) (segment3, 3) (segment4, 4) (segment5, 5) (segment6, 6) (segment7, 7) ] let mapped = digits |> List.map (fun ls -> ls |> List.map (fun x -> Map.find x segmentMap)) |> List.map segmentsToDigits let res = mapped |> List.map string |> String.concat "" |> int res let ans2 = parsed |> List.map figureItOut |> List.sum printfn "%A" ans2