Haskell Ladder
import Data.Array (Array, listArray, (!))
import Data.Bits (shiftL, (.&.))
ladder :: [Int] -> [Int] -> [Int]
ladder a b = [fibArr ! (ai + 1) .&. ((1 `shiftL` bi) - 1) | (ai, bi) <- zip a b]
where
maxA = maximum a
globalMask = (1 `shiftL` maximum b) - 1
fibs = 0 : 1 : zipWith (\x y -> (x + y) .&. globalMask) fibs (tail fibs)
fibArr = listArray (0, maxA + 1) (take (maxA + 2) fibs) :: Array Int Int
This precomputes climb counts once and applies the modulo per query, which avoids recalculating the same paths over and over.