Trying to make a function that checks sorting of a list - racket

I am trying to make a function that returns true or false if a list is in order. I can't figure out how to make it recursive. I keep getting error messages on the last line: define: expected only one expression for the function body, but found 1 extra part
(check-expect (is-sorted? (list)) true)
(check-expect (is-sorted? (list "A")) true)
(check-expect (is-sorted? (list "B" "A")) false)
(check-expect (is-sorted? (list "A" "B")) true)
(check-expect (is-sorted? (list "A" "C" "B")) false)
(check-expect (is-sorted? (list "A" "B" "C")) true)
(define (is-sorted? lst)
(cond
((empty-list? lst) true)
((= (length lst) 1) true) ;return true if there is only one element.
((string<? (first lst) second lst) true) ;If the first element is smaller than the second
;return true.
(else (is-sorted? (rest lst))))) ;do the above steps on the rest of the elements in the list.

Notice that you're not considering the case when the procedure should return false, and that you exit prematurely when you find that an element is sorted with respect to the next element (you need to keep iterating! it's just one match, what about the others?). The solution is simple, just negate the condition for this case and ask if it's not sorted return false. Like this:
(define empty-list? empty?)
(define (is-sorted? lst)
(cond
((empty-list? lst) true)
((empty-list? (rest lst)) true)
((string>=? (first lst) (second lst)) false)
(else (is-sorted? (rest lst)))))
It works with your test cases:
(is-sorted? (list)) ; true
(is-sorted? (list "A")) ; true
(is-sorted? (list "B" "A")) ; false
(is-sorted? (list "A" "B")) ; true
(is-sorted? (list "A" "C" "B")) ; false
(is-sorted? (list "A" "B" "C")) ; true

Related

Trying to create something similar to the "make-list" function in Racket

I am trying to code a function that will let me input a list, and it will produce a list of lists. Each list in the product will contain i+1 duplicates of the what was in index i of the original list.
So something like (expand (list "a" "b" "c")) will give me (list (list "a") (list "b" "b") (list "c" "c" "c")).
I am using Racket Beginning Student with List Abbreviations, and I am not allowed to use the "make-list" function.
Write helper function with new argument (i = number of duplicates) and use function make-list for repeating given element i times (or write your own version of make-list):
(define (my-make-list i elem)
(if (<= i 0) '()
(cons elem (my-make-list (- i 1) elem))))
(define (expand-help lst i)
(if (null? lst) '()
(cons (my-make-list i (car lst))
(expand-help (cdr lst) (+ i 1)))))
(define (expand lst)
(expand-help lst 1))
Example:
> (expand (list "a" "b" "c"))
(list (list "a") (list "b" "b") (list "c" "c" "c"))

Using Racket, create a function that returns a Boolean if all numbers are odd? or even?

