DEV Community

loading...

Discussion on: Advent of Code 2020 Solution Megathread - Day 18: Operation Order

Collapse
ntreu14 profile image
Nicholas Treu

Took me a while to dig through some docs to find what I wanted, but I wrote a parser in F# using FParsec.

open System.IO
open FParsec

// parsers
let parseDecimal : Parser<decimal, unit> = puint64 |>> decimal
let strWs s = pstring s >>. spaces
let parseTerm expression = (parseDecimal .>> spaces) <|> between (strWs "(") (strWs ")") expression

let runParser expr str =
  match run expr str with
    | Success (result, _ , _) -> result
    | Failure (errorMsg, _, _) -> failwithf "Error from parser: %s" errorMsg

let runPart addOperator input =
  let opp = OperatorPrecedenceParser<decimal, unit, unit>()
  let expression = opp.ExpressionParser

  let multOperator = InfixOperator ("*", spaces, 1, Associativity.Left, (*))

  opp.TermParser <- parseTerm expression
  opp.AddOperator(addOperator)
  opp.AddOperator(multOperator)

  input
    |> Array.sumBy (runParser expression) 
    |> printfn "%A"

let input = File.ReadAllLines "input.txt"

runPart (InfixOperator ("+", spaces, 1, Associativity.Left, (+))) input
runPart (InfixOperator ("+", spaces, 2, Associativity.Left, (+))) input
Enter fullscreen mode Exit fullscreen mode