简体   繁体   中英

How would I write a function in Racket which produces true if all the numbers in a list are the same and false otherwise?

How would I define a function in Dr. Racket which produces boolean true if all the numbers in a list are the same and false otherwise. This is my code so far:

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) (first lst)]
    [else (equal? (first lst)(same-numbers? (rest lst)))]))

If I type in:

(same-numbers? (cons 5 (cons 5 (cons 5 empty))))

My desired output is true. However, instead, I get a false. How would I correct this?

As the comments point out, assuming the list contains only numbers the simplest approach is to do (apply = lst) . If you want to implement this from scratch with explicit recursion, I suggest a different approach: if the list has more than one element, take the first element as reference and compare all the others against it, like this:

(define (same-numbers? lst)
  (if (or (empty? lst) (empty? (rest lst))) ; trivial cases
      #t
      (let loop ((val (first lst)) ; take first element as reference
                 (lst (rest lst))) ; loop over the other elements
        (or (empty? lst)           ; base case: we're finished
            (and (equal? (first lst) val)   ; base case: stop if elements are different
                 (loop val (rest lst))))))) ; recursive case: keep iterating

It works for my test cases:

(same-numbers? '())
=> #t
(same-numbers? '(5))
=> #t
(same-numbers? '(5 5))
=> #t
(same-numbers? '(5 5 5))
=> #t

(same-numbers? '(5 1))
=> #f
(same-numbers? '(1 5))
=> #f
(same-numbers? '(1 5 5))
=> #f
(same-numbers? '(5 5 1))
=> #f

I'll start with your code so far, and find the problems with it:

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) (first lst)]
    [else (equal? (first lst)(same-numbers? (rest lst)))]))

The first problem I see is with the base case: if lst is a list of numbers then (first lst) will be a number, not a boolean like you wanted.

;; same-numbers? : [Listof Number] -> Boolean

To fix this, the base case should return #true :

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) #true]
    [else (equal? (first lst) (same-numbers? (rest lst)))]))

The next problem I see is with the recursive case: since same-numbers? returns a boolean, you shouldn't use equal? as if you're expecting a number. Instead use equal? between the first and the second :

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) #true]
    [else ... (equal? (first lst) (second lst)) ... (same-numbers? (rest lst)) ...]))

Now the ... s around that need to be filled with stuff that combines the information in "first two equal" and "rest same-numbers". They're all equal when the first two are equal AND the rest are the same, so fill in the ... s with and to combine them:

(define (same-numbers? lst)
  (cond
    [(empty? (rest lst)) #true]
    [else (and (equal? (first lst) (second lst)) (same-numbers? (rest lst)))]))

If I type in:

> (same-numbers? (cons 5 (cons 5 (cons 5 empty))))
#true

There's still one problem left: the empty list. So just add another cond case for it:

;; same-numbers? : [Listof Number] -> Boolean
(define (same-numbers? lst)
  (cond
    [(empty? lst)        #true]
    [(empty? (rest lst)) #true]
    [else (and (equal? (first lst) (second lst)) (same-numbers? (rest lst)))]))

Using it:

> (same-numbers? empty)
#true
> (same-numbers? (cons 5 empty))
#true
> (same-numbers? (cons 5 (cons 5 (cons 5 empty))))
#true
> (same-numbers? (cons 5 (cons 5 (cons 6 empty))))
#false

Just like Atharva Shukla's comment (apply = lst) is good.

But (apply = '()) will show error.

#lang Racket
(define lon (list 1/2 1/2 1/2 1/3))
(define lon2 (list 1/2 1/2 1/2 0.5))

(define (same-n? lon)
  (andmap (lambda (n) (= (first lon) n)) lon))

;;; TEST

(same-n? lon) ; #f
(same-n? lon2) ; #t
(same-n? '()) ; #t

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM