Search code examples
functional-programmingclojureasciiconvertersmorse-code

Convert input string into Morse Code with Clojure


I am trying to develop a converter that takes an input string and converts it into morse code through a Morse Library map, while also respecting functional programming rules. Sorry for any clarification issues, I am new to Stack Overflow

(ns clojureassignment.core
  (:gen-class))
(require '[clojure.string :as str])

;this function is where the converter is developed

(defn  morse->ASCI
  [x]
  

  (def morse_Library {:A ".-":B "-...":C "-.-.":D "-..":E ".":F "..-.":G "--.":H "...."
:I "..":J ".---"
                      :K "-.-":L ".-..":M "--" :N "-.":O "---":P ".--.":Q "--.-":R ".-."
                      :S "...":T "-":U "..-":V "...-":W ".--":X "-..-":Y "-.--":Z "--.."
                      :0 "-----":1 ".----":2 "..---":3 "...--":4 "....-":5 "....."
                      :6 "-....":7 "--...":8 "---..":9 "----."})
 

  (let [stringVector  (str/upper-case(seq x))]         ;divide the string into a sequence of characters

;trying to create iteration of the input where it checks if its value is found in the morse library

    (doseq [[stringVector] (morse_Library)]       
      (if (= stringVector (morse_Library)
           (do  (println(str (key morse_Library))))
             (do  (println("characters not found"))))
             )))
    
  (print (str/upper-case stringVector))


    )








  (defn -main
    [& args]

    (println "ASCII to Morse Converter.")
    (println "Make sure to include whitespaces after each ASCII character. Add String")


    (def stringInput (read-line))

    (println stringInput )

    (morse->ASCI stringInput)


  


    )



  (-main)

I tried to create a "doseq" iteration where it checks if the value is found in the map.


Solution

  • ;; preparation of morse map
    (ns morse
      (:require [clojure.string :as str]))
    
    ;; I stole morse dictionary from some python code in:
    ;; https://www.geeksforgeeks.org/morse-code-translator-python/
    
    (def s "{ 'A':'.-', 'B':'-...',
                        'C':'-.-.', 'D':'-..', 'E':'.',
                        'F':'..-.', 'G':'--.', 'H':'....',
                        'I':'..', 'J':'.---', 'K':'-.-',
                        'L':'.-..', 'M':'--', 'N':'-.',
                        'O':'---', 'P':'.--.', 'Q':'--.-',
                        'R':'.-.', 'S':'...', 'T':'-',
                        'U':'..-', 'V':'...-', 'W':'.--',
                        'X':'-..-', 'Y':'-.--', 'Z':'--..',
                        '1':'.----', '2':'..---', '3':'...--',
                        '4':'....-', '5':'.....', '6':'-....',
                        '7':'--...', '8':'---..', '9':'----.',
                        '0':'-----', ', ':'--..--', '.':'.-.-.-',
                        '?':'..--..', '/':'-..-.', '-':'-....-',
                        '(':'-.--.', ')':'-.--.-'}")
    
    ;; and transformed it using clojure to a clojure map:
    (def m (read-string (str/replace 
                         (str/replace 
                          (str/replace 
                           (str/replace s
                                        "\n" "") 
                           "                    " " ")
                          ":" " ")
                         "'" "\"")))
    ;; now `m` contains the string-to-morse map
    

    The actual answer starts here:

    ;; convert any text string to a morse string:
    (defn string-to-morse [s]
      (str/join " "
                (map #(get m (str/upper-case %)) (str/split s #""))))
    
    ;; and this function can transform the output back to text:
    (defn morse-to-string [morse-string]
      (let [ms (zipmap (vals m) (keys m))]
        (str/join (map #(get (zipmap (vals m) (keys m)) % " ") 
                       (str/split morse-string #" ")))))