NullPointerException using Clojure - clojure

I'm new to clojure, attempting to write a function (all-bit-seqs n) that generates all bit strings of length n as a list. So if I were to call (all-bit-seqs 2), it would output ((0 0) (0 1) (1 0) (1 1)) in any order. However, I am getting a NullPointerException when I call the helper function rest-bit-seqs, and I can't figure out why. My code is as follows, any help would be appreciated.
(defn not-bit [x]
(* -1 (- x 1))
)
(defn inc-bit-seq [x]
(cond
(= 0 (not-bit (first x))) (cons 0 (inc-bit-seq (rest x)))
:else (cons 1 (rest x))
)
)
(defn pow [x, y]
(cond
(not= y 0) (* x (pow x (- y 1)))
:else 1
)
)
(defn rest-bit-seqs [n, x, lst]
(cond
(not= x (pow 2 n)) (cons lst (rest-bit-seqs n (+ 1 x) (inc-bit-seq lst)))
:else '()
)
)
(defn zero-seq [n]
(cond
(= n 0) '()
:else (cons 0 (zero-seq (- n 1)))
)
)
(defn all-bit-seqs [n]
(rest-bit-seqs n 0 (zero-seq n))
)

that is because you don't handle the case of an empty sequence here:
(defn inc-bit-seq [x]
(cond
(= 0 (not-bit (first x))) (cons 0 (inc-bit-seq (rest x)))
:else (cons 1 (rest x))
)
)
so at one point you pass (first x) (which is nil for an empty seq) to not-bit.
the following fix solves this:
(defn inc-bit-seq [x]
(when (seq x)
(cond
(= 0 (not-bit (first x))) (cons 0 (inc-bit-seq (rest x)))
:else (cons 1 (rest x))
))
)
in repl:
user> (all-bit-seqs 2)
((0 0) (1 0) (0 1) (1 1))
the other things that are totally weird here, is your choice of cond instead of simple if, and uncommon formatting. I would consider rewriting the code this way:
(defn not-bit [x]
(* -1 (- x 1)))
(defn inc-bit-seq [x]
(when (seq x)
(if (zero? (not-bit (first x)))
(cons 0 (inc-bit-seq (rest x)))
(cons 1 (rest x)))))
(defn pow [x, y]
(if-not (zero? y)
(* x (pow x (- y 1)))
1))
(defn rest-bit-seqs [n, x, lst]
(when-not (== x (pow 2 n))
(cons lst (rest-bit-seqs n (+ 1 x) (inc-bit-seq lst)))))
(defn zero-seq [n]
(when-not (zero? n)
(cons 0 (zero-seq (- n 1)))))
(defn all-bit-seqs [n]
(rest-bit-seqs n 0 (zero-seq n)))
(it's about style, haven't looked at overall code correctness)