I am stuck on this question. In fact, the code keeps running and doesn't end. Any suggestions?
(check-expect (all-elements? even? (list 1 2 3)) false)
(check-expect (all-elements? even? (list 2 4 6)) true)
(check-expect (all-elements? odd? (list 1 3 5)) true)
(define (all-elements? predicate lst)
(cond
[(empty? lst) false]
[(predicate (first lst)) true]
[else (all-elements? predicate lst)]
)
)
(define (all-elements? predicate lst)
(cond ((empty? lst) true)
((predicate (first lst)) (all-elements? predicate (cdr lst)))
(else false)))
Different approach:
;; make `and` as a function
(define (my-and a b) (and a b))
(define (all-elements? predicate args)
(foldr my-and #t (map predicate args)))
(all-elements? odd? '(1 3 5))
;; #t
or as a variadic function:
(define (all-elements? predicate . args)
(foldr my-and (map predicate args)))
then one can type:
(all-elements? odd? 1 3 5 7 9) ;; #t

Racket - Add or remove element from a 2dlist

I'm doing a problem which asks me to write a function that consumes a
list (dict1) and a list (act) that contains an action (remove or add) and a value. The updates should adhere to the following specifications:
• If the first element of act is “remove" and the key is in the dictionary, then the matching value in the associated list should be removed.
• If the matching value happens to be the last element in the associated list, then the key should remain in the dictionary, but the associated list becomes empty. If the value is not in the dictionary, the dictionary does not change.
• If the value of act is "add" and the key is in the dictionary, then the new value
should be added to the associated list in the dictionary if it does not already exist. If the value already exists in the associated list, the updated dictionary would not change.
• If the value of act is “add" and the key does not exist in the dictionary, then a
new association list entry for the key should be added to the dictionary.
For example:
(define dict1 (list (list "Num" (list 5 1.3 -1))
(list "Char" (list #\p))
(list "Str"
(list "cs" "CS" "Computer Science"))))
Then
(update dict1 (list "add" true)) =>
(list (list "Num" (list 5 1.3 -1))
(list "Bool" (list true))
(list "Char" (list #\p))
(list "Str" (list "cs" "CS" "Computer Science")))
(update dict1 (list "remove" "cs")) =>
(list (list "Num" (list 5 1.3 -1))
(list "Char" (list #\p))
(list "Str" (list "CS" "Computer Science")))
I could only come up with the first step, below is what I have so far:
(define (update dict1 act)
(cond
[(equal? (first act) "remove") (remove-value dict1 (second act))]
[(equal? (first act) "add") (add-value dict1 (second act))]))
For this question I'm only allowed to use member? or remove.
I knew that I've been asking a lot of questions in the past couple of days, but I am new to racket and I am doing my best to learn it :( Please help
no set! no local version
; please tell us which language you use (in front of code)
#|
In Beginning Student Language variabe can't be function
error: function call: expected a function after the open parenthesis, but found a variable
(define (f fn) (fn 1))
(f add1)
|#
; use "Advanced Student" language or "#lang racket".
#lang racket
(define dict1
(list (list "Num" (list 1 2 3))
(list "Char" (list #\p))
(list "Bool" '())
(list "Str" (list "a" "b" "c"))))
(define (index-title action)
(cond
[(number? (second action)) 0]
[(char? (second action)) 1]
[(boolean? (second action)) 2]
[(string? (second action)) 3]
[else (error "type error")]))
(define (my-remove word lst)
(cond
[(empty? lst) empty]
[(equal? word (first lst))
(rest lst)]
[else
(cons (first lst)
(my-remove word (rest lst)))]))
(define (exist? word lst)
(cond
[(empty? lst) #f]
[(equal? word (first lst)) #t]
[else
(exist? word (rest lst))]))
(define (add-if-not-exist word data)
(if (exist? word data)
data
(cons word data)))
(define (action-to-data word data action)
(cond
[(equal? action "add")
(add-if-not-exist word data)]
[(equal? action "remove")
(my-remove word data)]))
(define (aux-build-list i n dict act a-function)
(cond
[(= i n) empty]
[else
(cons (a-function i dict act)
(aux-build-list (+ i 1) n dict act a-function))]))
(define (my-build-list n dict act a-function)
(aux-build-list 0 n dict act a-function))
(define (build-new-sub-dict n dict act)
(cond
[(= n (index-title act))
(list (first (list-ref dict n))
(action-to-data (second act) (second (my-list-ref dict n)) (first act)))]
[else
(list-ref dict n)]))
(define (my-list-ref lst n)
(cond
[(< n 0) (error "error")]
[(= n 0) (first lst)]
[else
(my-list-ref (rest lst) (- n 1))]))
(define (update dict act)
(set! dict1
(my-build-list (length dict)
dict
act
(lambda (n dict act) (build-new-sub-dict n dict act)))))
;;; Test
(update dict1 '("add" 2))
(update dict1 '("remove" 3))
(update dict1 '("add" 4))
(update dict1 '("add" 4))
(update dict1 '("remove" 1))
(update dict1 '("remove" 2))
dict1

Get cdr of an elt in a list

I use 2 methods to build a tree based on cons cells.
(defun make-tree (nodes)
(cons nodes NIL))
(defun add-child (tree child)
(setf (cdr tree) (append (cdr tree) child)))
Then I created 4 parameters:
(defparameter *root* (make-tree "root"))
(defparameter *a* (make-tree "a"))
(defparameter *b* (make-tree "b"))
(defparameter *c* (make-tree "c"))
And I construct the following tree:
(add-child *root* *a*)
(add-child *root* *b*)
(add-child *a* *c*)
The *root* is displayed in the console:
CL-USER> *root*
("root" "a" "b")
My question is: Is it possible to retrieve c from *root*? Something like: (cdr (car (cdr *root*))) returns an error.
You need to use NCONC rather than APPEND in ADD-CHILD, so you don't make copies of the subtrees.
(defun add-child (tree child)
(setf (cdr tree) (append (cdr tree) child)))
With this change, after I do all the other steps, I get:
> *root*
("root" "a" "b" "c")
> (car (cdr (cdr (cdr *root*))))
"c"
> (cadddr *root*)
"c"

Getting all possible combinations of x booleans (Racket, Scheme)

i have a problem. How do I get all possible combinations of x booleans in Racket? (on a low language level)
I need something like that:
For x=1
(list
(list false)
(list true))
For x=2
(list
(list false false)
(list false true)
(list true false)
(list true true))
For x=3
(list
(list false false false)
(list false false true)
(list false true false)
(list false true true)
(list true false false)
(list true false true)
(list true true false)
(list true true true))
etc.
I have no idea how to do this in Racket.
Thanks you!
You're asking for all n-size permutations (not combinations!) of the list '(#t #f), with repetitions allowed. Adapting this answer for Racket:
(define (permutations size elements)
(if (zero? size)
'(())
(append-map (lambda (p)
(map (lambda (e)
(cons e p))
elements))
(permutations (sub1 size) elements))))
Use it like this:
(permutations 3 '(#t #f))
=> '((#t #t #t) (#f #t #t) (#t #f #t) (#f #f #t)
(#t #t #f) (#f #t #f) (#t #f #f) (#f #f #f))
Here is one way to convert a number to a list of booleans.
To generate all combinations, use it in a loop as you described.
(map (λ (x) (eqv? x #\1))
(string->list (number->string 12345 2)))
Replace 12345 with any number.
What you're actually doing is sort of building the powerset for a set of size x.
A powerset is the set of all possible subsets. For example, the powerset of (list 1 2 3) is (list (list 1 2 3) (list 1 2) (list 1 3) (list 1) (list 2 3) (list 2) (list 3) empty).
(A set is a subset of itself and the empty set is a subset of all sets.)
Why what you're doing describes the powerset is because an element can either be or not be in a subset. So apply (list true true true) to (list 1 2 3) will return (list 1 2 3) and (list false true true) will return (list 2 3).
This is my code for your problem.
(define baselist (list (list true) (list false)))
;; List1 List2 -> List of Lists
;; Where List1 is any list of lists, and list2 is a list of lists of size 2
;; and all of the lists within list 2 has one element
(define (list-combination list-n list-two)
(cond [(empty? list-n) empty]
[else (cons (append (first list-n) (first list-two))
(cons (append (first list-n) (second list-two))
(list-combination (rest list-n) list-two)))]))
;; tflist Number -> List of Boolean Lists
;; creates baselistn
(define (tflist n)
(cond [(= 1 n) baselist]
[else (list-combination (tlist (sub1 n)) baselist)]))
So (tflist 3) will return your original problem.
Now to make a powerset, you can do the following...
;; subset List1 ListofBooleans -> List
;; Determines which elements of a set to create a subset of
;; List1 and LoB are of the same length
(define (subset set t-f-list)
(cond [(empty? t-f-list) empty]
[(first t-f-list) (cons (first set) (subset (rest set) (rest t-f-list)))]
[else (subset (rest set) (rest t-f-list))]))
;;powerset set -> Powerset
;; produces a powerset of a set
(define (powerset set)
(local ((define upperbound (expt 2 (length set)))
(define tflist (tlist (length set)))
(define (powerset set n)
(cond [(= n upperbound) empty]
[else (cons (subset set (list-ref tflist n)) (powerset set (add1 n)))])))
(powerset set 0)))