Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Last active August 1, 2022 21:50
Show Gist options
  • Save ericnormand/415c98b46e216978728156fecc20bac4 to your computer and use it in GitHub Desktop.
Save ericnormand/415c98b46e216978728156fecc20bac4 to your computer and use it in GitHub Desktop.
471 Eric Normand Newsletter

License plates

When you cross the border in a car, you have to abide by the local license plate regulations. (This is not true, but let's play pretend!) The order of the numbers and letters stays the same. But the groupings change from country to country.

Write a function that takes a license plate code (letters, digits, and hyphens in a string) and a group size (integer). The function should return a new string with the characters regrouped with hyphens between groups. All groups should be of the given size, except for perhaps the first, if there aren't enough characters to fill the group.

Examples

(regroup "A5-GG-B88" 3) ;=> "A-5GG-B88"
(regroup "A5-GG-B88" 2) ;=> "A-5G-GB-88"
(regroup "6776" 2) ;=> "67-76"
(regroup "F33" 1) ;=> "F-3-3"
(regroup "IIO" 7) ;=> "IIO"

Thanks to this site for the problem idea, where it is rated Expert in Swift. The problem has been modified.

Please submit your solutions as comments on this gist.

To subscribe: https://ericnormand.me/newsletter

@rotaliator
Copy link

(defn regroup [s n]
  (->> (str/replace s #"-" "")
       (str/reverse)
       (partition-all n)
       (map reverse)
       (map #(apply str %))
       (reverse)
       (str/join "-")))

@thomas-shares
Copy link

(defn regroup [string size]
  (let [replaced (str/replace string #"-" "")
        length (count replaced) ]
    (if (or (and (< size length) (zero? (rem length size))) (not (< size length)))
      (str/join "-" (map str/join (partition-all size replaced )))
      (let [f (first replaced)
            r (rest replaced) ]
        (str f "-" (str/join "-" (map str/join (partition-all size (str/join "" r)))))))))

Yeah, not as nice as some of the others... I hadn't thought about reversing it, that is clever.

@esciafardini
Copy link

esciafardini commented Jul 16, 2022

(defn regroup [s n]
  (->> s
       reverse
       (remove #{\-})
       (partition-all n)
       (interpose \-)
       flatten
       reverse
       (apply str)))

@mchampine
Copy link

(defn regroup [s n]
  (->> (remove #{\-} (reverse s))
       (partition-all n)
       (map #(apply str (reverse %)))
       reverse
       (str/join "-")))

@miner
Copy link

miner commented Jul 16, 2022

(require '[clojure.string :as str])

(defn regroup [s width]
  (let [base (str/replace s "-" "")
        cnt (count base)]
    (str (reduce (fn [sb i] (.insert ^StringBuilder sb ^int i \-))
                 (StringBuilder. base)
                 (range (- cnt width) 0 (- width))))))

@reborg
Copy link

reborg commented Jul 18, 2022

So, if I had to showcase Clojure expressiveness, I'd go with a version similar to many others above:

(defn regroup
  [plate n]
  (->> (s/replace plate #"-" "")
       reverse
       (partition-all n)
       (interpose "-")
       reverse
       (mapcat reverse)
       (apply str)))

When I'm told "ahhh but that's so slow" then I can say go with something like:

(defn regroup
  [plate n]
  (let [nodash (s/replace plate #"-" "")
        cnt (count nodash)]
    (str
     (reduce
      (fn [^StringBuilder sb idx]
        (let [i (- cnt idx)
              group (inc (mod idx n))
              ch (subs nodash (dec i) i)]
          (.insert sb 0 ch)
          (when (and (= group n) (> i 1))
            (.insert sb 0 "-"))
          sb))
      (StringBuilder.)
      (range cnt)))))

But then somebody might say "aahhh but this is passing through the string twice, what if the string is huge?"

(defn regroup
  [^String plate n]
  (loop [i (count plate) sb (StringBuilder.) group 1]
    (if (= 0 i)
      (str sb)
      (let [i (dec i)
            ch (subs plate i (inc i))]
        (cond (= "-" ch)
              (recur i sb group)
              (and (> i 0) (= group n))
              (recur i (.insert sb 0 (str "-" ch)) 1)
              :else
              (recur i (.insert sb 0 ch) (inc group)))))))

@maquirag
Copy link

(defn regroup [text size]
    (->> text
        (filter #(not= "-" %))
        (reverse) 
        (partition size size nil)
        (reverse)
        (map reverse)
        (interpose "-")
        (flatten)
        (apply str)))```

@KingCode
Copy link

KingCode commented Jul 20, 2022

(require '[clojure.string :as str])

(defn regroup [plate n]
  (->> plate reverse
       (transduce (comp 
                   (remove #{\-})
                   (partition-all n)
                   (map #(str/join [\-]))
                  into
                  ())
       (apply str)))

@harwood19
Copy link

So yeah, got a DM response to my prior post/inquiry saying that “…we don’t really select the best solution nor breakdown or encourage. We don’t teach nor do we collaborate. We simply respond with our best Closure solution per exercise. They go into a black hole. But hey, it’s something… all we got.”

Fair enough! Again, figure ya’ll been doing this awhile. Appreciate your grace as I learn the culture while’st playing with a new coding language.

@KingCode
Copy link

@harwood19 Welcome aboard!

To answer your question, there is no sanctioning except perhaps for non-courteous behavior (which I have never seen).
Basically, it is up to others to comment on your code, which usually happens for interesting solutions.

My only suggestion for your posts would be to use the nice formatting tool afforded here, by enclosing your code with triple backslashes and the word clojure above, and triple backslashes below. The Preview pane can be used before you submit the post.

@ericnormand
Copy link
Author

(defn regroup [s size]
  (->> s
       (remove #{\-})
       reverse
       (partition-all size)
       (interpose \-)
       flatten
       reverse
       (apply str)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment