my Modulo Inverse in clojure Seems to give wrong answer - clojure

Hi I am programming in clojure and though the problem of modulo inverse has nothing to do with language i am stuck at this code -
(defn EulerDiv [x p]
(let [ToMod (+ p 2)]
(loop [num 1 toPow (int p) numDouble x]
(if (= 0 toPow)
num
(let [numDouble2 (rem (* numDouble numDouble) ToMod)
halfToPow (int (/ toPow 2))]
(if (odd? toPow)
(recur (rem (* num numDouble) ToMod)
halfToPow
numDouble2)
(recur num halfToPow numDouble2))
))))
)
It seems to give me right answers for small Primes but when i am using it in a problem with Bigger primes i am getting answers other than result like :
(= 2 (mod (* 4 (EulerDiv 2 (- 3 2))) 3))
This prints true
(def ToMod (+ 10e8 7))
( = 1 (int (mod (* 2 (EulerDiv 2 (- ToMod 2))) ToMod)) )
This prints false.
Also there is rem and mod in clojure.
mod makes the output positive and hence i can not use it in between the calculations.
It is a programming contest but this is just part of solution and this info of modulo inverse was also provided in the problem page.
The problem is that of programming calculator grammar for evaluating evpressions like 4/-2/(2 + 8)

You are straying from integer arithmetic.
Given integers, the / function can produce rationals: (/ 1 2) is 1/2, not 0.
And 1e9 is 1.0E9, a double, not an integer.
There are appropriate substitutes available. Look at the arithmetic section here for an integer division function, and at the cast section for something to convert a number to an integer.
All the best!

Related

Decimal to Binary Clojure

