Summing all the multiples of three recursively in Clojure - recursion

Hi I am a bit new to Clojure/Lisp programming but I have used recursion before in C like languages, I have written the following code to sum all numbers that can be divided by three between 1 to 100.
(defn is_div_by_3[number]
(if( = 0 (mod number 3))
true false)
)
(defn sum_of_mult3[step,sum]
(if (= step 100)
sum
)
(if (is_div_by_3 step)
(sum_of_mult3 (+ step 1 ) (+ sum step))
)
)
My thought was to end the recursion when step reaches sum, then I would have all the multiples I need in the sum variable that I return, but my REPL seems to returning nil for both variables what might be wrong here?

if is an expression not a statement. The result of the if is always one of the branches. In fact Clojure doesn't have statements has stated here:
Clojure programs are composed of expressions. Every form not handled specially by a special form or macro is considered by the compiler to be an expression, which is evaluated to yield a value. There are no declarations or statements, although sometimes expressions may be evaluated for their side-effects and their values ignored.
There is a nice online (and free) book for beginners: http://www.braveclojure.com
Other thing, the parentheses in Lisps are not equivalent to curly braces in the C-family languages. For example, I would write your is_div_by_3 function as:
(defn div-by-3? [number]
(zero? (mod number 3)))
I would also use a more idiomatic approach for the sum_of_mult3 function:
(defn sum-of-mult-3 [max]
(->> (range 1 (inc max))
(filter div-by-3?)
(apply +)))
I think that this code is much more expressive in its intention then the recursive version. The only trick thing is the ->> thread last macro. Take a look at this answer for an explanation of the thread last macro.