Your error is here:
(= 0 (not-bit (first x)))
If x is empty, (first x) will return nil, so this will happen:
(= 0 (not-bit nil))
(= 0 (* -1 (- nil 1))
When you try to evaluate (- nil 1), you'll get a NullPointerException.
The quick-and-dirty way to fix the problem is to get rid of not-bit and replace that condition with
(= 1 (first x))
However, there are much shorter/simpler ways to solve this problem. Here's one way:
(defn inc-bit-seq [[head & tail]]
(if (zero? head)
(cons 1 tail)
(cons 0 (inc-bit-seq tail))))
(defn all-bit-seqs [n]
(take (bit-shift-left 1 n)
(iterate inc-bit-seq (repeat n 0))))
Another way would be to use strings:
(defn pad-first [n x xs]
(concat (repeat (- n (count xs)) x) xs))
(defn all-bit-seqs [n]
(map (comp (partial pad-first n 0)
(partial map #(Character/getNumericValue %))
#(Long/toBinaryString %))
(range (bit-shift-left 1 n))))

Related

Why is this function not evaluating

I have been stuck on this one for a while and cant figure it out. Why is the function not evaluating for values greater or equal than 2? It works fine for values under it but anything above and it just prints the output seen in the pic
((fn fib
([x] (cond
(zero? x) []
(= x 1) [1]
(>= x 2) fib (- x 2) [1 1]))
([x seq] (if (zero? x)
seq
(recur (dec x) (conj seq (+ (last seq) (nth seq (- (count seq) 2)))))))) 3)
enter image description here
You forgot one parenthesis on this line, before fib:
(>= x 2) fib (- x 2) [1 1]))
After you will add it, this code will work. Just note that your variables shouldn't have the same name as already existing functions- you were shadowing core function seq.
((fn fib
([x] (cond
(zero? x) []
(= x 1) [1]
(>= x 2) (fib (- x 2) [1 1])))
([x values]
(if (zero? x)
values
(recur (dec x)
(conj values (+ (last values)
(nth values (- (count values) 2)))))))) 3)

Why is this lazy-sequence not printing?

I cannot figure out why this lazy-sequence is not printing. I've looked at other posts on here (such as this) and none seem to be exactly what I am looking for. Here is the code segment...
(defn exp [x n]
(reduce * (repeat n x))
)
(defn primes
([] (primes 1 1))
([n m] (if (= n 1) (lazy-seq (cons (* (exp 7 n) (exp 11 m)) (primes (+ m 1) (1))))
(lazy-seq (cons (* (exp 7 n) (exp 11 m)) (primes (- n 1) (+ m 1)))))
)
)
(take 4 (primes))
Any help is greatly appreciated. Thank you!
The three comments really give the answer. But always good to actually see the code, so here are two ways that give the printed output.
(defn exp [x n]
(reduce * (repeat n x)))
(defn primes
([] (primes 1 1))
([n m] (if (= n 1)
(lazy-seq (cons (* (exp 7 n) (exp 11 m)) (primes (+ m 1) 1)))
(lazy-seq (cons (* (exp 7 n) (exp 11 m)) (primes (- n 1) (+ m 1)))))))
(defn x-1 []
(doseq [prime (take 4 (primes 2 2))]
(println prime)))
(defn x-2 []
(->> (primes 2 2)
(take 4)
(apply println)))

Clojure for return result in list?

this code:
(vector (first x)
(for [i (range (dec (count x)))] (+ (nth x i) (nth x (inc i))))
(last x)
)
will return [1 (2) 1] for x=[1 1]. How I can make [1 2 1] instead [1 (2) 1] in best practice?
A simpler way to do what you want:
(concat [(first x)] (map + x (rest x)) [(last x)])
or if it must be a vector:
(into [(first x)] (conj (mapv + x (rest x)) (last x)))
As a convenient shorthand equivalent to Diego's answer, I would usually use a syntax-quoted expression here:
`[~(first x)
~#(map + x (rest x))
~(last x)]
An even more bulletproof solution is:
(flatten [ (first x)
(map + x (rest x))
(last x) ] )

Trapezoidal Integration is not accurate enough in Clojure

So currently, I wrote a Clojure code to do Trapezoidal integration of a polynomial function in HackerRank.com:
https://www.hackerrank.com/challenges/area-under-curves-and-volume-of-revolving-a-curv
(defn abs[x]
(max x (- 0 x))
)
(defn exp[x n]
(if (> n 0)
(* x (exp x (- n 1)))
1
)
)
(defn fact[x]
(if (> x 0)
(* x (fact (- x 1)))
1)
)
(defn func[x lst1 lst2]
((fn step [sum lst1 lst2]
(if (> (.size lst1) 0)
(step (+ sum (* (last lst1) (exp x (last lst2)))) (drop-last lst1) (drop-last lst2))
sum
)
)
0 lst1 lst2
)
)
(defn integrate[f a b]
(def h 0.001)
(def n (/ (abs (- b a)) h))
((fn step[i sum]
(if (< i n)
(step (+ i 1) (+ sum (f (+ (* i h) a))))
(* h (+ (/(+ (f a) (f b)) 2) sum))
)
) 0 0)
)
(defn volumeIntegral[f a b]
(defn area[r]
(* 3.14159265359 (* r r)))
(def h 0.001)
(def n (/ (abs (- b a)) h))
((fn step[i sum]
(if (< i n)
(step (+ i 1) (+ sum (area (f (+ (* i h) a)))))
(* h (+ (/ (+ (f a) (f b)) 2) sum))
)
) 0 0)
)
(defn lineToVec[line_str] (clojure.string/split line_str #"\s+"))
(defn strToDouble [x] (Double/parseDouble (apply str (filter #(Character/isDigit %) x))))
(defn readline[vec]
((fn step[list vec]
(if (> (.size vec) 0)
(step (conj list (last vec)) (drop-last vec))
list
)
) '() vec)
)
(integrate (fn [x] (func x '(1 2 3 4 5 6 7 8) '(-1 -2 -3 -4 1 2 3 4))) 1 2)
(volumeIntegral (fn [x] (func x '(1 2 3 4 5 6 7 8) '(-1 -2 -3 -4 1 2 3 4))) 1 2)
However, the output I have is:
107.38602491666647
45611.95754801859
While is supposed to be around:
101.4
41193.0
My code passed the first two test cases, but didn't manage to pass the rest. I assume is because of the issue accuracy. I looked through my code several times but couldn't seem to make it better. What am I doing wrong here ? Thank you.
Your exp function isn't quite right -- it doesn't handle negative exponents correctly. Probably best just to use Math/pow.
The other thing you could do is adjust your h value in volumeIntegral but to avoid stack issues, use recur (which gives you tail recursion), e.g. here's a slightly modified version:
(defn volume-integral [f a b]
(defn area[r]
(* Math/PI (* r r)))
(def h 0.000001)
(def n (/ (abs (- b a)) h))
((fn [i sum]
(if (not (< i n))
(* h (+ (/ (+ (f a) (f b)) 2) sum))
(recur (+ i 1) (+ sum (area (f (+ (* i h) a)))))))
0 0))
(I did the something similar with integral.) All in all, I wasn't able to quite hit the second figure, but this should get you on the right track:
101.33517384995224
41119.11576557253

Returning a value from a loop

Is there anyway i can return a value from a loop since the recursion has to be at the tail
(ns for)
(defn abc [y]
(loop [x 10]
(when (> x 2)
(if (= 2 3) (do (println "test") (recur (- x 2)))
(do (let [x (+ 1 x)
y 2] (println y) (recur (- x 2))))))))
(abc 1)
is there anyway i can return a value for the function by taking y as a parameter and updating a new value of y. However, the recur part has to be at the last line of the code hence i am unable to put y as the last line of the code.
Example
(ns for)
(defn abc [y]
(loop [x 10]
(when (> x 2)
(if (= 2 3) (do (println "test") (recur (- x 2)))
(do (let [x (+ 1 x)
y 2] (println y) (recur (- x 2)))))))
y)
(abc 1)
This would give me an error since recur has to be the last line of code. I have looked at similar questions and it says to put the return value at the end of the if loop which i tried but failed which gives me an exception thatthe recursion can only happen at the tail
I guess you meant this:
(defn abc [y]
(loop [x 10
y nil]
(if (> x 2)
(if (= 2 3)
(do (println "test")
(recur (- x 2) nil))
(do (let [x (+ 1 x)
y 2]
(println y)
(recur (- x 2) y))))
y)))
Update. Without unnecessary parts it would be
(defn abc [y]
(loop [x 10]
(if (> x 2)
(do (println 2)
(recur (- x 1)))
2)))
which is the same as
(defn abc [_]
(dotimes [_ 8] (println 2))
2)