clojure refactor code from recursion -


i have following bit of code produces correct results:

(ns scratch.core   (require [clojure.string :as str :only (split-lines join split)]))  (defn numberify [str]   (vec (map read-string (str/split str #" "))))  (defn process [acc sticks]   (let [smallest (apply min sticks)         cuts (filter #(> % 0) (map #(- % smallest) sticks))]      (if (empty? cuts)       acc       (process (conj acc (count cuts)) cuts))))  (defn print-result [[x & xs]]   (prn x)   (if (seq xs)     (recur xs)))  (let [input "8\n1 2 3 4 3 3 2 1"       lines (str/split-lines input)       length (read-string (first lines))       inputs (first (rest lines))]   (print-result (process [length] (numberify inputs)))) 

the process function above recursively calls until sequence sticks empty?.

i curious know if have used take-while or other technique make code more succinct?

if ever need work on sequence until empty use recursion can't thinking there better way.

your core problem can described as

  1. stop if count of sticks zero
  2. accumulate count of sticks
  3. subtract smallest stick each of sticks
  4. filter positive sticks
  5. go 1.

identify smallest sub-problem steps 3 , 4 , put box around it

(defn cuts [sticks]   (let [smallest (apply min sticks)]     (filter pos? (map #(- % smallest) sticks)))) 

notice sticks don't change between steps 5 , 3, cuts fn sticks->sticks, use iterate put box around that:

(defn process [sticks]   (->> (iterate cuts sticks) ;; ----- 8< ------------------- 

this gives infinite seq of sticks, (cuts sticks), (cuts (cuts sticks)) , on

incorporate step 1 , 2

(defn process [sticks]   (->> (iterate cuts sticks)        (map count)         ;; count each sticks        (take-while pos?))) ;; accumulate while counts positive  (process [1 2 3 4 3 3 2 1]) ;-> (8 6 4 1) 

behind scene algorithm hardly differs 1 posted, since lazy seqs delayed implementation of recursion. more idiomatic though, more modular, uses take-while cancellation adds expressiveness. doesn't require 1 pass initial count , right thing if sticks empty. hope looking for.


Comments

Popular posts from this blog

javascript - Google App Script ContentService downloadAsFile not working -

javascript - Function overwritting -

php - Find a regex to take part of Email -