I'm following this pseudo code to convert decimal to binary recursively.
findBinary(decimal)
if (decimal == 0)
binary = 0
else
binary = decimal % 2 + 10 * (findBinary(decimal / 2)
This is what I have tried:
(defn binary [n]
(loop [res 0]
(if (= n 0)
res
(recur (res (* (+ (mod n 2) 10) (binary (quot n 2)))) )
)
)
)
But I get this error :
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/binary (form-init9002795692676588773.clj:6)
Any ideas how to fix the code to complete the task?
I realize, that this is about the journey and not the result. But to
have it mentioned: Long/toString can give you a string from a number with a wide
variety of radixes.
(Long/toString 123 2)
; → "1111011"
Here's a slightly different approach which allows recur to be used:
(defn find-binary [d]
(loop [ decimal d
digits '() ]
(if (= decimal 0)
(Integer. (clojure.string/join (map str digits)))
(recur (quot decimal 2) (conj digits (mod decimal 2))))))
In the loop we build up a collection of binary digits, adding each new digit at the beginning of the list so that we end up with the digits in the desired order left-to-right in the list. When the terminating condition is reached we convert the collection-of-digits to a collection-of-strings, join the collection of strings together into single string, and convert the string back to an integer.
Your psuedo code can be expressed pretty directly in clojure:
(defn find-binary [decimal]
(if (= decimal 0)
0
(+ (mod decimal 2) (* 10 (find-binary (quot decimal 2))))))
Examples:
user=> (find-binary 1)
1
user=> (find-binary 2)
10
user=> (find-binary 25)
11001
user=> (find-binary 255)
11111111
The error in your version is here:
(recur (res (* (+ (mod n 2) 10) (binary (quot n 2))))
Specifically, the complaint is that you are trying to use res (which has the value 0) as a function.
To be honest, I'm not sure how to do this with loop-recur. When I try it complains about recur not being from the tail position. Perhaps another answer can enlighten us!
Using recur:
;; returns a binary number string of the given decimal number
(defn find-binary [decimal]
(loop [n decimal
res ""]
(if (= n 0)
res
(recur (quot n 2)
(str (mod n 2) res)))))
But without loop:
(defn find-binary [decimal & {:keys [acc] :or {acc ""}}]
(if (= decimal 0)
acc
(find-binary (quot decimal 2) :acc (str (mod decimal 2) acc))))
The original attempt was the following, but it can't go far in the size of decimal:
(defn find-binary [decimal]
(loop [n decimal ;; number to be binarized
res '() ;; collector list
pos 0] ;; position of binary number
(if (= n 0)
(reduce #'+ res) ;; sum up collector list
(recur (quot n 2)
(cons (* (int (Math/pow 10 pos))
(mod n 2))
res)
(+ 1 pos)))))
For large numbers use:

Unobtrusive Way to Trim Cycle in Clojure Sequence

I am trying to write a lazy seq to generate the Collatz sequence for a given input int.
I love this function because is so cleanly maps to the mathematical definition:
(defn collatz
"Returns a lazy seq of the Collatz sequence starting at n and ending at 1 (if
ever)."
[n]
(letfn [(next-term [x]
(if (even? x)
(/ x 2)
(inc (* 3 x))))]
(iterate next-term n)))
The problem is that this produces infinite seqs because of how the Collatz sequence behaves:
(take 10 (collatz 5))
=> (5 16 8 4 2 1 4 2 1 4)
I could easily drop the cycle by adding (take-while #(not= 1 %) ...), but the 1 is part of the sequence. All the other ways I've thought to trim the cycle after the one are ugly and obfuscate the mathematical heart of the Collatz sequence.
(I've considered storing the seen values in an atom and using that in a take-while predicate, or just storing a flag in an atom to similar effect. But I feel like there is some better, more beautiful, less intrusive way to do what I want here.)
So my question: What are clean ways to detect and trim cycles in infinite seqs? Or, could I generate my lazy seq in a way (perhaps using for) that automatically trims when it reaches 1 (inclusive)?
The below looks like a more or less literal translation of the definition and gives the result you want:
(defn collatz-iter [x]
(cond (= x 1) nil
(even? x) (/ x 2)
:else (inc (* 3 x))))
(defn collatz [n]
(take-while some? (iterate collatz-iter n)))
(collatz 12) ;; => (12 6 3 10 5 16 8 4 2 1)
Basically, you can use nil as the value to stop the sequence, thus keeping the final 1.
you could also use another approach, which is recursive lazy-seq generation. That is quite common for this class of tasks, doesn't break the lazy sequence abstraction and avoids intermediate sequences' creation:
(defn collatz [n]
(if (== n 1)
(list 1)
(lazy-seq (cons n (collatz (if (even? n)
(/ n 2)
(inc (* 3 n))))))))
user> (collatz 12)
;;=> (12 6 3 10 5 16 8 4 2 1)

Promotion to BigDecimal doesn't happen

I'm using Clojure 1.5.1. Here is my program:
(def bricks4
(memoize (fn [n]
(cond (> 0 n) 0
(= 0 n) 1
(= 1 n) 1
:else (+ (bricks4 (- n 1))
(bricks4 (- n 2))
(bricks4 (- n 3))
(bricks4 (- n 4)))))))
(bricks4 70) throws exception:
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
I'm confused, because I thought Clojure will automatically promote numbers from Integer to Long and then to BigDemical.
What should I do to fix this program?
Clojure hasn't auto-promoted to bigint since 1.2, which is like...three years ago? These days the default is for better performance, but you can get the auto-promoting behavior by using +' instead of +, *' instead of *, and so on.

Solving Project Euler 1

I am trying to solve Project Euler problem in Clojure using recursion. The following is the problem statement:
If we list all the natural numbers below 10 that are multiples of 3 or
5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
However, the code below seems to give the wrong answer. What am I doing wrong?
(defn m?
[x]
(or (= (rem x 3)) (= (rem x 5))))
(defn sum-m
[limit sum]
(if (= limit 0)
sum
(recur (dec limit)
(if (m? limit)
(+ sum limit)
sum))))
(sum-m (dec 1000) 0)
You didn't say what erroneous answer it was giving, but I believe the problem is in m?:
(or (= 0 (rem x 3)) (= 0 (rem x 5)))
m? change to
(defn m? [x]
(or (zero? (rem x 3))(zero? (rem x 5))))
I think you wanted the function m? to check if a number is multiple of 3 or 5. But it does not do that. You should check if any of (rem x 3) or (rem x 5) are zero.
It's an interesting exercise to solve this for very large numbers. For example, find the sum of all the natural numbers below 1 billion that are multiples of 3 or 5. Your solution is linear in time, but you can try for a solution that is faster. This is not part of your original question; just an interesting addition to it.

Why isn't this running in constant space (and how do I make it so it does)?

I'm doing Project Euler to learn Clojure.
The purpose of this function is to calculate the lcm of the set of integers from 1 to m.
(lcm 10) returns 2520
This is a rather brute-force way of doing this. In theory, we go through each number from m to infinity and return the first number for which all values 1 through m divide that number evenly.
If I understand what 'lazy' means correctly (and if I am truly being lazy here), then this should run in constant space. There's no need to hold more than the list of numbers from 1 to m and 1 value from the infinite set of numbers that we're looping through.
I am, however, getting a java.lang.OutOfMemoryError: Java heap space at m values greater than 17.
(defn lcm [m]
(let [xs (range 1 (+ m 1))]
(first (for [x (iterate inc m) :when
(empty?
(filter (fn [y] (not (factor-of? y x))) xs))] x))))
Thanks!
As far as I can tell, your code is in fact lazy (also in the sense that it's in no hurry to reach the answer... ;-) -- see below), however it generates piles upon piles upon piles of garbage. Just consider that (lvm 17) amounts to asking for over 1.2 million lazy filtering operations on (range 1 18). I can't reproduce your out-of-memory problem, but I'd tentatively conjecture it might be an issue with your memory & GC settings.
Now although I realise that your question is not actually about algorithms, note that the production of all that garbage, the carrying out of all those filtering operations etc. not only utterly destroy the space complexity of this, but the time complexity as well. Why not use an actual LCM algorithm? Like the one exploiting lcm(X) = gcd(X) / product(X) for X a set of natural numbers. The GCD can be calculated with Euclid's algorithm.
(defn gcd
([x y]
(cond (zero? x) y
(< y x) (recur y x)
:else (recur x (rem y x))))
([x y & zs]
(reduce gcd (gcd x y) zs)))
(defn lcm
([x y] (/ (* x y) (gcd x y)))
([x y & zs]
(reduce lcm (lcm x y) zs)))
With the above in place, (apply lcm (range 1 18)) will give you your answer in short order.
I'm getting the same OutOfMemoryError on Clojure 1.1, but not on 1.2.
I imagine it's a bug in 1.1 where for holds on to more garbage than necessary.
So I suppose the fix is to upgrade Clojure. Or to use Michal's algorithm for an answer in a fraction of the time.
While I accept that this is acknowledged to be brute force, I shiver at the idea. For the set of consecutive numbers that runs up to 50, the lcm is 3099044504245996706400. Do you really want a loop that tests every number up to that point to identify the lcm of the set?
Other schemes would seem far better. For example, factor each member of the sequence, then simply count the maximum number of occurrences of each prime factor. Or, build a simple prime sieve, that simultaneously factors the set of numbers, while allowing you to count factor multiplicities.
These schemes can be written to be highly efficient. Or you can use brute force. The latter seems silly here.
Michal is correct about the problem. A sieve will be a little bit faster, since no gcd calculations are needed:
EDIT: This code is actually horribly wrong. I've left it here to remind myself to check my work twice if I have such a hangover.
(ns euler (:use clojure.contrib.math))
(defn sieve
([m] (sieve m (vec (repeat (+ 1 m) true)) 2))
([m sieve-vector factor]
(if (< factor m)
(if (sieve-vector factor)
(recur m
(reduce #(assoc %1 %2 false)
sieve-vector
(range (* 2 factor) (+ 1 m) factor))
(inc factor))
(recur m sieve-vector (inc factor)))
sieve-vector)))
(defn primes [m] (map key (filter val (seq (zipmap (range 2 m) (subvec (sieve m) 2))))))
(defn prime-Powers-LCM [m] (zipmap (primes m) (map #(quot m %) (primes m))))
(defn LCM [m] (reduce #(* %1 (expt (key %2) (val %2))) 1 (seq (prime-Powers-LCM m))))