Haskell
There's probably a really clever way of abstracting just the difference between the two layouts.
import Data.Char (isSpace)
import Data.List (transpose)
import Data.List.Split (splitWhen)
op '+' = sum
op '*' = product
part1 =
sum
. map ((op . head . last) <*> (map read . init))
. (transpose . map words . lines)
part2 =
sum
. map ((op . last . last) <*> map (read . init))
. (splitWhen (all isSpace) . reverse . transpose . lines)
main = do
input <- readFile "input06"
print $ part1 input
print $ part2 input