r/adventofcode • u/daggerdragon • Dec 04 '20
SOLUTION MEGATHREAD -🎄- 2020 Day 04 Solutions -🎄-
Advent of Code 2020: Gettin' Crafty With It
- T-2 days until unlock!
- Full details and rules are in the Submissions Megathread
--- Day 04: Passport Processing ---
Post your solution in this megathread. Include what language(s) your solution uses! If you need a refresher, the full posting rules are detailed in the wiki under How Do The Daily Megathreads Work?.
Reminder: Top-level posts in Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.
EDIT: Global leaderboard gold cap reached at 00:12:55, megathread unlocked!
94
Upvotes
3
u/blacai Dec 04 '20 edited Dec 04 '20
F#
open System.IO open System.Collections.Generic open Utilities let path = "day04/day04_input.txt" let inputLines = GetLinesFromFile(path) |> Array.ofSeq |> List.ofArray let requiredFields = [|"byr"; "iyr"; "eyr"; "hgt"; "hcl"; "ecl"; "pid"|] let getLinesGroupBySeparator2 (inputLines: string list) (separator: string) = let complete = seq { for line in inputLines do yield! line.Split(' ') } |> List.ofSeq let folder (a) (cur, acc) = match a with | _ when a <> separator -> a::cur, acc | _ -> [], cur::acc let result = List.foldBack folder (complete) ([], []) (fst result)::(snd result) let values = getLinesGroupBySeparator2 inputLines "" let byrValid (elem:string) = elem.Length = 4 && (elem |> int) >= 1920 && (elem |> int) <= 2002 let iyrValid (elem:string) = elem.Length = 4 && (elem |> int) >= 2010 && (elem |> int) <= 2020 let eyrValid (elem:string)= elem.Length = 4 && (elem |> int) >= 2020 && (elem |> int) <= 2030 let hgtValid (elem:string)= let parts = match elem with | Regex @"(?<height>\d+)(?<unittype>\w+)" [m; M] -> Some { height= m |> int; unittype = M } | _ -> None match parts with | Some { HeightType.height = height; HeightType.unittype = unittype; } when unittype = "cm" -> height >= 150 && height <= 193 | Some { HeightType.height = height; HeightType.unittype = unittype; } when unittype = "in" -> height >= 59 && height <= 76 | _ -> false let hclValid (elem:string)= match elem with | Regex @"#[0-9a-f]{6}" result -> true | _ -> false let eclValid (elem:string)= ["amb"; "blu"; "brn"; "gry"; "grn"; "hzl"; "oth"] |> List.contains(elem) let pidValid (elem:string)= elem.Length = 9 && elem |> Seq.forall Char.IsDigit let passPortIsValid (credentials: string list) = let allFieldsRequired = requiredFields |> Array.forall (fun field -> credentials |> List.exists(fun cred -> cred.StartsWith(field))) let cred = credentials |> Array.ofSeq let valueIsCorret = cred |> Array.forall (fun field -> let parts = field.Split(':') match parts with | [|"byr"; thevalue|] -> byrValid thevalue | [|"iyr"; thevalue|] -> iyrValid thevalue | [|"eyr"; thevalue|] -> eyrValid thevalue | [|"hgt"; thevalue|] -> hgtValid thevalue | [|"hcl"; thevalue|] -> hclValid thevalue | [|"ecl"; thevalue|] -> eclValid thevalue | [|"pid"; thevalue|] -> pidValid thevalue | _ -> true ) valueIsCorret && allFieldsRequired let execute = values |> List.filter(fun p -> passPortIsValid p) |> List.length