Как работает сложение? Я имею в виду сложение на бумаге: одно число под другим?
Давайте попробуем за 465 + 248
465
+ 248
---
Мы начинаем с наименее значимых цифр: 5 + 8. Но 5 + 8 = 13, поэтому результат не уместится в одну цифру. Вот почему мы поступаем так, как нас учил учитель в дошкольных учреждениях: мы оставляем единичную цифру и переносим десятки в следующую колонку
1
465
+ 248
---
3
Теперь десятки. 6 + 4 + (несут) 1 = 11. Снова оставляем 1 и переносим 1 в следующий столбец:
11
465
+ 248
---
13
И последний столбец. 4 + 2 + 1 = 7.
11
465
+ 248
---
713
Таким образом, результат равен 713. Если на одно из этих двух чисел добавлено больше столбца, или в последнем добавлении вы перенесли бы его, вы можете просто переписать оставшиеся числа.
С неизменным списком избранного он будет работать точно так же (я сейчас объясню, почему я использовал неизменный):
- взять оба списка
- взять заголовки обоих списков (если один из них пуст, вы можете просто вернуть другой в результате добавления)
- добавить головы и разделить результат на перенос и текущую цифру (перенос будет 0 или 0, цифра от 0 до 9)
- если есть
carry > 0
добавить список carry :: Nil
к одному из хвостов рекурсивно
- префикс числа к рекурсивно добавленным хвостам
У вас должно получиться что-то вроде этого:
val add: (List[Int], List[Int]) => List[Int] = {
case (a :: as, b :: bs) =>
val digit = (a + b) % 10
val carry = (a + b) / 10
if (carry > 0) digit :: add(add(as, carry :: Nil), bs)
else digit :: add(as, bs)
case (as, Nil) => as
case (Nil, bs) => bs
}
add(5 :: 6 :: 4 :: Nil, 8 :: 4 :: 2 :: Nil) // 3 :: 1 :: 7 :: Nil
Теперь, если бы вы использовали изменяемый список, это было бы сложнее. Если вы хотите использовать изменяемый список, вы хотите обновить один из них, верно? Какой - первый? Во-вторых? И то и другое? Ваш алгоритм может вычислить правильный результат, но разделить ввод.
Допустим, вы всегда добавляете второй список в первый и хотите оставить второй нетронутым. Если второй список длиннее, и вам нужно будет добавить несколько новых мест для цифр, вы должны скопировать все оставшиеся сегменты (в противном случае вы можете, например, обновить один номер во втором списке и изменить первый). Вам также придется обращаться с угловым футляром с переносом.
Довольно нелогичное поведение - числа не изменяемы, и вы хотите представлять числа.