How would I create a negate binary function in racket - functional-programming

I am confused on how to approach this function
The function negate-binary consumes a list of natural numbers, alist, and produces
a list containing the ones complement of the numbers in the list that are valid binary numbers
(i.e. numbers that only contain 0s and 1s).
The ones’ complement numbers in the produced list must
be in the same relative order as the original binary numbers appear in alist.
Assume none of the numbers have leading 0s; in other words, alist will not contain any numbers like 0001
number->string and string->number may be helpful *
(negate-binary (list 1000 101010 123 111)) ⇒ (list 111 10101 0)
(negate-binary (list 95 137 401)) ⇒ empty

#lang racket
; 1String is a String of length 1.
; [List-of Number] -> [List-of Number]
(define (negate-binary lon)
(map ones-complement (filter is-binary? lon)))
; Number -> Boolean
; is `num` a binary number?
(define (is-binary? num)
(andmap is-binary-1string? (num->1string-list num)))
; Number -> [List-of 1String]
; number to a list of 1strings
(define (num->1string-list num)
(explode (number->string num)))
; String -> [List-of 1String]
; convert a string to a list of 1strings
(define (explode str)
(map string (string->list str)))
; 1String -> Boolean
; is 1string a binary 1string?
(define (is-binary-1string? 1string)
(or (string=? 1string "0") (string=? 1string "1")))
; Number -> Number
; one's complement of a number
(define (ones-complement num)
(str-list->number (flip-bits (num->1string-list num))))
; [List-of 1String] -> [List-of 1String]
; "0" to "1" and "1" to "0" in list of 1strings
(define (flip-bits lo1s)
(map flip-bit lo1s))
; 1String -> 1String
; convert "0" to "1" and "1" to "0"
(define (flip-bit 1string)
(if (string=? 1string "0") "1" "0"))
; [List-of 1String] -> Number
; convert the list of 1strings to a number
(define (str-list->number lo1s)
(string->number (apply string-append lo1s)))
(module+ test
(require rackunit)
(check-equal? (negate-binary (list 1000 101010 123 111)) (list 111 10101 0))
(check-equal? (negate-binary (list 95 137 401)) empty))
Edit: removed all higher-order list abstractions like map, andmap, filter and apply.
#lang racket
; 1String is a String of length 1.
; [List-of Number] -> [List-of Number]
(define (negate-binary lon)
(ones-complement* (binary-only lon)))
; [List-of Number] -> [List-of Number]
; only keep the binary numbers
(define (binary-only lon)
(cond
[(empty? lon) '()]
[else (if (is-binary? (first lon))
(cons (first lon) (binary-only (rest lon)))
(binary-only (rest lon)))]))
; [List-of Number] -> [List-of Number]
; one's complement for all numbers in lon
(define (ones-complement* lon)
(cond
[(empty? lon) '()]
[else (cons (ones-complement (first lon))
(ones-complement* (rest lon)))]))
; Number -> Boolean
; is `num` a binary number?
(define (is-binary? num)
(all-binary-1strings? (num->1string-list num)))
; [List-of 1String] -> Boolean
; are all 1strings in lo1s binary?
(define (all-binary-1strings? lo1s)
(cond
[(empty? lo1s) #true]
[else (and (is-binary-1string? (first lo1s))
(all-binary-1strings? (rest lo1s)))]))
; Number -> [List-of 1String]
; number to a list of 1strings
(define (num->1string-list num)
(explode (number->string num)))
; String -> [List-of 1String]
; convert a string to a list of 1strings
(define (explode str)
(charlist->string-list (string->list str)))
; [List-of Char] -> [List-of 1String]
; convert a list of characters to a list of 1strings
(define (charlist->string-list charlist)
(cond
[(empty? charlist) '()]
[else (cons (string (first charlist))
(charlist->string-list (rest charlist)))]))
; 1String -> Boolean
; is 1string a binary 1string?
(define (is-binary-1string? 1string)
(or (string=? 1string "0") (string=? 1string "1")))
; Number -> Number
; one's complement of a number
(define (ones-complement num)
(str-list->number (flip-bits (num->1string-list num))))
; [List-of 1String] -> [List-of 1String]
; "0" to "1" and "1" to "0" in list of 1strings
(define (flip-bits lo1s)
(flip-all-bits lo1s))
; [List-of 1String] -> [List-of 1String]
; flip bits of all 1strings in lo1s
(define (flip-all-bits lo1s)
(cond
[(empty? lo1s) '()]
[else (cons (flip-bit (first lo1s))
(flip-all-bits (rest lo1s)))]))
; 1String -> 1String
; convert "0" to "1" and "1" to "0"
(define (flip-bit 1string)
(if (string=? 1string "0") "1" "0"))
; [List-of 1String] -> Number
; convert the list of 1strings to a number
(define (str-list->number lo1s)
(string->number (join-all lo1s)))
; [List-of 1String] -> String
; join all 1strings in lo1s into a single string
(define (join-all lo1s)
(cond
[(empty? lo1s) ""]
[else (string-append (first lo1s)
(join-all (rest lo1s)))]))
(module+ test
(require rackunit)
(check-equal? (negate-binary (list 1000 101010 123 111)) (list 111 10101 0))
(check-equal? (negate-binary (list 95 137 401)) empty))

Related

Racket checkerboard program that takes the size (row x column) and size of squares as args and builds a red and black checkerboard with DrRacket

Hi I'm struggling with this problem, I don't know how to add the number of square tiles and incorporate that as a user input value, I only know how to increase the size of the tiles. So I can make the squares bigger but I can't increase the number of them. The main issue is alternating the square colors red and black and having user input of the board size. If you can show me with circles or anything else how to take user input to add more I'd appreciate any help, this is due in three days and I've been working on it for a while.
Edit: In my class we haven't learned for-loops in racket so if there's an iterative/recursive way that would help me out.
Here's my code with multiple attempts:
#lang slideshow
(define (square n) (filled-rectangle n n))
(define (redblock n) (colorize(square) "red"))
(define (blackblock n) (colorize(square) "black"))
;slideshow
(define (series n)
[hc-append (* square n)]) ; contract violation, expected: number?, given: #<procedure:square>
;slideshow
(define (rb-series mk)
(vc-append
(series [lambda (sz) (colorize (mk sz) "red")])
(series [lambda (sz) (colorize (mk sz) "black")])))
(define (checker p1 p2) ;makes 2x2
(let ([p12 (hc-append p1 p2)]
[p21 (hc-append p2 p1)])
(vc-append p12 p21)))
(define (four p) ;can we get the parameter of this as any number instead of the shape?
(define two-p (hc-append p p))
(vc-append two-p two-p))
(define (checkerboard n sz)
(let* ([redblock (colorize(square sz)"red")]
[blackblock (colorize(square sz)"black")])
(define (blackred-list n)
;(define (string lst)) ;is there a way to construct an empty string to add to?
(for ([i n])
(if (even? i)
(hc-append blackblock)
(else
(hc-append (redblock)))))) ; this else part throws an error saying no hc-append
(define (redblack-list n)
(for ([i n])
(if (even? i)
(hc-append redblock)
(else (hc-append blackblock))))) ;another else with the same issue
(define (row-list n)
(for ([i n])
(if (even? i)
(vc-append blackred-list)
(else
(vc-append redblack-list)))))
(checkerboard 5 20))) ;this is just to test it, but how would I get user input?```
Let's break it down step by step:
Define function named checkerboard:
(define (checkerboard n sz) ...
With local definitions of redblock and blackblock...
(let ([redblock (colorize (filled-rectangle sz sz) "red")]
[blackblock (colorize (filled-rectangle sz sz) "black")])
With function blackred-list (I used letrec for recursive local definitions)...
(letrec ([blackred-list
(lambda (m) (cond ((zero? m) '())
((even? m) (cons blackblock (blackred-list (sub1 m))))
(else (cons redblock (blackred-list (sub1 m))))))]
With function redblack-list, which is very similar to blackred-list, so I am leaving that as work for you.
With function row-list:
[row-list (lambda (m) (map (lambda (i) (apply hc-append (reverse
(if (even? i)
(blackred-list m)
(redblack-list m)))))
(range m)))]
Then write (apply vc-append (row-list n)) inside letrec.
User input isn't mentioned in task, because you will just call (checkerboard 6 15) (or any other test) in REPL, but you surely can do this:
> (checkerboard (read) (read))
If one can confidently write and assemble small functions then the suggestions in
the exercise may be all one needs to produce a solution. But if this is a skill
that one is learning, then following a systematic design method may
help that learning process.
The design method here is HtDF (How to Design Functions): write down stub with signature and purpose, examples, and template, then edit the template to produce the required function.
(This answer uses characters to stand for blocks -- substitute eg hc-append for list->string for images)
(define redblock #\r)
(define blackblock #\b)
#;
(define (blackred-list m) ;; Natural -> ListOfBlock ; *stub* ;; *signature*
;; produce list of m alternating blocks (last one red) ; *purpose statement*
empty) ; *stub body* (valid result)
(check-expect (blackred-list 0) empty ) ; *minimal example*
#;
(define (fn n) ; *template*
(cond ;
[(zero? n) ... ] ;
[else (.... n (fn (- n 1))) ])) ;
(check-expect (blackred-list 1) (list redblock) ) ; *examples* to guide .... edit
(check-expect (blackred-list 2) (list blackblock redblock) )
(define (blackred-list m) ;; Natural -> ListOfBlock ; (edit template)
;; produce list of m alternating blocks (last one red)
(cond
[(zero? m) empty ]
[else (cons
(if (even? m)
blackblock
redblock)
(blackred-list (- m 1))) ]))
(check-expect (blackred-list 3) (list redblock blackblock redblock) )
(define (redblack-list m) ;; Natural -> ListOfBlock
;; produce list of m alternating blocks (last one black)
(cond
[(zero? m) empty ]
[else (cons
(if (even? m)
redblock
blackblock)
(redblack-list (- m 1))) ]))
(check-expect (redblack-list 3) (list blackblock redblock blackblock) )
#;
(define (row-list m) ;; Natural -> ListOfString ; *stub*
;; produce list of m alternating strings of blocks (last one ends in red)
empty)
(check-expect (row-list 0) empty) ; *examples* (same template)
(check-expect (row-list 1) (list "r") )
(check-expect (row-list 2) (list "rb" "br") )
(define (n-strings-of-length m n) ;; Natural Natural -> ListOfString
;; produce list of n alternating length m strings of blocks (last one ends in red)
(cond
[(zero? n) empty ]
[else (cons
(if (even? n)
(list->string (redblack-list m))
(list->string (blackred-list m)))
(n-strings-of-length m (- n 1))) ]))
(define (row-list m) ;; Natural -> ListOfString
;; produce list of m alternating length m strings of blocks (last one ends in red)
(n-strings-of-length m m))
(define (display-rows los) ;; ListOfString -> ; (from natural list recursion template)
;; display los, one element per line
(cond
[(empty? los) (void) ]
[else (begin
(display (car los))
(newline)
(display-rows (cdr los))) ]))
(define (checkerboard m) ;; Natural ->
;; display checkerboard with side m
(display-rows (row-list m)))
Welcome to DrRacket, version 8.4 [cs].
Language: Advanced Student.
All 8 tests passed!
>
The functions can now be reordered to produce the solution in specified local form:
(define redblock #\r)
(define blackblock #\b)
(define (checkerboard m) ;; Natural ->
;; display checkerboard with side m
(local [
(define (blackred-list m) ;; Natural -> ListOfBlock
;; produce list of m alternating blocks (last one red)
(cond
[(zero? m) empty ]
[else (cons
(if (even? m)
blackblock
redblock)
(blackred-list (- m 1))) ]))
(define (redblack-list m) ;; Natural -> ListOfBlock
;; produce list of m alternating blocks (last one black)
(cond
[(zero? m) empty ]
[else (cons
(if (even? m)
redblock
blackblock)
(redblack-list (- m 1))) ]))
(define (n-strings-of-length m n) ;; Natural Natural -> ListOfString
;; produce list of n alternating length m strings of blocks (last one ends in red)
(cond
[(zero? n) empty ]
[else (cons
(if (even? n)
(list->string (redblack-list m))
(list->string (blackred-list m)))
(n-strings-of-length m (- n 1))) ]))
(define (row-list m) ;; Natural -> ListOfString
;; produce list of m alternating length m strings of blocks (last one ends in red)
(n-strings-of-length m m))
(define (display-rows los) ;; ListOfString ->
;; display los, one element per line
(cond
[(empty? los) (void) ]
[else (begin
(display (car los))
(newline)
(display-rows (cdr los))) ])) ])
(display-rows (row-list m)))
Welcome to DrRacket, version 8.4 [cs].
Language: Advanced Student.
> (checkerboard 5)
rbrbr
brbrb
rbrbr
brbrb
rbrbr
>

Check if a list has uppercase or lowercase letters or numbers in a list in racket

How can i create a function that checks
if a list has at least one uppercase or lowercase letters, (and may contain numbers in a list) in racket
and contains no special characters (no spaces, no special characters)
(alphabet (list "abc" "ABC" "aBC" "AbC")) ⇒ true
(list "9wa123re1" "0w1e2a3r4")) ⇒ true
#lang racket
;; for one string is the test:
(define (alpha-and-perhaps-numeric? s)
(regexp-match #rx"^([0-9]*[a-zA-Z]+[0-9]*)+$" s))
;; for a list of strings is the test:
(define (alpha-list? l)
(for/and ((x l))
(alpha-and-perhaps-numeric? x)))
[0-9]* means: zero or more (*) numeric ([0-9])
[a-zA-Z]+ means: at least one or more (+) lower or uppercase alphabetic ([a-zA-Z])
[0-9]* possibly followed by zero or more numbers.
( )+ This whole construct matched at least once if not more times.
^ $ ensures that this thing matches from beginning to end of string without gaps.
So any other string not buildable with this pattern will return #f.
(any non-alphanumeric character containing string).
#lang racket
(define (alpha+-num? clst (acc #f) (alpha 0))
(cond ((null clst) (and (not (zero? alpha)) acc))
((char-alphabetic? (car clst)) (alpha+-num? (cdr clst) #t (+ alpha 1)))
((char-numeric? (car clst)) (alpha+-num? (cdr clst) acc alpha))
(else #f)))
(define (alpha+-num-string? s)
(alpha+-num? (remove-duplicates (string->list s))))
(define (alpha+-num-string-list? sl (acc #f))
(cond ((null sl) acc)
((alpha+-num-string? (car sl)) (alpha+-num-string-list? (cdr sl)))
(else #f)))
What you want is alpha+-num-string-list?
(define check-lower-char
(lambda (input)
(andmap (lambda(s)
(andmap (lambda (c)
(or (not (char-alphabetic? c))
(char-lower-case? c)))
s))
(map string->list input))))
(check-lower-char (list "abc" "ABC" "aBC" "AbC"))) ;; => #f
(check-lower-char (list "9wa123re1" "0w1e2a3r4")) ;; => #t

Replaces occurrences in a list - Racket

I am writing a function called ptyper that takes a nested list, nl. This function replaces all occurrences of a number with n and all occurrences of a symbol with s. This is what I have now:
(define (ptyper nl) (cond
((null? nl) '())
((list? nl)
(let ((ls (car nl)))
(list (ptyper ls))))
((number? (car nl))
(cons "n" (cdr nl)))
((symbol? (car nl))
(cons "s" (cdr nl)))
(else
(cons (car nl) (cdr nl)))))
I ran this test (ptyper '(2 (abc () "abc"))) but received an error that their was a contract violation. I'm not exactly sure what I'm doing wrong so if could use some help. Thanks!
Here is a possible solution with one function:
(define (ptyper nl)
(cond
((null? nl) '()) ; if the argument is an empty list, return the empty list
((list? nl) ; if the argument is a list, then
(let* ((c (car nl)) ; get its first element
(nc (cond ((number? c) "n") ; transform it for numbers
((symbol? c) "s") ; and symbols
((list? c) (ptyper c)) ; if a list recur over it
(else c)))) ; otherwise (e.g. a string) return as it is
(cons nc (ptyper (cdr nl))))) ; recursive call on the rest of the list
(else nl))) ; this should never happen for the specification,
; return the parameter or cause an error
Note that the error in your case is caused by the recursive call. When the function is called on an atom, for instance 2, first it checks for null and list?, and those checks returns false. Then it checks for (number (car nl)), but nl is equal to 2 and so car fails.
Here is a data definition for an S-expression, this models your data.
; An S-expr is one of:
; – Atom
; – SL
; An SL is one of:
; – '()
; – (cons S-expr SL)
; An Atom is one of:
; – Number
; – String
; – Symbol
We have predicates for every kind of data except Atom, so we make atom?:
;; Any -> Boolean
;; is the x an atom?
(define (atom? x)
(not (list? x)))
We follow the structure of the data to build "templates" for our functions:
(define (func sexp)
(cond
[(atom? sexp) (func-atom sexp)]
[else (func-sl sexp)]))
(define (func-sl sl)
(cond
[(empty? sl) ...]
[else (... (func (first sl)) ... (func-sl (rest sl)) ...)]))
(define (func-atom at)
(cond
[(number? at) ...]
[(string? at) ...]
[(symbol? at) ...]))
We fill in the gaps:
; Atom -> String
(define (subs-atom at)
(cond
[(number? at) "n"]
[(string? at) at]
[(symbol? at) "s"]))
; SL -> SL
(define (subs-sl sl)
(cond
[(empty? sl) sl]
[else (cons (subs-sexp (first sl))
(subs-sexp (rest sl)))]))
; S-exp -> S-exp
(define (subs-sexp sexp)
(cond
[(atom? sexp) (subs-atom sexp)]
[else (subs-sl sexp)]))
Using the interface for ptyper:
(define (ptyper nl)
(subs-sexp nl))
(ptyper '(2 (abc () "abc")))
; => '("n" ("s" () "abc"))

Counting number of occurrences of elements in a list

I am writing a function called count-if, which takes in a predicate, p?, and a list, ls. The function returns the number of occurrences of elements in the nested list that satisfy p?
For example: (count-if (lambda (x) (eq? 'z x)) '((f x) z (((z x c v z) (y))))) will return 3. This is what I have written:
(define (count-if p ls) (cond
((null? ls) '())
((p (car ls))
(+ 1 (count-if p (cdr ls))))
(else
(count-if p (cdr ls)))))
But I just get an error. I could use some help finding a better way to go about this problem. Thanks!
What is the signature of count-if? It is:
[X] [X -> Boolean] [List-of X] -> Number
What does the first cond clause return? It returns:
'()
This is a simple type error. Just change the base case to 0 and count-if works.
Edit (for nested).
First we define the structure of the date as Nested.
A symbol is just fed into the score helper function. Otherwise the recursive call is applied on all nested sub-nesteds, and the results are summed up.
#lang racket
; Nested is one of:
; - Number
; - [List-of Nested]
; Nested -> Number
(define (count-if pred inp)
; Symbol -> Number
(define (score n) (if (pred n) 1 0))
; Nested -> Number
(define (count-if-h inp)
(if (symbol? inp)
(score inp)
(apply + (map count-if-h inp))))
(count-if-h inp))
(count-if (lambda (x) (eq? 'z x)) '((f x) z (((z x c v z) (y)))))
; => 3

DrRacket and Recursive Statement Binary to Decimal

I am trying to convert a binary number entered as "1010" for 10 using recursion. I can't seem to wrap my head around the syntax for getting this to work.
(define (mod N M)
(modulo N M))
(define (binaryToDecimal b)
(let ([s 0])
(helper b s)))
(define (helper b s)
(if (= b 0)
(begin (+ s 0))
(begin (* + (mod b 2) (expt 2 s) helper((/ b 10) + s 1)))))
Thanks!
Here's a simple recursive solution:
(define (bin->dec n)
(if (zero? n)
n
(+ (modulo n 10) (* 2 (bin->dec (quotient n 10))))))
testing:
> (bin->dec 1010)
10
> (bin->dec 101)
5
> (bin->dec 10000)
16
If you want "1010" to translate to 10 (or #b1010, #o12 or #xa) you implement string->number
(define (string->number str radix)
(let loop ((acc 0) (n (string->list str)))
(if (null? n)
acc
(loop (+ (* acc radix)
(let ((a (car n)))
(- (char->integer a)
(cond ((char<=? a #\9) 48) ; [#\0-#\9] => [0-9]
((char<? a #\a) 55) ; [#\A-#\Z] => [10-36]
(else 87))))) ; [#\a-#\z] => [10-36]
(cdr n)))))
(eqv? #xAAF (string->number "aAf" 16)) ; ==> #t
It processes the highest number first and everytime a new digit is processed it multiplies the accumulated value with radix and add the new "ones" until there are not more chars. If you enter "1010" and 2 the accumulated value from beginning to end is 0, 0*2+1, 1*2+0, 2*2+1, 5*2+0 which eventually would make sure the digits numbered from right to left 0..n becomes Sum(vn*radic^n)
Now, if you need a procedure that only does base 2, then make a wrapper:
(define (binstr->number n)
(string->number n 2))
(eqv? (binstr->number "1010") #b1010) ; ==> #t

Resources