Last active
June 2, 2024 17:22
-
-
Save PEZ/2cd6e7158b0ea3d24d125c997a0f8d1e to your computer and use it in GitHub Desktop.
Longest Increasing Sub-Seq – Rich 4Clojure Problem 53 – See: https://github.com/PEZ/rich4clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns rich4clojure.hard.problem-053 | |
(:require [hyperfiddle.rcf :refer [tests]])) | |
;; = Longest Increasing Sub-Seq = | |
;; By 4Clojure user: dbyrne | |
;; Difficulty: Hard | |
;; Tags: [seqs] | |
;; | |
;; Given a vector of integers, find the longest | |
;; consecutive sub-sequence of increasing numbers. If two | |
;; sub-sequences have the same length, use the one that | |
;; occurs first. An increasing sub-sequence must have a | |
;; length of 2 or greater to qualify. | |
(def __ :tests-will-fail) | |
(comment | |
) | |
(tests | |
(__ [1 0 1 2 3 0 4 5]) := [0 1 2 3] | |
(__ [5 6 1 3 2 7]) := [5 6] | |
(__ [2 3 3 4 5]) := [3 4 5] | |
(__ [7 6 5 4]) := []) | |
;; To participate, fork: | |
;; https://github.com/PEZ/rich4clojure | |
;; Post your solution below, please! |
status203
commented
Feb 16, 2022
•
Inspired by above solution:
(defn partition-by-equal-one
[xs]
(let [switch (reductions = true (map #(= 1 %) (map - (rest xs) (pop xs))))]
(->> switch
(map list xs)
(partition-by second)
(map (partial map first)))))
(defn longest-subseq-ones
"use equal one as indicators"
[xs]
(let [partitioned (partition-by-equal-one xs)
sorted (sort-by count partitioned)
output (vec (last sorted))]
(if (> (count output) 1)
output
[])))
OK is mine more simplistic?
(defn __
"vector of integers find the longest consecutive sub-sequence of increasing numbers."
([vecin] (__ vecin [] []))
([[hd & tail] this-run max-run]
(let [step ; helper fn to ensure lazy
(fn [h t]
(if (not (seq t)) max-run ; when t is at end return max-run
(if (= (inc h) (first t)) ; Is next int hd+1?
(let [run-add (if (seq this-run) (conj this-run (first t))
(conj this-run h (first t)))]
(if (> (count run-add) (count max-run)) ;this run> max so far
(__ t run-add run-add) (__ t run-add max-run)))
(if (> (count this-run) (count max-run)) ;this run > max so far
(__ t [] this-run) (__ t [] max-run)))))]
(step hd tail))))
I built it from the org.clojure section making clojure lazierhttps://clojure.org/reference/lazy
Sorry for the bad formatting.
(fn [coll]
(let [result (->> coll
(partition 2 1)
(partition-by (fn [[e1 e2]] (== 1 (- e2 e1))))
(filter (fn [[[e1 e2]]] (== 1 (- e2 e1))))
(reduce (fn [c1 c2] (if (< (count c1) (count c2)) c2 c1)) nil))]
(if (not-empty result)
(cons (ffirst result) (map second result))
'())))
(def __ (fn [coll] (let [predict #(= 1 (- (last %) (first %)))
result (map
(comp set flatten (partial filter predict))
(partition-by predict
(partition-all 2 1 coll)))
result_map (group-by count result)
max_key (apply max (keys result_map))]
(vec (apply sorted-set (first (result_map max_key)))))))
(defn get-consecutive-seq [sequence]
(letfn [(reduce-fn [acc n]
(let [last-item (last acc)]
(if (= (inc last-item) n)
(conj acc n)
(reduced acc))))]
(reduce reduce-fn [(first sequence)] (rest sequence))))
(defn __ [_seq]
(let [initial-consecutive-seq (get-consecutive-seq _seq)
initial-consecutive-seq-size (count initial-consecutive-seq)
rest-seq (drop initial-consecutive-seq-size _seq)
rest-consecutive-seq (get-consecutive-seq rest-seq)
rest-consecutive-seq-size (count rest-consecutive-seq)]
(->>
(if (>= initial-consecutive-seq-size rest-consecutive-seq-size)
initial-consecutive-seq
rest-consecutive-seq)
(#(if (> (count %) 1) % [])))))
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment