Count the number of odd numbers in a sentence

I am new to lisp and this is one of the problems of practice.

First of all, this problem is just a scheme . I do not know how to answer this. The purpose of this question is to write a count-odd function that takes a sentence as its input and counts the number of odd digits in it , as shown below:

(count-odd '(234 556 4 10 97)) 6

or

(count-odd '(24680 42 88)) 0

If possible, how could you do this using functions of a higher order, or recursion, or both, regardless of what work is done.

+4
source share
5 answers

I will give you some pointers, not a complete solution:

First of all, I see two different ways to do this: recursion or higher order functions + recursion. For this case, I think direct recursion is easier to peek at.

So, we need a function that takes a list and does something like this, therefore

 (define count-odd (lambda (ls) SOMETHING)) 

So this is recursive, so we want to split the list

 (define count-odd (lambda (ls) (let ((head (car ls)) (rest (cdr ls))) SOMETHING))) 

Now this has a problem, it is an error for an empty list (e.g. (count-odd '()) ), but I will let you know how to fix it. Hint, check the expression of the schema schema, this makes it easy to check and process an empty list

Now something is our recursion, so for something like:

 (+ (if (is-odd head) 1 0) (Figure out how many odds are in rest)) 

This should give you something to start with. If you have any specific questions later, feel free to post more questions.

+4
source

Please consider another answer guide for you to try to do this yourself. Below is another way to solve it. Here is a proven complete 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 continues to receive the first element of the list and pass it to num_odds until there are no elements left in the list (this is the base case, a null list).

  • num_odds gets the number of odd digits of a number. To do this, the question is always asked if the number is odd , and in this case it will add 1, otherwise 0. Then the number will be divided by 10 to remove the least significant digit (which determines whether the number is odd or even ) and passed as an argument to new call. The process is repeated until the number is zero (base register).

+1
source

Try to solve the problem manually using only recursion before moving on to a higher order solution; for this I would suggest looking at other answers. After you have done this, try to find a practical solution using the tools you have - I would divide the problem into two parts.

First, how to break a positive integer in the list of its digits; This is a recursive procedure on the input number. There are several ways to do this - first convert the number to a string or use arithmetic to extract numbers, to name a few. I will use later, with a recursive implementation:

 (define (split-digits n) (let loop ((nn) (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 reflects the mental process used to solve the problem manually:

  • First, we iterate over all the numbers in the input list (using map )
  • Divide each number in the digits that make it up (using split-digits )
  • Count how many of these numbers are odd, this gives a partial solution for just one number (using count )
  • Add all partial solutions to the list returned by map (using apply )

Here's what it looks like:

 (define (count-odd lst) (apply + (map (lambda (x) (count odd? (split-digits x))) lst))) 
0
source

Do not confuse if some of the other solutions look weird. Simply Scheme uses custom definitions for first and butfirst . Here is a solution that I hope follows Simply Scheme.

Here is one strategy to solve the problem:

  • turn a number into a list of numbers
  • converts to a list of zeros and ones (zero = even, one = odd)
  • add numbers to 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 has not been verified, so you may need to correct several typos.

0
source

I think this is also a good way.

 (define (count-odd sequence) (length (filter odd? sequence))) (define (odd? num) (= (remainder num 2) 1)) (count-odd '(234 556 4 10 97)) 

Hope this helps ~

(sequence of length) will return the length of the sequence,
(filter processing sequence) will return a sequence containing all elements that satisfy the process.
And you can define a function called (odd? Num)

0
source

All Articles