mutation 사용 (atom):
; (C) 2021 KIM Taegyoon
; Postfix Calculator
(require 'clojure.string)
(println "minicalc (C) 2021 KIM Taegyoon")
(println "+ - * / expt sqrt")
(defn check-num-op [stack n]
(cond
(< (count stack) n)
(do (printf "Not enough operands. Required: %s. Given: %s.\n" n (count stack))
false)
:else true))
(defn expt [a b] (Math/pow a b))
(defn calc [a]
(try
(let [stack (atom [])]
(doseq [tok (map read-string (clojure.string/split a #"\s+"))]
(cond
('#{+ - * / expt} tok)
(when (check-num-op @stack 2)
(reset! stack (cons ((eval tok) (second @stack) (first @stack)) (nthrest @stack 2))))
('#{sqrt} tok)
(when (check-num-op @stack 1)
(reset! stack (cons (Math/sqrt (first @stack)) (nthrest @stack 1))))
:else
(reset! stack (cons tok @stack))))
(first @stack))
(catch Exception e e)))
(loop []
(print "> ") (flush)
(let [line (read-line)]
(when line
(println (calc line))
(recur))))
fold 방식 (Clojure에서는 reduce) 사용:
iteration은 fold로 구현할 수 있다.
; (C) 2021 KIM Taegyoon
; Postfix Calculator
(require 'clojure.string)
(println "minicalc (C) 2021 KIM Taegyoon")
(println "+ - * / expt sqrt")
(defn check-num-op [stack n]
(if (< (count stack) n)
(do (printf "Not enough operands. Required: %s. Given: %s.\n" n (count stack))
false)
true))
(defn expt [a b] (Math/pow a b))
(defn calc1 [stack tok]
(cond ('#{+ - * / expt} tok)
(when (check-num-op stack 2)
(cons ((eval tok) (second stack) (first stack)) (nthrest stack 2)))
('#{sqrt} tok)
(when (check-num-op stack 1)
(cons (Math/sqrt (first stack)) (nthrest stack 1)))
:else
(cons tok stack)))
(defn calc [a]
(try
(if (> (count (clojure.string/trim a)) 0)
(first (reduce calc1 [] (map read-string (clojure.string/split a #"\s+"))))
0)
(catch Exception e e)))
(loop []
(print "> ") (flush)
(let [line (read-line)]
(when line
(println (calc line))
(recur))))
loop / recur 사용:
; (C) 2021 KIM Taegyoon
; Postfix Calculator
(require 'clojure.string)
(println "minicalc (C) 2021 KIM Taegyoon")
(println "+ - * / expt")
(defn expt [a b] (Math/pow a b))
(defn calc [a]
(try
(cond (> (count (clojure.string/trim a)) 0)
(loop [stack '(), expr (map read-string (clojure.string/split a #"\s+"))]
(cond (empty? expr)
(first stack)
:else
(let [tok (first expr)]
(cond ('#{+ - * / expt} tok)
(recur (cons ((eval tok) (second stack) (first stack)) (nthrest stack 2)) (rest expr))
:else
(recur (cons tok stack) (rest expr))))))
:else 0)
(catch Exception e e)))
(loop []
(print "> ") (flush)
(let [line (read-line)]
(when line
(println (calc line))
(recur))))
'Programming' 카테고리의 다른 글
SQL 툴 비교 (0) | 2022.02.16 |
---|---|
Import CSV File Into MySQL Table (mysqltutorial.org) (0) | 2022.02.15 |
Joker 사용 후기 (0) | 2021.12.15 |
(HTML) viewport 기본 폭은 980 픽셀이다. (0) | 2021.11.09 |
(SQL Developer) 다량 insert할 때 (0) | 2021.11.08 |