There are a few issues with this code.
1) Your first if in sum_of_mult3 is a noop. Nothing it returns can effect the execution of the function.
2) the second if in sum_of_mult3 has only one condition, a direct recursion if the step is a multiple of 3. For most numbers the first branch will not be taken. The second branch is simply an implicit nil. Which your function is guaranteed to return, regardless of input (even if the first arg provided is a multiple of three, the next recurred value will not be).
3) when possible use recur instead of a self call, self calls consume the stack, recur compiles into a simple loop which does not consume stack.
Finally, some style issues:
1) always put closing parens on the same line with the block they are closing. This makes Lisp style code much more readable, and if nothing else most of us also read Algol style code, and putting the parens in the right place reminds us which kind of language we are reading.
2) (if (= 0 (mod number 3)) true false) is the same as (= 0 (mod number 3) which in turn is identical to (zero? (mod number 3))
3) use (inc x) instead of (+ x 1)
4) for more than two potential actions, use case, cond, or condp
(defn sum-of-mult3
[step sum]
(cond (= step 100) sum
(zero? (mod step 3)) (recur (inc step) (+ sum step))
:else (recur (inc step) sum))

In addition to Rodrigo's answer, here's the first way I thought of solving the problem:
(defn sum-of-mult3 [n]
(->> n
range
(take-nth 3)
(apply +)))
This should be self-explanatory. Here's a more "mathematical" way without using sequences, taking into account that the sum of all numbers up to N inclusive is (N * (N + 1)) / 2.
(defn sum-of-mult3* [n]
(let [x (quot (dec n) 3)]
(* 3 x (inc x) 1/2)))
Like Rodrigo said, recursion is not the right tool for this task.

Related

Learning Clojure: recursion for Hidden Markov Model

I'm learning Clojure and started by copying the functionality of a Python program that would create genomic sequences by following an (extremely simple) Hidden Markov model.
In the beginning I stuck with my known way of serial programming and used the def keyword a lot, thus solving the problem with tons of side effects, kicking almost every concept of Clojure right in the butt. (although it worked as supposed)
Then I tried to convert it to a more functional way, using loop, recur, atom and so on. Now when I run I get an ArityException, but I can't read the error message in a way that shows me even which function throws it.
(defn create-model [name pA pC pG pT pSwitch]
; converts propabilities to cumulative prop's and returns a char
(with-meta
(fn []
(let [x (rand)]
(if (<= x pA)
\A
(if (<= x (+ pA pC))
\C
(if (<= x (+ pA pC pG))
\G
\T))))) ; the function object
{:p-switch pSwitch :name name})) ; the metadata, used to change model
(defn create-genome [n]
; adds random chars from a model to a string and switches models randomly
(let [models [(create-model "std" 0.25 0.25 0.25 0.25 0.02) ; standard model, equal props
(create-model "cpg" 0.1 0.4 0.4 0.1 0.04)] ; cpg model
islands (atom 0) ; island counter
m (atom 0)] ; model index
(loop [result (str)]
(let [model (nth models #m)]
(when (< (rand) (:p-switch (meta model))) ; random says "switch model!"
; (swap! m #(mod (inc #m) 2)) ; swap model used in next iteration
(swap! m #(mod (inc %) 2)) ; EDIT: correction
(if (= #m 1) ; on switch to model 1, increase island counter
; (swap! islands #(inc #islands)))) ; EDIT: my try, with error
(swap! islands inc)))) ; EDIT: correction
(if (< (count result) n) ; repeat until result reaches length n
(recur (format "%s%c" result (model)))
result)))))
Running it works, but calling (create-genome 1000) leads to
ArityException Wrong number of args (1) passed to: user/create-genome/fn--772 clojure.lang.AFn.throwArity (AFn.java:429)
My questions:
(obviously) what am I doing wrong?
how exactly do I have to understand the error message?
Information I'd be glad to receive
how can the code be improved (in a way a clojure-newb can understand)? Also different paradigms - I'm grateful for suggestions.
Why do I need to put pound-signs # before the forms I use in changing the atoms' states? I saw this in an example, the function wouldn't evaluate without it, but I don't understand :)
Since you asked for ways to improve, here's one approach I often find myself going to : Can I abstract this loop into a higher order pattern?
In this case, your loop is picking characters at random - this can be modelled as calling a fn of no arguments that returns a character - and then accumulating them together until it has enough of them. This fits very naturally into repeatedly, which takes functions like that and makes lazy sequences of their results to whatever length you want.
Then, because you have the entire sequence of characters all together, you can join them into a string a little more efficiently than repeated formats - clojure.string/join should fit nicely, or you could apply str over it.
Here's my attempt at such a code shape - I tried to also make it fairly data-driven and that may have resulted in it being a bit arcane, so bear with me:
(defn make-generator
"Takes a probability distribution, in the form of a map
from values to the desired likelihood of that value appearing in the output.
Normalizes the probabilities and returns a nullary producer fn with that distribution."
[p-distribution]
(let[sum-probs (reduce + (vals p-distribution))
normalized (reduce #(update-in %1 [%2] / sum-probs) p-distribution (keys p-distribution) )]
(fn [] (reduce
#(if (< %1 (val %2)) (reduced (key %2)) (- %1 (val %2)))
(rand)
normalized))))
(defn markov-chain
"Takes a series of states, returns a producer fn.
Each call, the process changes to the next state in the series with probability :p-switch,
and produces a value from the :producer of the current state."
[states]
(let[cur-state (atom (first states))
next-states (atom (cycle states))]
(fn []
(when (< (rand) (:p-switch #cur-state))
(reset! cur-state (first #next-states))
(swap! next-states rest))
((:producer #cur-state)))))
(def my-states [{:p-switch 0.02 :producer (make-generator {\A 1 \C 1 \G 1 \T 1}) :name "std"}
{:p-switch 0.04 :producer (make-generator {\A 1 \C 4 \G 4 \T 1}) :name "cpg"}])
(defn create-genome [n]
(->> my-states
markov-chain
(repeatedly n)
clojure.string/join))
To hopefully explain a little of the complexity:
The let in make-generator is just making sure the probabilities sum to 1.
make-generator makes heavy use of another higher-order looping pattern, namely reduce. This essentially takes a function of 2 values and threads a collection through it. (reduce + [4 5 2 9]) is like (((4 + 5) + 2) + 9). I chiefly use it to do a similar thing to your nested ifs in create-model, but without naming how many values are in the probability distribution.
markov-chain makes two atoms, cur-state to hold the current state and next-states, which holds an infinite sequence (from cycle) of the next states to switch to. This is to work like your m and models, but for arbitrary numbers of states.
I then use when to check if the random state switch should occur, and if it does perform the two side effects I need to keep the state atoms up to date. Then I just call the :producer of #cur-state with no arguments and return that.
Now obviously, you don't have to do this exactly this way, but looking for those patterns certainly does tend to help me.
If you want to go even more functional, you could also consider moving to a design where your generators take a state (with seeded random number generator) and return a value plus a new state. This "state monad" approach would make it possible to be fully declarative, which this design isn't.
Ok, it's a long shot, but it looks like your atom-updating functions:
#(mod (inc #m) 2)
and
#(inc #islands)
are of 0-arity, and they should be of arity at least 1.
This leads to the answer to your last question: the #(body) form is a shortcut for (fn [...] (body)). So it creates an anonymous function.
Now the trick is that if body contains % or %x where x is a number, the position where it appears will be substituted for the referece to the created function's argument number x (or the first argument if it's only %).
In your case that body doesn't contain references to the function arguments, so #() creates an anonymous function that takes no arguments, which is not what swap! expects.
So swap tries to pass an argument to something that doesn't expect it and boom!, you get an ArityException.
What you really needed in those cases was:
(swap! m #(mod (inc %) 2)) ; will swap value of m to (mod (inc current-value-of-m) 2) internally
and
(swap! islands inc) ; will swap value of islands to (inc current-value-of-islands) internally
respectively
Your mistake has to do with what you asked about the hashtag macro #.
#(+ %1 %2) is shorthand for (fn [x y] (+ x y)). It can be without arguments too: #(+ 1 1). That's how you are using it. The error you are getting is because swap! needs a function that accepts a parameter. What it does is pass the atom's current value to your function. If you don't care about its state, use reset!: (reset! an-atom (+ 1 1)). That will fix your error.
Correction:
I just took a second look at your code and realised that you are actually using working on the atoms' states. So what you want to do is this:
(swap! m #(mod (inc %) 2)) instead of (swap! m #(mod (inc #m) 2)).
As far as style goes, you are doing good. I write my functions differently every day of the week, so maybe I'm not one to give advice on that.

Build lazy-seq by multiplying previous term by constant

I'm starting out with Clojure and, despite having an understanding of recursion, am having trouble thinking of the "right" way to build a lazy-seq for the following function:
I want to build a list of all the frequencies starting from middle C. My first element would be 120 (the frequency of middle C). To get the second element, I'd multiply the first element, 120, by 1.059463 to get 127.13556. To the get the third I'd multiply the second element, 127.13556, by 1.059463, etc etc...
What's the best way to do this in Clojure?
You can use the iterate function for that.
(iterate #(* % 1.059463) 120)
If you are planning to expand this into something more complicated, then you would create a function that recursive calls itself inside a call to lazy-seq. (This is what iterate does internally.)
(defn increasing-frequencies
([] (increasing-frequencies 120))
([freq]
(cons freq (lazy-seq (increasing-frequencies (* freq 1.059463))))))
(nth (increasing-frequencies) 2) ;; => 134.69542180428002
If you start to use this in a tight loop, you may also want to generate a chunked lazy seq. This will pre-calculate the next few elements, instead of one by one.
(defn chunked-increasing-frequencies
([] (chunked-increasing-frequencies 120))
([freq]
(lazy-seq
(let [b (chunk-buffer 32)]
(loop [i freq c 0]
(if (< c 32)
(do
(chunk-append b i)
(recur (* i 1.059463) (inc c)))
(chunk-cons (chunk b) (chunked-increasing-frequencies i))))))))
Note: I would advise against doing this until you have measured a performance problem related to calculating individual elements.
(defn get-frequencies []
(iterate #(* 1.059463 %) 120))
See iterate
Or, if you want to use lazy-seq explicitly, you can do this:
(defn get-frequencies-hard []
(cons
120
(lazy-seq
(map #(* 1.059463 %) (get-frequencies-hard)))))
Which will cons 120 to a lazy seq of every value applied to the map function.

Converting a list of digits to a number

I was wondering if there was a way to take a list of numbers (digits), and truncate the numbers together to be one large number (not addition) in Scheme. For example, I would want
(foo '(1 2 3 4))
;=> 1234
Does Scheme have a built in function to do this?
There are a number of languages that are in the Scheme family, and there are a few versions of Scheme, too. If you're using one, e.g., Racket, that includes a left associative fold (often called foldl, fold, or reduce, though there are other variations, too), this is pretty straightfoward to implement in terms of the fold. Folds have been described in more detail in these questions and answers:
Finding maximum distance between two points in a list (scheme) This question includes a description of how fold can be viewed as an iterative construct (and in Scheme, which mandates tail call optimization, is compiled to iterative code), and also includes an implementation of foldl for Schemes that don't have it.
Flattening a List of Lists This question is about a somewhat unusual fold, and how it (or a standard fold) can be used to flatten a list.
scheme structures and lists This question has an example of how you might adjust the function that you pass to a fold to achieve slightly different behavior. (I also include an opinionated (but true ;), I assure you) comment about how Common Lisp's reduce provides a somewhat more convenient interface than what's provided in some of the Scheme libraries.
Here's what the code looks like in terms of foldl:
(define (list->num digits)
(foldl (lambda (digit n)
(+ (* 10 n) digit))
0
digits))
> (list->num '(1 2 3 4))
1234
If your language doesn't have it, foldl is pretty easy to write (e.g., my answer to the one of the questions above includes an implementation) and use the preceding code, or you can write the whole function (using the same approach) yourself:
(define (list->num-helper digits number-so-far)
(if (null? digits)
number-so-far
(list->num-helper (cdr digits)
(+ (* 10 number-so-far)
(car digits)))))
(define (list->num digits)
(list->num-helper digits 0))
You can make that a bit more concise by using a named let:
(define (list->num digits)
(let l->n ((digits digits)
(number 0))
(if (null? digits)
number
(l->n (cdr digits)
(+ (* 10 number)
(car digits))))))

Count amount of odd numbers in a sentence

I am fairly new to lisp and this is one of the practice problems.
First of all, this problem is from simply scheme. I am not sure how to answer this.
The purpose of this question is to write the function, count-odd that takes a sentence as its input and count how many odd digits are contained in it as shown below:
(count-odd'(234 556 4 10 97))
6
or
(count-odd '(24680 42 88))
0
If possible, how would you be able to do it, using higher order functions, or recursion or both - whatever gets the job done.
I'll give you a few pointers, not a full solution:
First of all, I see 2 distinct ways of doing this, recursion or higher order functions + recursion. For this case, I think straight recursion is easier to grok.
So we'll want a function which takes in a list and does stuff, so
(define count-odd
(lambda (ls) SOMETHING))
So this is recursive, so we'd want to split the list
(define count-odd
(lambda (ls)
(let ((head (car ls)) (rest (cdr ls)))
SOMETHING)))
Now this has a problem, it's an error for an empty list (eg (count-odd '())), but I'll let you figure out how to fix that. Hint, check out scheme's case expression, it makes it easy to check and deal with an empty list
Now something is our recursion so for something something like:
(+ (if (is-odd head) 1 0) (Figure out how many odds are in rest))
That should give you something to start on. If you have any specific questions later, feel free to post more questions.
Please take first into consideration the other answer guide so that you try to do it by yourself. The following is a different way of solving it. Here is a tested full solution:
(define (count-odd num_list)
(if (null? num_list)
0
(+ (num_odds (car num_list)) (count-odd (cdr num_list)))))
(define (num_odds number)
(if (zero? number)
0
(+ (if (odd? number) 1 0) (num_odds (quotient number 10)))))
Both procedures are recursive.
count-odd keeps getting the first element of a list and passing it to num_odds until there is no element left in the list (that is the base case, a null list).
num_odds gets the amount of odd digits of a number. To do so, always asks if the number is odd in which case it will add 1, otherwise 0. Then the number is divided by 10 to remove the least significant digit (which determines if the number is odd or even) and is passed as argument to a new call. The process repeats until the number is zero (base case).
Try to solve the problem by hand using only recursion before jumping to a higher-order solution; for that, I'd suggest to take a look at the other answers. After you have done that, aim for a practical solution using the tools at your disposal - I would divide the problem in two parts.
First, how to split a positive integer in a list of its digits; this is a recursive procedure over the input number. There are several ways to do this - by first converting the number to a string, or by using arithmetic operations to extract the digits, to name a few. I'll use the later, with a tail-recursive implementation:
(define (split-digits n)
(let loop ((n n)
(acc '()))
(if (< n 10)
(cons n acc)
(loop (quotient n 10)
(cons (remainder n 10) acc)))))
With this, we can solve the problem in terms of higher-order functions, the structure of the solution mirrors the mental process used to solve the problem by hand:
First, we iterate over all the numbers in the input list (using map)
Split each number in the digits that compose it (using split-digits)
Count how many of those digits are odd, this gives a partial solution for just one number (using count)
Add all the partial solutions in the list returned by map (using apply)
This is how it looks:
(define (count-odd lst)
(apply +
(map (lambda (x)
(count odd? (split-digits x)))
lst)))
Don't be confused if some of the other solutions look strange. Simply Scheme uses non-standard definitions for first and butfirst. Here is a solution, that I hope follows Simply Scheme friendly.
Here is one strategy to solve the problem:
turn the number into a list of digits
transform into a list of zero and ones (zero=even, one=odd)
add the numbers in the list
Example: 123 -> '(1 2 3) -> '(1 0 1) -> 2
(define (digit? x)
(<= 0 x 9))
(define (number->digits x)
(if (digit? x)
(list x)
(cons (remainder x 10)
(number->digits (quotient x 10)))))
(define (digit->zero/one d)
(if (even? d) 0 1))
(define (digits->zero/ones ds)
(map digit->zero/one ds))
(define (add-numbers xs)
(if (null? xs)
0
(+ (first xs)
(add-numbers (butfirst xs)))))
(define (count-odds x)
(add-numbers
(digits->zero/ones
(number->digits x))))
The above is untested, so you might need to fix a few typos.
I think this is a good way, too.
(define (count-odd sequence)
(length (filter odd? sequence)))
(define (odd? num)
(= (remainder num 2) 1))
(count-odd '(234 556 4 10 97))
Hope this will help~
The (length sequence) will return the sequence's length,
(filter proc sequence) will return a sequence that contains all the elements satisfy the proc.
And you can define a function called (odd? num)

What to return in a collection when using map

I read a lot of documentation about Clojure (and shall need to read it again) and read several Clojure questions here on SO to get a "feel" of the language. Besides a few tiny functions in elisp I've never written in any Lisp language before. I wrote my first project Euler solution in Clojure and before going further I'd like to better understand something about map and reduce.
Using a lambda, I ended up with the following (to sum all multiple of either 3 or 5 or both between 1 and 1000 inclusive):
(reduce + (map #(if (or (= 0 (mod %1 3)) (= 0 (mod %1 5))) %1 0) (range 1 1000)))
I put it on one line because I wrote it on the REPL (and it gives the correct solution).
Without the lambda, I wrote this:
(defn val [x] (if (or (= 0 (mod x 3)) (= 0 (mod x 5))) x 0))
And then I compute the solution doing this:
(reduce + (map val (range 1 1000)))
In both cases, my question concerns what the map should return, before doing the reduce. After doing the map I noticed I ended up with a list looking like this: (0 0 3 0 5 6 ...).
I tried removing the '0' at the end of the val definition but then I received a list made of (nil nil 3 nil 5 6 etc.). I don't know if the nil are an issue or not. I figured out that I was going to sum while doing a fold-left anyway so that the zero weren't really an issue.
But still: what's a sensible map to return? (0 0 3 0 5 6 ...) or (nil nil 3 nil 5 6...) or (3 5 6 ...) (how would I go about this last one?) or something else?
Should I "filter out" the zeroes / nils and if so how?
I know I'm asking a basic question but map/reduce is obviously something I'll be using a lot so any help is welcome.
It sounds like you already have an intuative undestanding of the need to seperate mapping concerns form the reducing It's perfectly natural to have data produced by map that is not used by the reduce. infact using the fact that zero is the identity value for addition make this even more elegant.
mappings job is to produce the new data (in this case 3 5 or "ignore")
reduces job is to decide what to include and to produce the final result.
what you started with is idiomatic clojure and there is no need to complicate it any more,
so this next example is just to illustrate the point of having map decide what to include:
(reduce #(if-not (zero? %1) (+ %1 %2) %2) (map val (range 10)))
in this contrived example the reduce function ignores the zeros. In typical real world code if the idea was as simple as filtering out some value then people tend to just use the filter function
(reduce + (filter #(not (zero? %)) (map val (range 10))))
you can also just start with filter and skip the map:
(reduce + (filter #(or (zero? (rem % 3)) (zero? (rem % 5))) (range 10)))
The watchword is clarity.
Use filter, not map. Then you don't have to choose a null
value that you later have to decide not to act on.
Naming the filtering/mapping function can help. Do so with let
or letfn, not defn, unless you have use for the function elsewhere.
Acting on this advice brings us to ...
(let [divides-by-3-or-5? (fn [n] (or (zero? (mod n 3)) (zero? (mod n 5))))]
(reduce + (filter divides-by-3-or-5? (range 1 1000))))
You may want to stop here for now.
This reads well, but the divides-by-3-or-5? function sticks in the throat. Change the factors and we need a completely new function. And that repeated phrase (zero? (mod n ...)) jars. So ...
We want a function, that - given a list (or other collection) of possible factors - tells us whether any of them apply to a given number. In other words, we want
a function of a collection of numbers - the possible factors - ...
that returns a function of one number - the candidate - ...
that tells us whether the candidate is divisible by any of the possible factors.
One such function is
(fn [ns] (fn [n] (some (fn [x] (zero? (mod n x))) ns)))
... which we can employ thus
(let [divides-by-any? (fn [ns] (fn [n] (some (fn [x] (zero? (mod n x))) ns)))]
(reduce + (filter (divides-by-any? [3 5]) (range 1 1000))))
Notes
This "improvement" has made the program a little slower.
divides-by-any? might prove useful enough to be promoted to a
defn.
If the operation were critical, you could consider stripping out
redundant factors. For example [2 3 6] could be reduced to [6].
If the operation were really critical, and the factors were supplied
as constants, you could consider creating the filter function with a
macro that went back to using or.
This is a bit of a shaggy-dog story, but it recounts the thoughts prompted by the problem you refer to.
In your case I would use keep instead of map. It is similar to map except that it keeps only the non-nil values.

Resources