Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
414 PurelyFunctional.tv Newsletter

Decimal to binary

Write a function that takes a string and replaces all occurrences of numbers with their decimal form.

Examples

(d->b "I have 2 arms.") ;=> "I have 10 arms."
(d->b "That costs 3 dollars. But I only have 1 dollar.") ;=> "That costs 11 dollars. But I only have 1 dollar."
(d->b "I was born in 1981.") ;=> "I was born in 11110111101."

Any contiguous string of digits is a number. That means that spaces, periods, and commas separate numbers instead of indicating differnt parts. For instance, 2,000 is the number 2 followed by the number 000.

Thanks to this site for the challenge idea where it is considered Expert in JavaScript. The problem has been modified from the original.

Please submit your solutions as comments on this gist.

@steffan-westcott
Copy link

steffan-westcott commented Feb 15, 2021

(require '[clojure [string :as str] [pprint :as pp]])

(defn d->b [s]
  (str/replace s #"\d+" #(pp/cl-format nil "~B" (read-string %))))

@souenzzo
Copy link

souenzzo commented Feb 15, 2021

Nice solution @steffan-westcott !! Your solution may run on cljs too

(letfn [(try-s->b10->b2 [s]
          (try (-> s
                   edn/read-string
                   int
                   (Integer/toString 2))
               (catch Throwable ex
                 s)))
        (d->b [s]
          (->> (string/split s #"\s")
               (map try-s->b10->b2)
               (string/join " ")))]
  [(d->b "I have 2 arms.")
   #_#_=> "I have 10 arms."
   (d->b "That costs 3 dollars. But I only have 1 dollar.")
   #_#_=> "That costs 11 dollars. But I only have 1 dollar."
   (d->b "I was born in 1981.")
   #_#_=> "I was born in 11110111101."])

@jaihindhreddy
Copy link

jaihindhreddy commented Feb 15, 2021

Haven't tried in CLJS, but should work.

(defn d->b [s]
  (let [replacement
          #?(:clj  #(.toString (BigInteger. %) 2)
             :cljs #(.toString (BigInt. %) 2))]
    (clojure.string/replace s #"\d+" replacement)))

@sztamas
Copy link

sztamas commented Feb 15, 2021

(defn d->b [s]
  (string/replace s #"\d+" #(-> % Long/parseLong Long/toBinaryString)))

@burnall
Copy link

burnall commented Feb 15, 2021

(defn- s->b [s]
  (-> s
      (Integer/parseInt)
      (Integer/toString 2))) 

(defn d->b [s]
  (clojure.string/replace s #"\d+" s->b))

@diavoletto76
Copy link

diavoletto76 commented Feb 15, 2021

(defn d->b [xs]
  (clojure.string/replace xs #"\d+" #(Integer/toString (read-string %1) 2)))

@mchampine
Copy link

mchampine commented Feb 15, 2021

Since there are several good versions that use clojure.string/replace, I decided to try again with the constraint of not using it.

(defn cvt-ints [v]
  (let [rv (read-string v)]
    (if (integer? rv) (Integer/toString rv 2) v)))

(defn d->b [s]
  (->> (clojure.string/split s #" ")
       (map cvt-ints)
       (interpose " ")
       (apply str)))

@dfuenzalida
Copy link

dfuenzalida commented Feb 15, 2021

I overlooked the clojure.string/replace function, so this is a naive but working version:

(defn binary-string [n]
  (Long/toBinaryString n))

(defn d->b [s]
  (let [words (clojure.string/split s #"\d+")
        numbs (map (comp binary-string read-string) (re-seq #"\d+" s))]
    (reduce str (interleave words (concat numbs (repeat ""))))))

;; (d->b "I have 2 arms")
;; => "I have 10 arms"

;; (d->b "That costs 3 dollars. But I only have 1 dollar.")
;; => "That costs 11 dollars. But I only have 1 dollar."

;; (d->b "I was born in 1981.")
;; => "I was born in 11110111101."

@dfornika
Copy link

dfornika commented Feb 15, 2021

(defn try-parse-int [s]
  (try (Integer/parseInt s)
    (catch Exception e s)))

(defn int-to-binary [i]
  (if (number? i)
    (Integer/toBinaryString i)
    i))

(defn d->b [s]
  (let [split-s (re-seq #"[^\d]+|\d+" s)]
    (->> split-s
         (map try-parse-int)
         (map int-to-binary)
         (str/join ""))))

@segudev
Copy link

segudev commented Feb 19, 2021

(defn d->b [string]
  (let [regex #"\d+"
        converter #(Integer/toBinaryString (Integer/parseInt %))
        binary-digits (map converter (re-seq regex string))
        split-string (str/split string regex)]
    (str/join (cons (first split-string)
              (interleave binary-digits (rest split-string))))))

@prairie-guy
Copy link

prairie-guy commented Apr 5, 2021

(defn d->b [s]                                                                                                                                        
  (string/replace s #"[0-9]+" #(Integer/toString (read-string %1) 2)))

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