How to split this?

Hello,

Why does the split not work here :

; Create an infix function that takes a list like (1 + 3 * 4 - 5) and transforms 
; it into the lists that Clojure needs in order to correctly evaluate the 
; expression using operator precedence rules.

(defn infix [expr]
  (let [splitted (str/split expr #" ")]
    splitted))

(print (infix "(1 + 3 * 4 - 5) ") )

What did it do, vs what did you expect?

P.S. Do not allow print to mislead you! For this kind of troubleshooting, it’s best to work in the REPL and let it do the printing. Look at what detail is omitted by print:

user=> (require '[clojure.string :as string])
nil
user=> (string/split "(1 + 3 * 4 - 5)"  #" ")
["(1" "+" "3" "*" "4" "-" "5)"]
user=> (print *1)
[(1 + 3 * 4 - 5)]
nil

Thanks, now construct something clojure can be working with
and find a way to remove the parentheses first

Think there a better way :

(defn infix [expr]
  (let [splitted (str/split (subs expr 1 (- (count expr) 1)) #" ")]
    splitted))

You can call (read-string "(1 + 3 * 4 - 5)") to get '(1 + 3 * 4 - 5) (a list of numbers and symbols) back. You can do any processing with that you like, partition, filter, …

Judging by the comment you have there outlining the exercise, it doesn’t seem like your function should be taking a string at all. The way I read it, you are supposed to accept an expression such as the list '(1 + 3 * 4 - 5) and then inside your function reorder it to become (- (+ 1 (* 3 4) 5) which you can then evaluate. Parsing strings as Clojure code seems like missing the point of the exercise, and if parsing was the objective, regular expressions are definitely not the right tool for the job.

I think so

Maybe this better :

(defn infix [expr]
  (let [first (first expr)
        second (nth expr 1)
        thirth (nth expr 2)
        fourth (nth expr 3)
        fifth (nth expr 4)
        sixth (nth expr 5)
        seventh (nth expr 6)]
    (list sixth (list second (list fourth thirth fifth) first) seventh)))

Your exercise says “a list like”, so you should assume that the function should be able to evaluate any kind of basic arithmetic enclosed in a list, not just that specific example.

This better

(def priorities {'+ 1, '- 1, '* 2, '/ 2})

(defn infix2 [expr]
  (let [first-number (first expr)
        operator (nth expr 1)
        second-number (nth expr 2)
        r (drop 3 expr)]
    (if (empty? r)
      (list operator first-number second-number)
      (if (< (get priorities operator) (get priorities (first r)))
        (list operator first-number (infix2 (conj r second-number)))
        (infix2 (conj r (list operator first-number second-number)))))))

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.