Translation of Scheme code for Sierpinski carpet - scheme

I found code for generating Sierpinski carpet at http://rosettacode.org/wiki/Sierpinski_carpet#Scheme - but it won't run in the DrRacket environment or WeScheme. Could someone provide solutions for either environments?

It looks like this code runs fine in DrRacket after prepending a
#lang racket
line indicating that the code is written in Racket. I can provide more detail if this is not sufficient.

I've translated the program to run under WeScheme. I've made a few changes: rather than use (display) and (newline), I use the image primitives that WeScheme provides to make a slightly nicer picture. You can view the running program and its source code. For convenience, I also include the source here:
;; Sierpenski carpet.
;; http://rosettacode.org/wiki/Sierpinski_carpet#Scheme
(define SQUARE (square 10 "solid" "red"))
(define SPACE (square 10 "solid" "white"))
(define (carpet n)
(local [(define (in-carpet? x y)
(cond ((or (zero? x) (zero? y))
#t)
((and (= 1 (remainder x 3)) (= 1 (remainder y 3)))
#f)
(else
(in-carpet? (quotient x 3) (quotient y 3)))))]
(letrec ([outer (lambda (i)
(cond
[(< i (expt 3 n))
(local ([define a-row
(letrec ([inner
(lambda (j)
(cond [(< j (expt 3 n))
(cons (if (in-carpet? i j)
SQUARE
SPACE)
(inner (add1 j)))]
[else
empty]))])
(inner 0))])
(cons (apply beside a-row)
(outer (add1 i))))]
[else
empty]))])
(apply above (outer 0)))))
(carpet 3)

Here is the modified code for WeScheme. WeScheme don't support do-loop syntax, so I use unfold from srfi-1 instead
(define (unfold p f g seed)
(if (p seed) '()
(cons (f seed)
(unfold p f g (g seed)))))
(define (1- n) (- n 1))
(define (carpet n)
(letrec ((in-carpet?
(lambda (x y)
(cond ((or (zero? x) (zero? y))
#t)
((and (= 1 (remainder x 3)) (= 1 (remainder y 3)))
#f)
(else
(in-carpet? (quotient x 3) (quotient y 3)))))))
(let ((result
(unfold negative?
(lambda (i)
(unfold negative?
(lambda (j) (in-carpet? i j))
1-
(1- (expt 3 n))))
1-
(1- (expt 3 n)))))
(for-each (lambda (line)
(begin
(for-each (lambda (char) (display (if char #\# #\space))) line)
(newline)))
result))))

Related

Queues in Racket?

I used the following code to solve Sum by Factors:
#lang racket
(provide sum-of-divided)
(define (sum-of-divided lst)
(define (go ps n l)
(define ((exhaust d) x)
(define q (/ x d))
(if (integer? q)
((exhaust d) q)
(if (> x 1) `(,x) '())))
(if (null? l)
ps
(if
(for/or
([p ps])
#:break (< n (sqr p))
(= 0 (modulo n p)))
(go ps (+ n 1) l)
(go
(append ps `(,n))
(+ n 1)
(append-map (exhaust n) l)))))
(for*/list
([m (go '() 2 (map abs lst))]
[s `(,(for/fold
([a '(0 #f)])
([x lst])
(if (= 0 (modulo x m))
`(,(+ (car a) x) #t)
a)))]
#:when (cadr s))
`(,m ,(car s))))
To my surprise, it passed the tests, which have a time limit of 12 s, only after I changed sequence-append in L20 to append. The documentation for sequence-append says:
The new sequence is constructed lazily.
But, as it turns out, it apparently means that the subsequent sequences aren't concatenated unless needed. But when their elements are needed, i.e. the sequence resulting from sequence-append is consumed far enough, the time cost linear in the sum of lengths of all previous sequences is incurred. Right? Is that why it was slow?
If so, how to work around it? (In this case append was performant enough, but suppose I really needed a structure which is at least a FIFO queue with the usual complexities.) Is there a good alternative within the racket language, without requireing additional packages (which may be unavailable, as is the case on Codewars)? Difference lists maybe (quite easy to implement from scratch)?
I ended up using the obvious, hitherto purposely avoided: mutable lists:
#lang racket
(provide sum-of-divided)
(define (sum-of-divided lst)
(define ps (mcons 0 '()))
(define t ps)
(for*/list
([m
(let go ([n 2] [l (map abs lst)])
(if (null? l)
(mcdr ps)
(go
(+ n 1)
(if
(for/or
([p (mcdr ps)])
#:break (< n (sqr p))
(= 0 (modulo n p)))
l
(begin
(set-mcdr! t (mcons n '()))
(set! t (mcdr t))
(remq*
'(1)
(map
(λ (x)
(let exhaust ([s x])
(define q (/ s n))
(if (integer? q)
(exhaust q)
s)))
l)))))))]
[s `(,(for/fold
([a '(0 #f)])
([x lst])
(if (= 0 (modulo x m))
`(,(+ (car a) x) #t)
a)))]
#:when (cadr s))
`(,m ,(car s))))
I also tried a purely functional approach with streams:
#lang racket
(provide sum-of-divided)
(define primes
(letrec
([ps
(stream*
2
(for*/stream
([i (in-naturals 3)]
#:unless
(for/or
([p ps])
#:break (< i (sqr p))
(= 0 (modulo i p))))
i))])
ps))
(define (sum-of-divided lst)
(for/fold
([l lst]
[r '()]
#:result (reverse r))
([d primes])
#:break (null? l)
(values
(remq*
'(1)
(map
(λ (x)
(let exhaust ([s x])
(define q (/ s d))
(if (integer? q)
(exhaust q)
s)))
l))
`(,#(for/fold
([a 0]
[f #f]
#:result
(if f
`((,d ,a))
'()))
([n lst])
(if (= 0 (modulo n d))
(values (+ a n) #t)
(values a f)))
,#r))))
Surprisingly, it consistently times out, whereas the imperative one above never does. Having believed Racket implementors cared at least equally for performance with functional style, I'm disappointed.

Scheme R5RS contract violation

The code below is the answer given by the professor for a question in my intro to scheme course but it comes out with an error. Cannot see why.
#!r5rs
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
(complex-sqrt 7)
;; ERROR mcar: contract violation
;; expected: mpair?
;; given: 7
I took a screenshot of the error with trace illustartion while running it in DrRacket.
Here's your code transcribed. Please consider posting the actual code rather than a screenshot in future.
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
Was the (complex-sqrt 7) part provided by your professor too? We're trying to get the square root of a complex number, so we should pass in a complex number:
(complex-sqrt (make-complex 5 2))
'(2.27872385417085 . 0.43884211690225433)
Which according to https://www.wolframalpha.com/input/?i=sqrt(2i%2B5) is correct!
The implementation of complex-sqrt is an unsafe one. What that means is that it assumes you pass it a complex number, in this case something created with make-complex.
To fix this you need to check if the argument is complex:
;; Not 100%. Should use `struct` to not
;; mix with random pairs that happens to have numeric parts
(define (complex? x)
(and (pair? x)
(number? (car x))
(number? (cdr x))))
;; The original code is renamed to unsafe-complex-sqrt
(define (complex-sqrt x)
(if (complex? x)
(unsafe-complex-sqrt x)
(raise-argument-error 'complex-sqrt "complex?" x)))
Now you can test it:
(complex-sqrt (make-complex 7 0))
; ==> (2.6457513110645907 . 0)
(complex-sqrt 7)
; ERROR complex-sqrt: contract violation
; expected: complex?
; given: 7
Perfect. Now it says you have mot passed the required complex number to a function that requires a complex number to work.
So what happend in the original code?
In unsafe-complex-sqrt it uses car and cdr which are safe operations that signal contract violation if the argument x supplied isn't #t for (pair? x).
Racket uses mcons in its #!r5rs implementation and thus the errors refer to every pair/list function in R5RS prefixed with an m since the error doesn't pay attention to renaming.

How to make this function elegant

In response to the following exercise from the SICP,
Exercise 1.3. Define a procedure that takes three numbers as arguments
and returns the sum of the squares of the two larger numbers.
I wrote the following (correct) function:
(define (square-sum-larger a b c)
(cond ((or (and (> a b) (> b c)) (and (> b a) (> a c))) (+ (* a a) (* b b)))
((or (and (> a c) (> c b)) (and (> c a) (> a b))) (+ (* a a) (* c c)))
((or (and (> b c) (> c a)) (and (> c b) (> b a))) (+ (* b b) (* c c)))))
Unfortunately, that is one of the ugliest functions I've written in my life. How do I
(a) Make it elegant, and
(b) Make it work for an arbitrary number of inputs?
I found an elegant solution (though it only works for 3 inputs):
(define (square-sum-larger a b c)
(+
(square (max a b))
(square (max (min a b) c))))
If you're willing to use your library's sort function, this becomes easy and elegant.
(define (square-sum-larger . nums)
(define sorted (sort nums >))
(let ((a (car sorted))
(b (cadr sorted)))
(+ (* a a) (* b b))))
In the above function, nums is a "rest" argument, containing a list of all arguments passed to the function. We just sort that list in descending order using >, then square the first two elements of the result.
I don't know if it's elegant enough but for a 3 argument version you can use procedure abstraction to reduce repetition:
(define (square-sum-larger a b c)
(define (square x)
(* x x))
(define (max x y)
(if (< x y) y x))
(if (< a b)
(+ (square b) (square (max a c)))
(+ (square a) (square (max b c)))))
Make it work for an arbitrary number of inputs.
(define (square-sum-larger a b . rest)
(let loop ((a (if (> a b) a b)) ;; a becomes largest of a and b
(b (if (> a b) b a)) ;; b becomes smallest of a and b
(rest rest))
(cond ((null? rest) (+ (* a a) (* b b)))
((> (car rest) a) (loop (car rest) a (cdr rest)))
((> (car rest) b) (loop a (car rest) (cdr rest)))
(else (loop a b (cdr rest))))))
A R6RS-version using sort and take:
#!r6rs
(import (rnrs)
(only (srfi :1) take))
(define (square-sum-larger . rest)
(apply +
(map (lambda (x) (* x x))
(take (list-sort > rest) 2))))
You don't need to bother sorting you just need the find the greatest two.
(define (max-fold L)
(if (null? L)
#f
(reduce (lambda (x y)
(if (> x y) x y))
(car L)
L)))
(define (remove-num-once x L)
(cond ((null? L) #f)
((= x (car L)) (cdr L))
(else (cons (car L) (remove-once x (cdr L))))))
(define (square-sum-larger . nums)
(let ((max (max-fold nums)))
(+ (square max)
(square (max-fold (remove-num-once max nums))))))
(square-sum-larger 1 8 7 4 5 6 9 2)
;Value: 145

How to do square in RACKET

Here is my code:
(define (squares 1st)
(let loop([1st 1st] [acc 0])
(if (null? 1st)
acc
(loop (rest 1st) (* (first 1st) (first 1st) acc)))))
My test is:
(test (sum-squares '(1 2 3)) => 14 )
and it's failed.
The function input is a list of number [1 2 3] for example, and I need to square each number and sum them all together, output - number.
The test will return #t, if the correct answer was typed in.
This is rather similar to your previous question, but with a twist: here we add, instead of multiplying. And each element gets squared before adding it:
(define (sum-squares lst)
(if (empty? lst)
0
(+ (* (first lst) (first lst))
(sum-squares (rest lst)))))
As before, the procedure can also be written using tail recursion:
(define (sum-squares lst)
(let loop ([lst lst] [acc 0])
(if (empty? lst)
acc
(loop (rest lst) (+ (* (first lst) (first lst)) acc)))))
You must realize that both solutions share the same structure, what changes is:
We use + to combine the answers, instead of *
We square the current element (first lst) before adding it
The base case for adding a list is 0 (it was 1 for multiplication)
As a final comment, in a real application you shouldn't use explicit recursion, instead we would use higher-order procedures for composing our solution:
(define (square x)
(* x x))
(define (sum-squares lst)
(apply + (map square lst)))
Or even shorter, as a one-liner (but it's useful to have a square procedure around, so I prefer the previous solution):
(define (sum-squares lst)
(apply + (map (lambda (x) (* x x)) lst)))
Of course, any of the above solutions works as expected:
(sum-squares '())
=> 0
(sum-squares '(1 2 3))
=> 14
A more functional way would be to combine simple functions (sum and square) with high-order functions (map):
(define (square x) (* x x))
(define (sum lst) (foldl + 0 lst))
(define (sum-squares lst)
(sum (map square lst)))
I like Benesh's answer, just modifying it slightly so you don't have to traverse the list twice. (One fold vs a map and fold)
(define (square x) (* x x))
(define (square-y-and-addto-x x y) (+ x (square y)))
(define (sum-squares lst) (foldl square-y-and-addto-x 0 lst))
Or you can just define map-reduce
(define (map-reduce map-f reduce-f nil-value lst)
(if (null? lst)
nil-value
(map-reduce map-f reduce-f (reduce-f nil-value (map-f (car lst))))))
(define (sum-squares lst) (map-reduce square + 0 lst))
racket#> (define (f xs) (foldl (lambda (x b) (+ (* x x) b)) 0 xs))
racket#> (f '(1 2 3))
14
Without the use of loops or lamdas, cond can be used to solve this problem as follows ( printf is added just to make my exercises distinct. This is an exercise from SICP : exercise 1.3):
;; Takes three numbers and returns the sum of squares of two larger number
;; a,b,c -> int
;; returns -> int
(define (sum_sqr_two_large a b c)
(cond
((and (< a b) (< a c)) (sum-of-squares b c))
((and (< b c) (< b a)) (sum-of-squares a c))
((and (< c a) (< c b)) (sum-of-squares a b))
)
)
;; Sum of squares of numbers given
;; a,b -> int
;; returns -> int
(define (sum-of-squares a b)
(printf "ex. 1.3: ~a \n" (+ (square a)(square b)))
)
;; square of any integer
;; a -> int
;; returns -> int
(define (square a)
(* a a)
)
;; Sample invocation
(sum_sqr_two_large 1 2 6)

Creating a list from conditionals during iteration

I have written a simple procedure to find the divisors of a number (not including the number itself). I have figured out how to print them, but I would like to have this function return a list containing each of the divisors.
(define (divisors n)
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond
((= (modulo n i) 0)
(printf "~a " i)))))
My idea is to create a local list, adding elements to it where my printf expression is, and then having the function return that list. How might I go about doing that? I am new to Scheme, and Lisp in general.
Do you necessarily have to use have to use do? here's a way:
(define (divisors n)
(do ((i 1 (add1 i))
(acc '() (if (zero? (modulo n i)) (cons i acc) acc)))
((> i (floor (/ n 2)))
(reverse acc))))
But I believe it's easier to understand if you build an output list with a named let:
(define (divisors n)
(let loop ((i 1))
(cond ((> i (floor (/ n 2))) '())
((zero? (modulo n i))
(cons i (loop (add1 i))))
(else (loop (add1 i))))))
Or if you happen to be using Racket, you can use for/fold like this:
(define (divisors n)
(reverse
(for/fold ([acc '()])
([i (in-range 1 (add1 (floor (/ n 2))))])
(if (zero? (modulo n i))
(cons i acc)
acc))))
Notice that all of the above solutions are written in a functional programming style, which is the idiomatic way to program in Scheme - without using mutation operations. It's also possible to write a procedural style solution (see #GoZoner's answer), similar to how you'd solve this problem in a C-like language, but that's not idiomatic.
Just create a local variable l and extend it instead of printing stuff. When done, return it. Like this:
(define (divisors n)
(let ((l '()))
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond ((= (modulo n i) 0)
(set! l (cons i l))))
l))
Note that because each i was 'consed' onto the front of l, the ordering in l will be high to low. Use (reverse l) as the return value if low to high ordering is needed.

Resources