{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-orphans #-} -- | -- Module : Advent.OCR.Internal -- Copyright : (c) Justin Le 2020 -- License : BSD3 -- -- Maintainer : justin@jle.im -- Stability : experimental -- Portability : non-portable -- -- Internal utility functions for "Advent.OCR". module Advent.OCR.Internal ( -- * Parse V2(..) , Point , parseLettersV2 , parseLettersEitherV2 , parseAsciiMapV2 -- * Letter Map , LetterMap(..) , lookupLetterMap , defaultLetterMap , rawLetterforms1 , rawLetterforms2 , parseLetterMap -- * Utility , contiguousShapes , contiguousShapesBy ) where import Advent.OCR.LetterMap import Data.Default.Class import Data.Maybe import Data.Monoid import Data.Set (Set) import Language.Haskell.TH.Lift import qualified Data.Set as S -- | A version of 'Advent.OCR.parseLetters' taking 'Point'. Used -- internally. parseLettersV2 :: LetterMap -> Set Point -> Maybe String parseLettersV2 lm = (fmap . map) (either (const '?') id) . parseLettersEitherV2 lm -- | A version of 'Advent.OCR.parseLettersEither' taking (and returning) -- 'Point'. Used internally. parseLettersEitherV2 :: LetterMap -> Set Point -> Maybe [Either (Set Point) Char] parseLettersEitherV2 lm letters = listToMaybe attempts where attempts = [ res | refl <- [id, reflX] , rots <- [id, perp, negate, negate . perp] , let ls = S.map (rots . refl) letters ((Sum n, Sum goodCount), res) = tryMe ls percGood = goodCount / n :: Double , n > 0 && percGood >= 0.5 ] tryMe = traverse (\c -> maybe ((Sum 1, Sum 0), Left c) (((Sum 1, Sum 1),) . Right) . lookupLetterMap c $ lm) . contiguousShapesBy v2x perp (V2 x y) = V2 (negate y) x reflX (V2 x y) = V2 (negate x) y -- | Default is compatible with all challenges in Advent of Code 2015 to -- 2019. instance Default LetterMap where def = defaultLetterMap -- | The default lettermap compatible all challenges in Advent of Code 2015 -- - 2019. defaultLetterMap :: LetterMap defaultLetterMap = $( lift $ uncurry parseLetterMap rawLetterforms1 <> uncurry parseLetterMap rawLetterforms2 )