Haskell Fish
fish :: [Int] -> [Int] -> Int
fish a b = size - dead
where
size = length a
(dead, _) = foldl step (0, []) (zip a b)
step (d, stack) (ai, bi)
| bi == 1 = (d, ai : stack)
| otherwise = fight ai stack d
fight _ [] d = (d, [])
fight ai (top : tops) d
| ai > top = fight ai tops (d + 1)
| otherwise = (d + 1, top : tops)
This uses a stack for downstream fish and resolves fights only when opposite directions meet.