Haskell
main = do
input Int
soln1 x = (*) (countTwos (lines x)) (countThrees (lines x))
soln2 :: String -> String
soln2 x = findCommon (findDiff1 (lines x) (lines x))
extractKey :: Eq a => a -> [(a, b)] -> [b] -> [b]
extractKey _ [] acc = acc
extractKey x (y:ys) acc = extractKey x ys (if (fst y) == x then (snd y):acc else acc)
extractByKey' :: Eq a => [(a, b)] -> [a] -> [(a, [b])]
extractByKey' [] _ = []
extractByKey' (x:xs) seen
| elem (fst x) seen = extractByKey' xs seen
| otherwise = (fst x, extractKey (fst x) xs [snd x]):extractByKey' xs ((fst x):seen)
extractByKey :: Eq a => [(a, b)] -> [(a, [b])]
extractByKey x = extractByKey' x []
reduceByKey :: Eq a => [(a, b)] -> ([b] -> b) -> [(a, b)]
reduceByKey x f = map (\y -> (fst y, f (snd y))) (extractByKey x)
countLetters :: String -> [(Char, Int)]
countLetters s = reduceByKey (map (\x -> (x, 1)) s) sum
hasTwo :: [(Char, Int)] -> Bool
hasTwo [] = False
hasTwo (x:xs) = if (snd x == 2) then True else hasTwo xs
countTwos :: [String] -> Int
countTwos x = sum (map (\y -> if (hasTwo . countLetters) y then 1 else 0) x)
hasThree :: [(Char, Int)] -> Bool
hasThree [] = False
hasThree (x:xs) = if (snd x == 3) then True else hasThree xs
countThrees :: [String] -> Int
countThrees x = sum (map (\y -> if (hasThree . countLetters) y then 1 else 0) x)
countDiff :: String -> String -> Int
countDiff s0 s1 = sum (map (\x -> if (fst x == snd x) then 0 else 1) (zip s0 s1))
findDiff1 :: [String] -> [String] -> (String, String)
findDiff1 [] [] = ("", "")
findDiff1 (x:xs) [] = findDiff1 xs xs
findDiff1 (x:xs) (y:ys) = if (countDiff x y) == 1 then (x, y) else findDiff1 (x:xs) ys
findCommon :: (String, String) -> String
findCommon ([], []) = []
findCommon x
| (head (fst x)) == (head (snd x)) = (head (fst x)):findCommon ((tail (fst x)), (tail (snd x)))
| otherwise = findCommon ((tail (fst x)), (tail (snd x)))