How do I divide these lists? [closed] - scheme

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Example input:
((a1 . b) (a1 . c)):
I have one list with two elements, those elements are lists or pairs with two elements. And i want to check if the first element of the first pair/list is equal to the first element of the second pair/list.
output: If so, i want to create a new list with two lists, the first is the list:
while (b < c) -> (a1 . b(even)) (a1 . b+2(even))...
The other list is the same, but with the odd's
How do I implement this in scheme:
INPUT:
((1 . 1) (1 . 7))
OUTPUT:
(((1 . 2) (1 . 4) (1 . 6)) ((1 . 3) (1 . 5) (1 . 7)))
I have one list with two elements. Each element is also a list with two elements, both integers >= 0 and < 8
I have to create this:
input ((a1 . b) (a1 . c))
output: (if (and (= a1 a2) (odd? b))
While < b c
(list (a1 . b+1) (a1 . b+3) (a1 . b+n)...))
(list (a2 . b) (a2 . b+2) (a2 . b+4)...)
I had done this, but i can't find where i'm failing, could you help me?....
;;; Verify if absissa0 = absissa1
(define (game-position input)
(if (= (car (car j)) (cdr (cdr j)))
(col1_col2 j)
(error "Not valid"))))
;;; verify if absissa0 is even
(define (col1_col2 gstart)
(if (even? (cdr (car jstart)))
(list (pos-start jstart))
(list (pos-start (list (cons (car (car jstart)) (- (cdr (car jstart)) 1)) (car (cdr jstart))))))
;;; Loop that creates positions of even's and odd's
(define (pos-start j2)
(while ( < (cdr (car j2)) (- (cdr (cdr j2)) 2))
((cons (car (car j2)) (+ (cdr (car j2)) 2)) (pos-start (list (cons (car (car j2)) (+ (cdr (car j2)) 2)) (car (cdr j2)))))
(odd_2 (list (cons (car (car j2)) (+ (cdr (car j2)) 1)) (car (cdr j2)))))
(define (odd_2 j3)
(while ( < (cdr (car j3)) (- (car (cdr j3)) 2))
((j3) (odd_2 (list (cons (car (car j3)) (+ (cdr (car j3)) 2)) (car (cdr j3)))
(value)))

; position l e a coluna c.
(define (do-pos l c)
(if (and (integer? l) (integer? c) (>= l 0) (>= c 0) (<= l 7) (<= c 7))
(cons l c)
(error "insert a valid number between 0 and 7")))
; returns l
(define (line-pos p)
(car p))
; returns c
(define (column-pos p)
(cdr p))
; Arg is position.
(define (pos? arg)
(and (pair? arg) (integer? (line-pos arg)) (integer? (column-pos arg)) (< (car arg) 8) (>= (car arg) 0) (< (cdr arg) 8) (>= (cdr arg) 0)))
; two positions are equal?
(define (pos=? p1 p2)
(and (= (line-pos p1)(line-pos p2))(= (column-pos p1)(column-pos p2))))
(define (oper* x y)
(* (- x y) (- x y)))
; Distance between p1 e p2.
(define (distance p1 p2)
(sqrt (+ (oper* (line-pos p1) (line-pos p2)) (oper* (column-pos p1) (column-pos p2)))))
; Same directions? if same line and same column
(define (same-direction? p1 p2)
(or (= (line-pos p1) (line-pos p2)) (= (column-pos p1) (column-pos p2))))
; check if to positions are adjacent
(define (adjacent? p1 p2)
(and (same-direccao? p1 p2) (= (distance p1 p2) 1)))
; from a position, returns all adjacents moves
(define (adjacent p) (cond ((and (= (line-pos p) 0) (= (column-pos p) 0)) (list (faz-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1))))
((and (= (line-pos p) 7) (= (column-pos p) 7)) (list (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (- (column-pos p) 1))))
((= (line-pos p) 0) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))
((= (column-pos p) 0) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1))))
((= (line-pos p) 7) (list (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))
((= (column-pos p) 7) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (- (column-pos p) 1))))
(else (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))))
; returns a move with p1 and p2
(define (do-game p1 p2)
(if (and (pos? p1) (pos? p2))
(list p1 p2)
(error "Insert two valid positions")))
; returns the beguining of j.
(define (b-do-game j)
(car j))
; returns the end of j.
(define (e-do-hame j)
(car (cdr j)))
; Arg is a do-game?.
(define (do-game? arg)
(and (list? arg) (pos? (b-do-game arg)) (pos? (e-do-game arg))))
; do game is null?.
(define (do-game-null? j)
(pos=? (b-do-game j) (e-do-game j)))
; list with two do-game (pc and pl)
(define (play-pos pc pl)
(if (and (list? pc) (list? pl))
(list pc pl)
(error "Insere two valid moves")))
; returns pc.
(define (cap-pieces pj)
(b-do-game pj))
; returns pj
(define (free_pieces pj)
(e-do-game pj))
(define (neven n)
(if (even? n)
n (+ n 1)))
; create sublists
(define (sublist a mn mx)
(cond ((<= mn mx) (cons (do-pos a mn) (sublist a (+ mn 2) mx)))
(else '())))
(define (sublist2 a mn mx)
(cond ((<= mx (- mn 2)) (cons (do-pos a (- mn 2)) (sublist2 a (- mn 2) mx)))
(else '())))
(define (sublist3 a mn mx)
(cond ((<= mn mx) (cons (do-pos mn a) (sublist3 a (+ mn 2) mx)))
(else '())))
(define (sublist4 a mn mx)
(cond ((<= mx (- mn 2)) (cons (do-pos (- mn 2) a) (sublist4 a (- mn 2) mx)))
(else '())))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Returns game-positions
(define (game-positions j)
(if (not (and (do-game? j) (same-direction? (b-do-game j) (e-do-game j)) (even? (distance (b-do-game j) (e-do-game j)))))
(list)
(if (= (line-pos (b-do-game j)) (line-pos (e-do-game j)))
(f_odd_even? j)
(f_odd_even2? j))))
; Check is starts with odd or even.
(define (f_odd_even? j) (if (even? (column-pos (b-do-game j)))
(b_even j)
(b_odd j)))
(define (f_odd_even2? j) (if (even? (line-pos (b-do-jogada j)))
(b-even1 j)
(b_odd1 j)))
; If starts with odd:
(define (b_odd j)
(if (< (column-pos (b-do-game j)) (column-pos (e-do-game j)))
(list (sublist (line-pos (b-do-game j))
(neven (column-pos (b-do-game j)))
(column-pos (e-do-game j)))
(sublist (line-pos (b-do-game j))
(+ 1 (neven (column-pos (b-do-game j))))
(column-pos (e-do-game j))))
(list (sublist2 (line-pos (b-do-game j))
(+ 1 (column-pos (b-do-game j)))
(column-pos (e-do-game j)))
(sublist2 (line-pos (b-do-game j))
(column-pos (b-do-game j))
(- 1 (column-pos (e-do-game j)))))))
(define (b_even j)
(if (< (column-pos (b-do-game j)) (column-pos (e-do-game j)))
(list (sublist (line-pos (b-do-game j))
(+ 2 (neven (column-pos (b-do-game j))))
(column-pos (e-do-game j)))
(sublist (line-pos (b-do-game j))
(+ 1 (neven (column-pos (b-do-game j))))
(column-pos (e-do-game j))))
(list (sublist2 (line-pos (b-do-game j))
(column-pos (b-do-game j))
(column-pos (e-do-game j)))
(sublist2 (line-pos (b-do-game j))
(+ 1 (column-pos (b-do-game j)))
(column-pos (e-do-game j))))))
(define (b_odd1 j)
(if (< (line-pos (b-do-game j)) (column-pos (e-do-game j)))
(list (sublist3 (column-pos (b-do-game j))
(neven (line-pos (b-do-game j)))
(line-pos (e-do-game j)))
(sublist3 (column-pos (b-do-game j))
(+ 1 (neven (line-pos (b-do-game j))))
(line-pos (e-do-game j))))
(list (sublist4 (column-pos (b-do-game j))
(+ 1 (line-pos (b-do-game j)))
(line-pos (e-do-game j)))
(sublist4 (column-pos (b-do-game j))
(line-pos (b-do-game j))
(- 1 (line-pos (e-do-game j)))))))
(define (b_even1 j)
(if (< (line-pos (b-do-game j)) (line-pos (e-do-game j)))
(list (sublist3 (column-pos (b-do-game j))
(+ 2 (neven (line-pos (b-do-game j))))
(line-pos (e-do-game j)))
(sublist3 (column-pos (b-do-game j))
(+ 1 (neven (line-pos (b-do-game j))))
(line-pos (e-do-game j))))
(list (sublist4 (column-pos (b-do-game j))
(line-pos (b-do-game j))
(line-pos (e-do-game j)))
(sublist4 (column-pos (b-do-game j))
(+ 1 (line-pos (b-do-game j)))
(line-pos (e-do-game j))))))
This is the first part of the game I'm making, I was translating the variables from portuguese to english so it could have some error.
Dlm, can you do the same that you did in your code with "while cicles"?
Could you check my code and improve it a litle? I am trying to improve my programming skills, and it's starts from my code, Basicaly I want to get a programming style

Sorry for the previous posting. It was my first post
and I posted as an unregistered user. I obviously
haven't figured out how to format text yet.
I've created an account (user dlm) and I'm making a
second attempt -- here goes.
I've been working on learning Racket/Scheme for a while
now and this site looks like a great place to share and
learn from others.
I'm not 100% sure of the spec on this question and
have my doubts that my code actually solves the problem
at hand but I think it's readable enough to be modified
as needed
Readability is one of the things I've been working on
and would appreciate feedback/suggestions from others.
dlm.
My 2 cents :
(define (process-list? lst)
(let*([pair-0 (list-ref lst 0)]
[pair-1 (list-ref lst 1)])
(and (= (car pair-0) (car pair-1))
(< (cdr pair-0) (cdr pair-1)))))
(define (make-odd/even-sets data)
(let*([x (car (list-ref data 0))]
[y-start (cdr (list-ref data 0))]
[max (cdr (list-ref data 1))])
(define (loop y evens odds)
(if (<= y max)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds))
(list (reverse odds) (reverse evens))))
(loop y-start '() '())))
(define (main data)
(if (process-list? data)
(let*([odd/even (make-odd/even-sets data)])
(printf "~a~n" (list-ref odd/even 0))
(printf "~a~n" (list-ref odd/even 1)))
(printf "Invalid list~n" )))
(main '((1 . 1) (1 . 7)) )
UPDATE:
Hi gn66,
I don't know how much I can actually do in terms of the
game itself but I might be able to give you some
pointers/ideas.
A major thing to look for in improving code is to to
look for repeating code applied to specific situations
and try to think of ways to generalize. At first the
generalized form can seam harder to read when you don't
see what's going on but once you fully understand it
it's actually easier, not only to read but modify.
Looking at your code the 'adjacent' procedure jumps out
as something that could be shortened so I'll use that as
an example. Let's start by first ignoring the boundary
conditions and look for the generial pattern of
operations (example: where you put the logic for
conditional test can have a big effect on the size of the
code).
(define (adjacent p)
(list (do-pos (+ (line-pos p) 1) (column-pos p))
(do-pos (- (line-pos p) 1) (column-pos p))
(do-pos (line-pos p) (+ (column-pos p) 1))
(do-pos (line-pos p) (- (column-pos p) 1))) )
The problem here can be partitioned into 2 different
problems: 1) changing line postions + - 1 and
2) changing row positions + - 1. Both applying
the same operations to different components of the
position. So let's just work with one.
(instead of a while loop lets look at MAP which is
like a "while list not empty" loop)
Using 'map' to apply an operation to data list(s)
is pretty straight forward:
(map (lambda (val) (+ val 5))
'(10 20 30))
If needed you can inclose it inside the scope of a procdure
to maintain state information such as a counter:
(define (test lst)
(let*([i 0])
(map (lambda (val)
(set! i (+ i 1))
(+ val i))
lst)))
(test '(10 20 30))
Or pass in values to use in the operation:
(define (test lst amount)
(map (lambda (val) (+ val amount))
lst))
(test '(10 20 30) 100)
Now turn your thinking inside out and consider that
it's possible to have it map a list of operations to
some data rather than data to the operation.
(define (test val operations-lst)
(map (lambda (operation) (operation val))
operations-lst))
(test 10 (list sub1 add1))
Now we have the tools to start creating a new
'adjacent' procedure:
(define (adjacent p)
(define (up/down p) ;; operations applied to the line componet
(map (lambda (operation)
(cons (operation (line-pos p)) (column-pos p)))
(list add1 sub1)))
(define (left/right p) ;; operations applied to the column componet
(map (lambda (operation)
(cons (line-pos p) (operation (column-pos p))))
(list add1 sub1)))
(append (up/down p) (left/right p))
)
(adjacent (do-pos 1 1))
This works find for positions that aren't on the boundary
but just as the old saying goes "it's sometimes easier to do
something and then apologize for it than it is to first ask
permission". Let's take the same approach and let the errant
situations occur then remove them. The 'filter' command is
just the tool for the job.
The 'filter' command is similiar to the map command in that
it takes a list of values and passes them to a function. The
'map' command returns a new list containing new elements
that correpsond to each element consumed. Filter returns
the original values but only the ones that the (predicate)
function "approves of" (returns true for).
(filter
(lambda (val) (even? val))
'(1 2 3 4 5 6 7 8))
will return the list (2 4 6 8)
So adding this to the new 'adjacent' procedure we get:
(define (adjacent p)
(define (up/down p)
(map (lambda (operation)
(cons (operation (line-pos p)) (column-pos p)))
(list add1 sub1)))
(define (left/right p)
(map (lambda (operation)
(cons (line-pos p) (operation (column-pos p))))
(list add1 sub1)))
(define (select-valid p-lst)
(filter
(lambda (p) (and (>= (line-pos p) 0) (>= (column-pos p) 0)
(<= (line-pos p) 7) (<= (column-pos p) 7)))
p-lst))
(select-valid
(append (up/down p) (left/right p))))
As for the "while cycles" you asked about: you need to
develop the ability to "extract" information like this from
existing examples. You can explore different aspects of
existing code by trying to remove as much code as you can
and still get it to work for what you are interested in
(using print statements to get a window onto what's going
on). This is a great way to learn.
From my first posting cut out the loop that creates the
evens/odds list. When you try to run you find out what is
missing (the dependencies) from the error messages so
just define them as needed:
(define x 1)
(define max 5)
(define (loop y evens odds)
(if (<= y max)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds))
(list (reverse odds) (reverse evens))))
(loop 1 '() '())
Add a print statement to get info on the mechanics of how
it works:
(define x 1)
(define max 5)
(define y-start 1)
(define (loop y evens odds)
(if (<= y max)
(begin
(printf "section 1 : y=~a~n" y)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds)))
(begin
(printf "section 2 : y=~a~n" y)
(list (reverse odds) (reverse evens))
)))
(loop y-start '() '())
Now remove parts you aren't interested in or don't need,
which may take some exploration:
(let*([max 5])
(define (loop y)
(if (<= y max)
(begin
(printf "section 1 : y=~a~n" y)
(loop (add1 y)))
(begin
(printf "section 2 : y=~a~n" y)
'()
)))
(loop 1))
Now you should be able to more easily see the mechanics of a
recursive while loop and use this as a simple template
to apply to other situations.
I hope this helps and I hope it doesn't cross the line
on the "subjective questions" guidelines -- I'm new to
this site and hope to fit in as it looks like a great
resource.

I'm a bit rusty in scheme, I've managed to get this solution to your problem,
it use recursion vs while, but I'm not accustomed to that construct in scheme:
(define data (list (cons 1 1) (cons 1 7)))
(define (neven n) (if (even? n) n (+ n 1)))
(define (sublist a mn mx)
(cond
((<= mn mx ) (cons (cons a mn) (sublist a (+ mn 2) mx)))
(else '())))
(define (game-position input)
(if (= (caar input) (caadr input))
(list (sublist (caar input)
(neven (cdar input))
(cdadr input))
(sublist (caar input)
(+ 1 (neven (cdar input)))
(cdadr input)))
(error "no match")))
(game-position data)
edit: It works in guile and drscheme. Hope it will works in plt-scheme too.
edit: sublist inner working
First the parameters:
a is the car of the pairs contained into the list
mn is the cdr of the first pair
mx is the upper limit of the serie.
the body of the function is quite simple:
if the cdr of the current pair is smaller or equal to the upper limit then return a list
composed by a pair (a . mn) and the list created by a call to sublist with the mn parameter changed to reflect the next possible pair.
if the current pair will have a cdr higher than the upper limit then return null (empty list) in order to close the cons issued by the previous invocation of sublist.

I've been working on learning Racket/Scheme for a while
now and this site looks like a great place to share and
learn from others.
I'm not 100% sure of the spec on this question and
have my doubts that my code actually solves the problem
at hand but I think it's readable enough to be modified
as needed
Readability is one of the things I've been working on
and would appreciate feedback/suggestions from others.
dlm.
My 2 cents :
(define (process-list? lst)
(let*([pair-0 (list-ref lst 0)]
[pair-1 (list-ref lst 1)])
(and (= (car pair-0) (car pair-1))
(< (cdr pair-0) (cdr pair-1)))))
(define (make-odd/even-sets data)
(let*([x (car (list-ref data 0))]
[y-start (cdr (list-ref data 0))]
[max (cdr (list-ref data 1))])
(define (loop y evens odds)
(if (<= y max)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds))
(list (reverse odds) (reverse evens))))
(loop y-start '() '())))
(define (main data)
(if (process-list? data)
(let*([odd/even (make-odd/even-sets data)])
(printf "~a~n" (list-ref odd/even 0))
(printf "~a~n" (list-ref odd/even 1)))
(printf "Invalid list~n" )))
(main '((1 . 1) (1 . 7)) )

Related

Why does this program work on Chez Scheme but fail on Chicken Scheme?

When I run this program at Ideone:
; scrambled words
(define rand ; knuth random number generator with shuffle box
(let* ((a 69069) (c 1234567) (m 4294967296) (k 32) ; 32-bit
; (a 6364136223846793005) (c 1442695040888963407)
; (m 18446744073709551616) (k 256) ; 64-bit
(seed 19380110) ; happy birthday knuth
(next (lambda ()
(set! seed (modulo (+ (* a seed) c) m)) seed))
(init (lambda (seed) (let ((box (make-vector k)))
(do ((j 0 (+ j 1))) ((= j k) box)
(vector-set! box j (next))))))
(box (init seed)))
(lambda args
(if (pair? args)
(set! seed (modulo (car args) m)) (set! box (init seed)))
(let* ((j (quotient (* k seed) m)) (n (vector-ref box j)))
(set! seed (next)) (vector-set! box j seed) (/ n m)))))
(define (randint . args)
(let ((lo (if (pair? (cdr args)) (car args) 0))
(hi (if (pair? (cdr args)) (cadr args) (car args))))
(+ lo (floor (* (rand) (- hi lo))))))
(define (shuffle x)
(do ((v (list->vector x)) (n (length x) (- n 1)))
((zero? n) (vector->list v))
(let* ((r (randint n)) (t (vector-ref v r)))
(vector-set! v r (vector-ref v (- n 1)))
(vector-set! v (- n 1) t))))
(define (scramble str)
(let* ((cs (string->list str))
(upper (map char-upper-case? cs))
(cs (map char-downcase cs)))
(let loop ((cs cs) (word (list)) (zs (list)))
(cond ((null? cs) ; end of input
(list->string
(map (lambda (u? c)
(if u? (char-upcase c) c))
upper (reverse zs))))
((char-alphabetic? (car cs)) ; in a word
(loop (cdr cs) (cons (car cs) word) zs))
((pair? word) ; end of word
(loop cs (list) (append (shuffle word) zs)))
(else ; not in a word
(loop (cdr cs) word (cons (car cs) zs)))))))
(display (scramble "Programming Praxis is fun!")) (newline)
(display (scramble "Programming Praxis is fun!")) (newline)
(display (scramble "Programming Praxis is fun!")) (newline)
I get this error output:
Error: (vector-ref) bad argument type: 1.0
Call history:
<eval> [next] (+ (* a seed) c)
<eval> [next] (* a seed)
<eval> [init] (doloop14 (+ j 1))
<eval> [init] (+ j 1)
<eval> [init] (= j k)
<eval> (quotient (* k seed) m)
<eval> (* k seed)
<eval> (vector-ref box j)
<eval> (next)
<eval> [next] (modulo (+ (* a seed) c) m)
<eval> [next] (+ (* a seed) c)
<eval> [next] (* a seed)
<eval> (vector-set! box j seed)
<eval> (/ n m)
<eval> [randint] (- hi lo)
<eval> [shuffle] (vector-ref v r) <--
Can someone please explain what is going wrong? And how to fix it?
This program generates very large integers. It looks like Ideone is using CHICKEN 4, which did not support arbitrarily large integers ("bignums" in Scheme parlance).
When you get numbers too large to fit a machine word (minus 2 bits), CHICKEN 4 would stuff the number in a floating-point number in order to neatly overflow. That's why you get the vector-ref error.
If ideone supports it, you could try adding (use numbers) at the start of your program. This numbers egg adds support for the full numeric tower (with several caveats) in CHICKEN 4.
CHICKEN 5 supports the full numeric tower out of the box and the program works fine there, unmodified.

Producing a list of lists

I am trying to produce a list of lists which has *.
Here is what I have so far:
(define (position loc count)
(cond [(empty? loc)empty]
[else (cons (list (first loc) count)
(position (rest loc) (add1 count)))]
))
So:
(position (string->list "**.*.***..") 0)
would produce:
(list
(list #\* 0) (list #\* 1) (list #\. 2) (list #\* 3) (list #\. 4) (list #\* 5)
(list #\* 6) (list #\* 7) (list #\. 8) (list #\. 9))
Basically I am trying to get
(list (list (list #\* 0) (list #\* 1))
(list (list #\* 3))
(list (list #\* 5)(list #\* 6) (list #\* 7)))
I thought about using foldr but not sure if that will work. Any help would be appreciated.
It's not exactly a foldr solution though, you need a function that modifies it's behaviour based on prior input in order to group the continuous star characters. Check out my use of a boolean to switch behaviour upon finding a match.
(define (combine-continuous char L)
(let loop ((L L) (acc '()) (continuing? #t))
(cond ((null? L) (list (reverse acc)))
((equal? (caar L) char)
(if continuing?
(loop (cdr L) (cons (car L) acc) #t)
(cons (reverse acc)
(loop (cdr L) (list (car L)) #t))))
(else (loop (cdr L) acc #f)))))
(combine-continuous #\* (position (string->list "**.*.***..") 0))
=->
;Value 19: (((#\* 0) (#\* 1)) ((#\* 3)) ((#\* 5) (#\* 6) (#\* 7)))

Translation of Scheme code for Sierpinski carpet

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))))

string to decimal number in scheme

What is the most transparent and elegant string to decimal number procedure you can create in Scheme?
It should produce correct results with "+42", "-6", "-.28", and "496.8128", among others.
This is inspired by the previously posted list to integer problem: how to convert a list to num in scheme?
I scragged my first attempt since it went ugly fast and realized others might like to play with it as well.
Much shorter, also makes the result inexact with a decimal point, and deal with any +- prefix. The regexp thing is only used to assume a valid syntax later on.
#lang racket/base
(require racket/match)
(define (str->num s)
;; makes it possible to assume a correct format later
(unless (regexp-match? #rx"^[+-]*[0-9]*([.][0-9]*)?$" s)
(error 'str->num "bad input ~e" s))
(define (num l a)
(match l
['() a]
[(cons #\. l) (+ a (/ (num l 0.0) (expt 10 (length l))))]
[(cons c l) (num l (+ (* 10 a) (- (char->integer c) 48)))]))
(define (sign l)
(match l
[(cons #\- l) (- (sign l))]
[(cons #\+ l) (sign l)]
[_ (num l 0)]))
(sign (string->list s)))
Here is a first shot. Not ugly, not beautiful, just longer than I'd like. Tuning another day. I will gladly pass the solution to someone's better creation.
((define (string->number S)
(define (split L c)
(let f ((left '()) (right L))
(cond ((or (not (list? L)) (empty? right)) (values L #f))
((eq? c (car right)) (values (reverse left) (cdr right)))
(else (f (cons (car right) left) (cdr right))))))
(define (mkint L)
(let f ((sum 0) (L (map (lambda (c) (- (char->integer c) (char->integer #\0))) L)))
(if (empty? L) sum (f (+ (car L) (* 10 sum)) (cdr L)))))
(define list->num
(case-lambda
((L) (cond ((empty? L) 0)
((eq? (car L) #\+) (list->num 1 (cdr L)))
((eq? (car L) #\-) (list->num -1 (cdr L)))
(else (list->num 1 L))))
((S L) (let*-values (((num E) (split L #\E)) ((W F) (split num #\.)))
(cond (E (* (list->num S num) (expt 10 (list->num E))))
(F (* S (+ (mkint W) (/ (mkint F) (expt 10 (length F))))))
(else (* S (mkint W))))))))
(list->num (string->list S)))

Matrix addition in Scheme

I am trying to add a matrix and it is not working...
(define (matrix-matrix-add a b)
(map (lambda (row) (row-matrix-add row b))
a))
(define (row-matrix-add row matrix)
(if (null? (car matrix))
'()
(cons (add-m row (map car matrix))
(row-matrix-add row (map cdr matrix)))))
(define (add-m row col)
(if (null? col)
0
(+ (car row)
(car col)
(add-m (cdr row) (cdr col)))))
Here is very short working implementation. Map is good at getting rid of a layer of recursion, when you can use it.
(define (matrix-add x y) (map (lambda (x y) (map + x y)) x y))
Here is a working implementation:
(define (matrix-add m1 m2)
(define (matrix-add-row r1 r2 res-row)
(if (and (not (null? r1)) (not (null? r2)))
(matrix-add-row (cdr r1) (cdr r2)
(cons (+ (car r1) (car r2)) res-row))
(reverse res-row)))
(define (matrix-add-each m1 m2 res)
(if (and (not (null? m1)) (not (null? m2)))
(let ((res-row (matrix-add-row (car m1) (car m2) ())))
(matrix-add-each (cdr m1) (cdr m2) (cons res-row res)))
(reverse res)))
(matrix-add-each m1 m2 ()))
Sample usage and output:
> (matrix-add '((7 2) (3 8)) '((4 8) (0 5)))
((11 10) (3 13))
> (matrix-add '((5 2) (4 9) (10 -3)) '((-11 0) (7 1) (-6 -8)))
((-6 2) (11 10) (4 -11))

Resources