Advent of Code Day 1 требует зацикливания в той или иной форме длинной строки скобок, например ((((())(())(((()))((
и т. д. , Идея состоит в том, что (
поднимается на один «этаж», )
спускается на один этаж, а задачи состоят в том, чтобы напечатать
- первый индекс в строке, где номер этажа отрицательный и
- последний этаж, когда найден конец строки.
Императивное решение с циклом for простое (например, Python):
def main():
flr = 0
basement = False
for idx, elt in enumerate(text):
flr += {
"(": 1,
")": -1
}.get(elt)
if flr < 0 and not basement:
print("first basement pos:", idx + 1)
basement = True
print("final floor:", flr)
Рекурсивное функциональное решение немного сложнее, но все же не слишком сложно.
def worker(flr, txt, idx, basement):
flr += {"(": 1, ")": -1}[ txt[0] ]
if not (len(txt) - 1): return flr
if flr < 0 and not basement:
print("first basement floor index: ", idx + 1)
basement = True
return worker(flr, txt[1:], idx + 1, basement)
def starter(txt):
flr, basement, idx = 0, False, 0
return worker(flr, txt, idx, basement)
if __name__ == '__main__':
__import__("sys").setrecursionlimit(int(1e5))
print("final floor:", starter(text))
Оба они дают правильный вывод
first basement floor index: 1795
final floor: 74
при запуске против моего вызова.
за исключением того, что второй вариант глупый, потому что в Python нет оптимизации хвостовых вызовов, но это неважно
Как я могу реализовать любой из них в Factor? Это то, что меня смущает с тех пор, как я начал использовать Factor.
Мы не можем просто использовать цикл for, потому что нет эквивалента, позволяющего сохранять изменяемое состояние между итерациями.
Мы могли использовать рекурсивное решение:
: day-1-starter ( string -- final-floor )
[ 0 ] dip 0 f day-1-worker 3drop "final floor: %s" printf ;
: day-1-worker
( floor string index basement? -- floor string index basement? )
day-1-worker ! what goes here?
; recursive
Отлично, это скелет, но что входит в тело day-1-worker
? В Factor нет никакого способа "досрочного возврата" из рекурсивного вызова, потому что нет способа запустить программу в обратном порядке и нет концепции возврата - это не имеет никакого смысла.
У меня такое чувство, что, возможно, рекурсия не является ответом на этот вопрос в Factor. Если это так, как мне остановить рекурсию?