@lllaptemlll

Как оптимизировать код и избавиться от костылей в рекурсии на первой и последней итерации?

Задание: Напишите функцию, которая принимает на вход канал состоящий из последовательности чисел, первое из которых является количеством последующих элементов, которые нужно поместить в массив, а за ней следуют элементы этого массива, и возвращающая отдельные массивы. Например 3, 4, 0, 2, 1, 2, 2, 4, 5 будет превращено в [4, 0, 2], [2], [4, 5]

Сейчас это выглядит примерно так:
В функции main я принимаю на вход вектор и с помощью рекурсии каждое значение либо помещается в Temp, если Count не 0, либо иначе присваивается Count'у, одновременно с чем Temp помещается в Result. Но выходит такая штука, что как только рекурсия заканчивается, последний Temp не уходит в Result и поэтому приходится приписывать костыль в vec-to-chan c добавлением лишнего элемента. Можно как-то найти более правильное решение, чтобы избавиться от костыля? Пробовал в if-let добавить Temp в Result, но сама конструкция else не особо то хочет работать
И можно ли избавиться как-то от условия с (if (= i 0) ? Оно служит для того, чтобы в самый первый Temp с пустым [] не записывался в Result

(ns untitled1.core
  (:require [promesa.core :as p]
            [clojure.core.async
             :as a
             :refer [>! <! >!! <!! go chan close! go-loop]]))

(defn vec-to-chan [vec]
    (let [c (chan)
          v (conj vec "end")]
      (go (doseq [x v]
                (>! c x))

              (close! c))
  c))

(defn main[c]
  (<!!
    (go-loop [Result [] Temp [] Count 0 i 0]
      (if-let [x (<! c)]
        (if (= i 0)
          (recur Result [] x (inc i))
          (do
            (if (= Count 0)
              (recur (conj Result Temp) [] x (inc i))
              (recur Result (conj Temp x) (dec Count) (inc i))
              ))
          )
        Result)
      )))


(def ch (vec-to-chan [3 4 0 2 1 2 2 4 5]))
(println "Result" (main ch))
  • Вопрос задан
  • 190 просмотров
Решения вопроса 1
leahch
@leahch
3D специалист. Dолго, Dорого, Dерьмово.
Вот, накидал. Самому интересно стало :-) - https://repl.it/@AlexeyCheremisi/DelightfulValuabl...
И да, не ругайте строго! Это мой первый код на этом языке, и кажется, не последний :-)
PS. Немного облагородил через let т привел возвращаемое к vector, как в вопросе!
;; my recursion function
(defn func [inp]
  (loop [ acc [] [cnt & rest] inp ] ;; accumulator, counter from rest, rest
    (let [head (take cnt rest) tail (drop cnt rest)] ;; get portion of data to head, get tail of data
      (if (= (count rest) 0) acc ;; return accumulator if no data
        (recur (conj acc (into [] head)) tail))))) ;; loop with convert list to vector

;; input data
(def indata [3 4 0 2 1 2 2 4 5])

;; test recursion
(func indata) ;; => [[4 0 2] [2] [4 5]]
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы