En un proyecto en el que estoy trabajando me encontré con un problema interesante que me llama la atención sobre otras soluciones. Estoy leyendo "The Little Schemer", así que estoy probando algunas técnicas de recursión. Me pregunto si hay otra manera de hacer esto con la recursión y también me interesa si hay un enfoque sin usar la recursión.Particionado de una secuencia - Recursividad en Clojure (o Lisp en general)
El problema es tomar una secuencia y dividirla en un seqs de secos tomando cada elemento enésimo. Por ejemplo, este vector:
[ :a :b :c :d :e :f :g :h :i ]
cuando se repartió con n = 3 produciría la SEC
((:a :d :g) (:b :e :h) (:c :f :i))
y con n = 4:
((:a :e :i) (:b :f) (:c :g) (:d :h))
y así sucesivamente. Lo resolví usando dos funciones. El primero crea los seqs internos y el otro los une. Aquí están mis funciones:
(defn subseq-by-nth
"Creates a subsequence of coll formed by starting with the kth element and selecting every nth element."
[coll k n]
(cond (empty? coll) nil
(< (count coll) n) (seq (list (first coll)))
:else (cons (nth coll k) (subseq-by-nth (drop (+ n k) coll) 0 n))))
(defn partition-by-nth
""
([coll n]
(partition-by-nth coll n n))
([coll n i]
(cond (empty? coll) nil
(= 0 i) nil
:else (cons (subseq-by-nth coll 0 n) (partition-by-nth (rest coll) n (dec i))))))
No estoy completamente satisfecho con la función de partición por enésima tener múltiples aridad simplemente por la recursividad, pero no podía ver otra manera.
Esto parece funcionar bien con todos los casos de prueba. ¿Es este un enfoque decente? ¿Es demasiado complicado? ¿Hay alguna manera de hacer esto sin recurrencia o tal vez en una sola función recursiva?
Gracias por las sugerencias. Soy nuevo en Clojure y Lisp, así que estoy aprendiendo las diferentes técnicas sobre la marcha.
Gracias, esto es increíble!No tenía idea de que podría ser tan fácil. Justo cuando creo que estoy empezando a entender esto, me muestran lo poco que realmente hago. –
¡Conozco la sensación! – JohnJ
@DaveKincaid: Debería intentar modelar su solución utilizando las funciones existentes de alto orden en lugar de utilizar la recursión y sin duda podrá proponer este tipo de soluciones concisas :) – Ankur