Ich habe 45 Probleme von 4clojure.com gelöst und ich bemerkte ein wiederkehrendes Problem in der Art, wie ich versuche, einige Probleme mit Rekursion und Akkumulatoren zu lösen.Akkus, Conj und Rekursion
Ich werde versuchen, das Beste zu erklären, was ich tun kann, um mit fugly Lösungen zu enden, in der Hoffnung, dass einige Clojurer "bekommen" würden, was ich nicht bekomme.
Zum Beispiel fragt Problem 34, eine Funktion zu schreiben (ohne Verwendung Bereich) zwei ganze Zahlen als Argumente und erstellt einen Bereich (ohne Verwendung von Bereich). Stellen Sie einfach (... 1 7) und Sie bekommen (1 2 3 4 5 6).
Nun geht es in dieser Frage nicht darum, dieses spezielle Problem zu lösen.
Was ist, wenn ich wollen, um dies zu lösen, indem ich Rekursion und einen Akkumulator verwende?
Mein Denkprozess geht so:
Ich brauche eine Funktion nimmt zwei Argumente zu schreiben, beginne ich mit (fn [xy])
Ich muss recurse und ich werde Spur einer Liste zu halten brauchen, ich werde einen Speicher verwenden, so schreibe ich eine zweite Funktion innerhalb der ersten ein zusätzliches Argument unter:
(fn [xy]
((fn g [xy acc] ...) x y ‚())
(anscheinend kann ich nicht richtig formatiert werden, dass Clojure Code auf SO !?)
Hier bin ich mir schon nicht sicher ob ich es richtig mache: die erste Funktion muss genau zwei ganzzahlige Argumente nehmen (nicht mein Aufruf) und ich bin mir nicht sicher: wenn ich einen Akku verwenden möchte, kann ich einen verwenden Akkumulator ohne eine geschachtelte Funktion zu erstellen?
Dann möchte ich Konj, aber ich kann nicht tun:
(conj 0 1)
so seltsame Dinge, die ich tun, um sicherzustellen, dass ich zum ersten Mal eine Sequenz haben und ich mit diesem Ende:
(fn
[x y]
((fn g [x y acc] (if (= x y) y (conj (conj acc (g (inc x) y acc)) x)))
x
y
'()))
Aber dies dann produzieren:
(1 (2 (3 4)))
Statt dessen:
(1 2 3 4)
So beende ich eine zusätzliche abflachen tun und es funktioniert, aber es ist völlig hässlich.
Ich fange an, ein paar Dinge zu verstehen, und ich fange manchmal an, in einer clojuresque Weise "zu denken", aber ich habe ein Problem, die Lösung zu schreiben.
Zum Beispiel hier habe ich beschlossen:
- einen Speicher zu verwenden
- durch Erhöhen x rekursiv, bis es erreicht y
Aber ich mit der Ungeheuerlichkeit oben am Ende .
Es gibt einen viele die Art und Weise, dieses Problem und wieder zu lösen, ist es nicht das, was ich bin nach.
Was ich nach, wie, nachdem ich cons/conj entschieden, einen Speicher verwenden, und recurse, ich kann mit diesem Ende (nicht von mir geschrieben):
#(loop [i %1
acc nil]
(if (<= %2 i)
(reverse acc)
(recur (inc i) (cons i acc))))
Statt dem :
((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)
ich nehme es ein Anfang ein paar Probleme lösen zu können, aber ich bin ein bisschen durch die hässlichen Lösungen, die ich ...
Haben Sie keine Angst, schlechte Lösungen wegzuwerfen. Wenn Sie feststellen, dass Ihr Code unhandlich wird, machen Sie einen Schritt zurück und denken Sie darüber nach. Wenn es sich nicht richtig anfühlt, ist es das wahrscheinlich nicht. – Jeremy
@ JeremyHeiler: ok, aber die "Idee" ist nicht so schlecht, es ist die "Realisation"/der tatsächliche Code, der schlecht ist. Zum Beispiel schrieb die kurze Lösung using und accumulator + recursivity von jemandem, der die Probleme gelöst hatte (und einige von ihnen sind wirklich nicht trivial). Meine Idee scheint also nicht schlecht zu sein, aber ich kann meine Ideen (noch) nicht sauber umsetzen. Ich nehme an, es dauert einige Zeit, bis die Puzzlestücke einrasten: -/ –
Das tut es sicherlich. Übe einfach weiter und spiele mit Code! – Jeremy