===== Lab 1: Introduction to Scheme ===== The goal of this lab is to make the students familiar with the IDE we will use for Scheme and help them write first simple programs. ===Dr. Racket IDE=== The IDE can be downloaded for free for Linux, Windows, MAC from: https://racket-lang.org/ /* Due to the pandemic situation, the labs will be online. Thus students are supposed to install DrRacket on their computers so that they can work on the tasks discussed in the labs. */ The students can use the one installed in the lab computers. The teacher may help the students (to a reasonable degree) to get the IDE running on students’ laptops. Get familiar with the definition window and REPL in DrRacket. The documentation of implemented functions is accessible via Help Desk in the menu. The language (scheme variant) can be selected via the #lang directive. - ''#lang racket'' (same as ''#lang scheme'') - ''#lang r5rs'' (if you wish to follow the R5RS standard) ===Scheme/Racket basics=== Start interaction in REPL. Scheme uses prefix notation for all functions. Let students compute simple formulas, e.g., 2+3/5. /* For the following exercises, I suggest first explaining the task. Then leaving the students to work on it individually for a few minutes. Discuss their ideas and approach to the problem. Afterwards, a randomly selected student will explain the solution to everyone on the whiteboard with help from the teacher and the other students. */ **Exercise 1:** Write a recursive function ''my-even?'' that decides whether a number is even using only functions +, -, = (without mutual recursion). ++++ solution | (define (my-even? n) (cond ([< n 0] (my-even? (- n))) ([= n 0] #t) ([= n 1] #f) (else (my-even? (- n 2))))) ++++ **Exercise 2:** Using the function string-append, create a function ''(copy-str n str)'' taking as arguments an integer ''n'', a string ''str'' and returns a string consisting of ''n''-many copies of ''str''. For example ''(copy-str 3 "abc") => "abcabcabc"''. ++++ solution | (define (copy-str n str) (if (<= n 0) "" (string-append str (copy-str (- n 1) str)))) ++++ **Exercise 3:** Rewrite the function from Exercise 2 so that it uses tail recursion. ++++ solution | (define (copy-str n str [acc ""]) (if (<= n 0) acc (copy-str (- n 1) str (string-append acc str)))) ++++ **Exercise 4:** Write a function ''(consecutive-chars first last)'' which takes two characters and returns a string consisting of a sequence of consecutive characters starting with ''first'', ending with ''last'' and following the order in ASCII table. For example ''(consecutive-chars #\A #\D) => "ABCD"'' or ''(consecutive-chars #\z #\u) => "zyxwvu"''. For converting characters into positions in ASCII table use functions ''char->integer'' and ''integer->char''. ++++ solution | (define (integer->string i) (string (integer->char i))) (define (consecutive-chars first last) (define first-index (char->integer first)) (define last-index (char->integer last)) (define step (if (< first-index last-index) 1 -1)) (define (iter k acc) (if (= k last-index) (string-append acc (integer->string k)) (iter (+ k step) (string-append acc (integer->string k))))) (iter first-index "")) ; alternatively: #| (define (char+1 c) (integer->char (add1 (char->integer c)))) (define (char-1 c) (integer->char (sub1 (char->integer c)))) (define (consecutive-chars fst lst [acc ""]) (cond [(char=? fst lst) (string-append acc (string fst))] [(char? fst lst) (consecutive-chars (char-1 fst) lst (string-append acc (string fst)))])) |# ++++ Try to solve the following individual tasks. **Task 1:** Write a function ''num-of-digits'' which takes an integer ''n'' and computes the number of digits ''n'' has in the standard decimal representation. For example ''(num-of-digits 123) => 3'' or ''(num-of-digits -3456) => 4''. //Hint:// The number of digits can be computed by successive dividing the input number by 10. For the integer division, you can use the function ''quotient''. ++++ solution | (define (num-of-digits n [acc 1]) (cond ([< n 0] (num-of-digits (- n))) ([< n 10] acc) (else (num-of-digits (quotient n 10) (+ acc 1))))) ++++ ** Task 2:** Write a function ''(num->str n [radix 10])'' taking as input an integer ''n'' together with ''radix'' denoting the number of symbols used to represent the number ''n'' (for example 2,10,16 for binary, decimal, hexadecimal representation respectively). This function returns a string containing the representation of ''n'' in the corresponding numerical system. For the representation use the standard symbols 0123456789ABCDEF. Examples: * ''(num->str 52) => "52"'', * ''(num->str 5 2) => "101"'', * ''(num->str 255 16) => "FF"''. //Hint:// The representation can be obtained by consecutive division of ''n'' by ''radix'' and collecting the remainders. The remainder after integer division can be computed by the function ''remainder''. ++++ solution | (define (num->str n [radix 10]) (define rem (remainder n radix)) (define initial (if (< rem 10) (char->integer #\0) (- (char->integer #\A) 10))) (define rem-str (string (integer->char (+ initial rem)))) (if (< n radix) rem-str (string-append (num->str (quotient n radix) radix) rem-str))) ; Alternative #| (define numeric-alphabet "0123456789ABCDEF") (define (num->char n [radix 10]) (string-ref numeric-alphabet (remainder n radix))) (define (num->str n [radix 10] [acc '()]) (cond [(negative? n) (num->str (- n) radix '(#\-))] [(< n radix) (list->string (cons (num->char n radix) acc))] [else (num->str (quotient n radix) radix (cons (num->char n radix) acc))])) |# ++++