🏡 index : ~doyle/aoc.git

#!/usr/bin/env nix-shell
#!nix-shell --pure -i "runghc -- -i../" -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [ ])"

import Aoc (parseMultipleGrids, readAndParseStdin)
import Data.Bifunctor (Bifunctor (first))
import Data.List (transpose)

main = do
  input <- readAndParseStdin parseMultipleGrids
  print $ part1 input
  print $ part2 input

part1 :: [[[Bool]]] -> Int
part1 = sum . map (findReflectionAny 0)

part2 :: [[[Bool]]] -> Int
part2 = sum . map (findReflectionAny 1)

findReflectionAny :: Int -> [[Bool]] -> Int
findReflectionAny diffs xs =
  let hl = findReflection diffs xs
      hr = findReflection diffs . reverse $ xs
      vl = findReflection diffs . transpose $ xs
      vr = findReflection diffs . reverse . transpose $ xs
   in case (hl, hr, vl, vr) of
        (v, 0, 0, 0) -> v * 100
        (0, v, 0, 0) -> (length xs - v) * 100
        (0, 0, v, 0) -> v
        (0, 0, 0, v) -> (length . head) xs - v

findReflection :: Int -> [[Bool]] -> Int
findReflection diffs xs = go xs
  where
    go [] = 0
    go xs
      | cmp (first reverse $ splitAt (length xs `div` 2) xs) == diffs = length xs `div` 2
      | otherwise = go (init xs)
    cmp (x1, x2) = sum $ zipWith cmpInner x1 x2
    cmpInner x1 x2 = length . filter id $ zipWith (/=) x1 x2