Я решил 45 проблем с 4clojure.com, и я заметил повторяющуюся проблему в том, как я пытаюсь решить некоторые проблемы с помощью рекурсии и аккумуляторов.Аккумуляторы, конъюнкция и рекурсия
Я попытаюсь объяснить лучшее, что могу, что я делаю, чтобы в конечном итоге получить верные решения, надеясь, что некоторые Клоуриузеры «получат» то, что я не получаю.
Например, проблема 34 просит написать функцию (без использования диапазон), беря два целых числа в качестве аргументов и создавая диапазон (без использования диапазона). Проще говоря, вы делаете (... 1 7) и получаете (1 2 3 4 5 6).
Теперь этот вопрос не касается решения этой конкретной проблемы.
Что делать, если я хочу решить это с помощью рекурсии и аккумулятора?
Моего мыслительный процесс выглядит следующим образом:
Мне нужно написать функцию, принимающую два аргумента, я начинаю с (Fn [х])
мне придется рекурсивным и мне нужно будет отслеживать список, я буду использовать накопитель, поэтому я напишу 2-ю функцию внутри первой с дополнительным аргументом:
(fn [xy]
((п г [ху акк] ...) х у «())
(по-видимому, я не могу правильно форматировать, что Clojure код на SO !?)
Здесь я уже не уверен, что делаю это правильно: первая функция должна взять ровно два целых аргумента (не мой вызов), и я не уверен: если я хочу использовать аккумулятор, могу ли я использовать аккумулятора без создания вложенной функции?
Тогда я хочу Conj, но я не могу сделать:
(conj 0 1)
так что я странные вещи, чтобы убедиться, что у меня есть последовательность первых, и я в конечном итоге с этим:
(fn
[x y]
((fn g [x y acc] (if (= x y) y (conj (conj acc (g (inc x) y acc)) x)))
x
y
'()))
Но тогда это производит это:
(1 (2 (3 4)))
Вместо этого:
(1 2 3 4)
Так что я в конечном итоге делает дополнительный расплющить и она работает, но это совершенно некрасиво.
Я начинаю понимать несколько вещей, и в некоторых случаях я даже начинаю «думать» более clojureque, но у меня проблема с написанием решения.
К примеру здесь я решил:
- использовать аккумулятор
- для рекурсии приращением х до тех пор, пока не достигнет у
Но я в конечном итоге с уродством выше ,
Есть проблема , чтобы решить эту проблему, и еще раз это не то, что мне нужно.
То, что я после того, как, как, после того, как я решил минусы/CONJ, используйте аккумулятор и рекурсию, я могу закончить с этим (не написано мной):
#(loop [i %1
acc nil]
(if (<= %2 i)
(reverse acc)
(recur (inc i) (cons i acc))))
Вместо этого :
((fn
f
[x y]
(flatten
((fn
g
[x y acc]
(if (= x y) acc (conj (conj acc (g (inc x) y acc)) x)))
x
y
'())))
1
4)
Я беру это начало, чтобы иметь возможность решить несколько проблем, но я немного разочарован уродливые решения я, как правило, производят ...
Не бойтесь выбросить плохие решения. Если вы начинаете видеть, что ваш код становится громоздким, сделайте шаг назад и подумайте об этом. Когда он не чувствует * правильно, это, вероятно, не так. – Jeremy
@JeremyHeiler: хорошо, но «идея» не так уж плоха, это «реализация»/фактический код, который плохой. Например, использование короткого решения и аккумулирование + рекурсия было написано кем-то, кто решил 150 проблем 4clojure (и некоторые из них действительно не тривиальны). Так что моя идея не выглядит плохой: но я не могу (пока) чисто реализовать свои идеи. Понимаю, это займет некоторое время, чтобы кусочки головоломки встали на свои места: -/ –
Это конечно. Просто продолжайте практиковать и играть с кодом! – Jeremy