Fork me on GitHub
#code-reviews
<
2023-10-18
>
Pavel Filipenco12:10:15

Hello! Are there any suggestions for improving this?

(defn opposite-pairs [start end]
  (let [coll (range start (+ 2 end))
        max (last coll)]
    (->> coll
      (take (-> (count coll) (/ 2)))
      (mapcat
        (fn [x]
          (let [other (- max x)]
            (if (= x other)
              [x]
              [x other]))))
      (run! println))))
Reference output:
user> (opposite-pairs 1 999)
1
999
2
998
3
997
4
996
5
[...]

👀 1
kennytilton13:10:33

Isn't max just (+ 2 end) minus one? I hate threading. 🙂 What is wrong with (/ (count coll) 2)? Looking at the logic, I do not see a need to create the coll range (or the take). Just do a for loop up to half the difference between start and end, computing other as you do now -- that was insanely sloppy pseudo code -- I have to run -- but hopefully you get the idea.

serioga13:10:16

@U060FHA3K28 do you really need to work with sequences here?

(loop [start 1 end 999]
    (when (< start end)
      (println start end)
      (recur (inc start) (dec end)))

👍 4
Fredrik14:10:36

You can split your function up into a part that generates the numbers, and another that does something with them, in your case printing them.

(defn opposite-pairs [start end]
  (cond
    (< start end) (concat [start end] (opposite-pairs (inc start) (dec end)))
    (== start end) [start]))
and then compose with println:
(run! println (opposite-pairs start end))

👍 1
Pavel Filipenco15:10:11

General enough of a solution?

(defn converge [point & fns]
  (loop [ms (map (fn [f] {:prev (f) :fn (f point)}) fns)
         res []]
    (if (empty? ms)
      res
      (recur
        (->> ms
          (map #(update % :prev (:fn %)))
          (filter :prev))
        (conj res (map :prev ms))))))

(defn from [start continue? step]
  (fn
    ([] start)
    ([point]
     (fn [prev]
       (when (continue? prev point)
         (step prev))))))

(comment
  (->>
    (converge 500
      (from 999 #(> %1 (+ 1 %2)) #(- % 1))
      (from 1 < #(+ % 1)))
    (flatten)
    (run! println)))

teodorlu12:10:27

another option:

(defn opposite-pairs [start end]
  (let [numbers (range start (inc end))]
    (interleave numbers (reverse numbers))))

(take 10 (opposite-pairs 1 999))
;; => (1 999 2 998 3 997 4 996 5 995)
I expect @U0HJNJWJH’s solution to be faster than mine, because I expect calculating every other number to be faster than reversing a list.

pithyless22:10:27

No need for the reverse, range supports a step argument:

(interleave (range start (inc end))
            (range end (dec start) -1))

👍 3