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)
Related
some of you may find this question a little odd, but i really want to know if this program is recursive or not, and that is all I want to know.
(defun howmany(sez)
(if (null sez)
0
(+ 1 (howmany (cdr sez)))))
(defun sum(sez)
(if (null sez)
0
(+ (car sez) (sum(cdr sez)))))
(defun avg(sez)
(if (null sez)
0
(/ (sum sez) (howmany sez))))
(print (avg '(100 200 300)))
Thank for all your answers!
First, take a look at your code and format it a little bit more, in order to be easily read by a lisper
(defun howmany (sez)
(if (null sez)
0
(+ 1 (howmany (cdr sez)))))
(defun sum (sez)
(if (null sez)
0
(+ (car sez) (sum (cdr sez)))))
(defun avg (sez)
(if (null sez)
0
(/ (sum sez) (howmany sez))))
(print (avg '(100 200 300)))
Then analize this script, it contains three functions an a last s-expression which evaluate the functions.
For this three functions, avg, sum and howmany,
There is a story titled Martin and the Dragon, you can find in chapter 8 from here Common Lisp: A Gentle Introduction to Symbolic Computation and you should read, which sumarizes in:
The dragon, beneath its feigned distaste for Martin's questions,
actually enjoyed teaching him about recursion. One day it decided to
formally explain what recursion means. The dragon told Martin to
approach every recursive problem as if it were a journey. If he
followed three rules for solving problems recursively, he would always
complete the journey successfully.
The dragon explained the rules this way:
Know when to stop.
Decide how to take one step.
Break the journey down into that step plus a smaller journey.
Let's see the functions howmany and sum
Know when to stop
it stops when sez is null, i.e. when the list is nil
Decide how to take one step
the if have two ways or 0 for both or
(+ 1 (howmany (cdr sez)))
(+ (car sez) (sum (cdr sez)))
Break the joourney down into that step plus a smaller journey
in the last expressions, the list is smaller take out the first and then continue, with the smaller list
So, this two functions are recursive, the other avg, is not recursive, only take cares of the empty list, in order to prevent dividing by zero or zero/zero indetermination.
Hope this helps
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.
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.
I'm a real scheme newbie and i'm trying to work out how to return all the sub-lists given with a list argument (i.e. (1 2 (3 4 5) (6 7 8) 9) should return the two lists (3 4 5) and (6 7 8)).
I know I should be using a recursive function with the rest of the list but I'm having trouble producing the results I want. Here is what I've written: -
(define (find-sublists list)
(cond
((null? list) #t))
(not
(list? (first list)))
(print (first list))
(find-sublists (rest list)))
I'm trying to search through the list and output anything which is a list and then search again, otherwise just recursively search the rest of the list. However I'm not sure how to jump straight to the last line when the condition is met.
Does anybody have any advice for me?
First, I'm assuming that this is a homework assignment; please correct me if I'm wrong.
Next: It looks to me like you have one vital misunderstanding of the problem: it asks you to return the two lists, not to print them.
Next, I'm going to steer you to the How To Design Programs design recipe. Your first step is to write down the data definition that you're working with--I'm not quite sure what it is here, but it might be something like this:
;; a list-of-maybe-lists is either
;; - empty, or
;; - (cons maybe-list list-of-maybe-lists)
;; a maybe-list is either
;; - a list, or
;; - something else
Your next step is to write down a contract and a purpose statement for your program, and then some test cases.
Boilerplate: please forgive me for giving you lots of little steps rather than the answer; the point of all these steps is to enable you to fish for yourself, rather than just waiting for other people to fish for you.
If you just want to filter out all the lists in a given list, use filter:
(filter list? '(1 2 (3 4 5) (6 7 8) 9))
or you implement it yourself:
(define (my-filter func lst)
(cond ((null? lst) '())
((func (car lst))
(cons (car lst) (my-filter func (cdr lst))))
(else
(my-filter func (cdr lst)))))
i need to write a function which calculates how many elements on list with scheme language.
for example
(howMany 'a) returns 0
(howMany '(a b)) returns 1
(howMany '(a (b c))) returns 2
how can i do that? i did not want a working code, just only an idea for do that. so maybe you should consider to remove working codes. :) thank you
The fold answers will work. However, if this is homework, you may be trying to do this using only simple built-in functions. There are two possible answers.
Here's the naive way:
(define (howMany list)
(if (null? list)
0
(+ 1 (howMany (cdr list)))
)
)
(Your implementation of Scheme may have a function empty? instead of null?.)
However, this algorithm will take an amount of space linearly proportional to the number of elements in the list, because it will store (+ 1 ...) for each element of the list before doing any of the additions. Intuitively, you shouldn't need this. Here's a better algorithm that avoids that issue:
(define (howMany list)
(define (iter numSoFar restOfList)
(if (null? restOfList)
numSoFar
(iter (+ numSoFar 1) (cdr restOfList))
)
)
(iter 0 list)
)
(Bonus points: use Scheme's (let iter ...) syntax to write this more succinctly. I used this style because it's more clear if you only know a few Scheme primitives.)
This will most likely get down-voted for this phrase, but, I don't know scheme. I am, however, familiar with functional programming.
If there is no built-in for this, start by 'folding' the list with start value of 0 and add 1 on every additional fold.
It is simply counting the number of elements in the list.
(define howMany
(lambda (list)
(cond
[(not (list? list)) 0]
[(null? list) 0]
[else (+ 1 (howMany (cdr list)))])))