I'm debugging the following mit-scheme program through vim with the assistance of slimv.
(define (pascal x)
(define (pascal-iter m n max-len)
(cond ((and (> m 0) (> n 0))
(pascal-iter m (- n 1) max-len)
(beauti-print (pascal-item m n) max-len))
((= n 0) (pascal-iter (- m 1) (- m 1) max-len)
(display "\n")
(print-space (* (- x m) max-len)))
((= m 0) "Done")))
(define (pascal-item m n)
(cond ((= n 1) 1)
((= n m) 1)
(else (+ (pascal-item (- m 1) (- n 1))
(pascal-item (- m 1) n)))))
(define (beauti-print item max-len)
(print-space (floor (- max-len
(/ (num-of-digit item) 2))))
(display item)
(print-space (ceiling (- max-len
(/ (num-of-digit item) 2)))))
(define (num-of-digit n)
(+ (floor (/ (log n) (log 10))) 1) )
;; (print-space 1) -> " "
;; (print-space 1.5) -> " "
(define (print-space n)
(cond ((> n 0) (display " ")
(print-space (- n 1)))
(else (display ""))))
(pascal-iter x x (num-of-digit (pascal-item x (/ x 2)))))
(pascal 10)
When I ran the command :!mit-scheme --load "pascal.scm", a pascal triangle is printed on the screen, so there I can't spot any bug in my program. However, when I executed ,d and tried to run this program in slimv's REPL buffer, I got:
(user)> (pascal 10)
; Evaluation aborted on <unknown reason>
(user)> (+ 40 2) ;; other statements are interpreted as expected
42
(user)>
So, what's the <unknown reason> that prevents my program from running properly? Is it my fault, or a bug of slimv?
This is the relevant part of swank.log:
[-Received-] 0.481893
(:return (:abort "<unknown reason>") 8)
[Actionlist] 0.482347
8: finished :listener-eval
[---Sent---] 0.525237
(:emacs-rex (swank-repl:listener-eval "(pascal 12)
") "(user)" :repl-thread 9)
Related
When I run this , it says ill-formed special form let..
what could be the reason?
Here is the code :
(define (cm m)
(case m
(#\f)
(do ((i 300 (+ i 100)))
((> i 1300))
(let ((x (* i 2))) (let ((y (/ x 2)) (z (+ x 3))))
(display x) (display " ") (display y) (display " ") (display z) )))
((#\a) 'gold)
((#\c) 3)
(else 4)))
As the other commenters have stated, proper indentation will help significantly. I'm not sure what you're trying to achieve, but this compiles and runs fine:
(define (cm m)
(case m
((#\f)
(do ((i 300 (+ i 100)))
((> i 1300))
(let ((x (* i 2)))
(let ((y (/ x 2))
(z (+ x 3)))
(display x)
(display " ")
(display y)
(display " ")
(display z)))))
((#\a) 'gold)
((#\c) 3)
(else 4)))
(cm #\f)
; 600 300 603800 400 8031000 500 10031200 600 12031400 700 14031600 800 16031800 900 18032000 1000 20032200 1100 22032400 1200 24032600 1300 2603
(cm #\a)
; 'gold
I'm learning Scheme using racket. I made the following program but it gives a contract violation error.
expected: (exact-nonnegative-integer? . -> . any/c)
given: '()
The program finds a list of all numbers in an interval which are divisible by 3 or 5.
#lang racket
;;Global Definitions
(define upper-bound 10)
(define lower-bound 0)
;;set-bounds: Int, Int -> ()
(define (set-bounds m n)
(set! upper-bound (max m n))
(set! lower-bound (min m n)))
;;get-numbers: () -> (Int)
(define (get-numbers)
(build-list upper-bound '()))
;;make-list: Int, (Int) -> (Int)
(define (build-list x y)
(cond
[(= x lower-bound) y]
[(= (modulo x 5) 0) (build-list (sub1 x) (cons x y))]
[(= (modulo x 3) 0) (build-list (sub1 x) (cons x y))]
[else (build-list (sub1 x) y)]))
EDIT: I made the changes suggested by Oscar Lopez.
An alternative method can be with the use of for/list to create the list:
(define (build-list ub lst)
(for/list ((i (range lb ub))
#:when (or (= 0 (modulo i 3))
(= 0 (modulo i 5))))
i))
Usage:
(define lb 0)
(build-list 10 '())
Output:
'(0 3 5 6 9)
Edit:
Actually lst is not needed here:
(define (build-list ub)
(for/list ((i (range lb ub))
#:when (or (= 0 (modulo i 3))
(= 0 (modulo i 5))))
i))
So one can call:
(build-list 10)
Following is a modification of the recursion method (uses 'named let'):
(define (build-list2 ub)
(let loop ((x ub) (lst '()))
(cond
[(= x lb) lst]
[(= (modulo x 5) 0) (loop (sub1 x) (cons x lst))]
[(= (modulo x 3) 0) (loop (sub1 x) (cons x lst))]
[else (loop (sub1 x) lst)])))
Also, if you always have to call your function with an empty list '(), you can put this as default in your argument list:
(build-list x (y '()))
Then you can call with simplified command:
(build-list 10)
You should test first the condition where the recursion stops - namely, when x equals the lower-bound:
(define (build-list x y)
(cond
[(= x lower-bound) y]
[(= (modulo x 5) 0) (build-list (sub1 x) (cons x y))]
[(= (modulo x 3) 0) (build-list (sub1 x) (cons x y))]
[else (build-list (sub1 x) y)]))
I wrote a program, that given two numbers that specify a range, should return the number (count) of numbers in that range that represented in octal form consist of a number of identical digits. For example 72->111 meets this criteria, because all the digits are the same. Examples of output:
(hw11 1 8) -> 7,(hw11 1 9) -> 8,(hw11 1 18) -> 9,(hw11 1 65) -> 14, and so on...
My problem is that to be correct my program must define only 2 procedures, and at the moment I have much more than that and have no idea how to make them less. So any help with rewriting the code is welcomed :). The code is below:
(define (count-digits n)
(if (<= n 0)
0
(+ 1 (count-digits (quotient n 10)))))
(define (toOct n)
(define (helper n octNumber i)
(if(<= n 0)
octNumber
(helper (quotient n 8)
(+ octNumber
(* (expt 10 i)
(remainder n 8)))
(+ i 1))))
(helper n 0 0))
(define (samedigits n)
(define (helper n i)
(if (<= n 0)
#t
(if (not (remainder n 10) i))
#f
(helper (quotient n 10) i))))
(helper n (remainder n 10))
)
(define (hw11 a b)
(define (helper a x count)
(if (> a x)
count
(if (samedigits (toOct x))
(helper a (- x 1) (+ count 1))
(helper a (- x 1) count))))
(helper a b 0))
You probably have restrictions and you didn't state which Scheme implementation you're using; the following is an example that has been tested on Racket and Guile:
(define (hw11 a b)
(define (iter i count)
(if (<= i b)
(let* ((octal (string->list (number->string i 8)))
(allc1 (make-list (length octal) (car octal))))
(iter (+ i 1) (if (equal? octal allc1) (+ count 1) count)))
count))
(iter a 0))
Testing:
> (hw11 1 8)
7
> (hw11 1 9)
8
> (hw11 1 18)
9
> (hw11 1 65)
14
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
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have to solve an exercise in functional programming. I solved by iterative schemes, I want to use recursion but not knowing conversion? Can anyone help me k?
Title: N and N of the people, the things i would have done the job performance j A [i] [j]. Find the plan work assignments so that the greatest performance?
Here is code use loop circle
(define (Bai15 N)
(define i 0)
(define j 0)
(define k 0)
(define t 0)
(define ii 0)
(define jj 0)
(define dem 0)
(define MaTrix (make-vector N))
(define Result (make-vector N))
(define Test (make-vector N))
(define Max 0)
(display "a.Nhap ma trận X[1..N][1..N]:")
(newline)
(newline)
(while (< i N)
(set! (vector-ref MaTrix i) (make-vector N))
(set! i (+ i 1))
)
(set! i 0)
(while (< i N)
(set! k (vector-ref MaTrix i))
(while (< j N)
(display "X[")
(display i)
(display "][")
(display j)
(display "]= ")
(set! (vector-ref k j) (read))
(set! j (+ j 1))
)
(newline)
(set! j 0)
(set! i (+ i 1))
)
(newline)
(set! i 0)
(set! j 0)
(while (< i N)
(set! k (vector-ref MaTrix i))
(while (< j N)
(display (vector-ref k j))
(display " ")
(set! j (+ j 1))
)
(newline)
(set! j 0)
(set! i (+ i 1))
)
(set! i 0)
(while (< i N)
(set! (vector-ref Result i) -1)
(set! i (+ i 1))
)
(set! i 0)
(while (< i N)
(set! (vector-ref Test i) -1)
(set! i (+ i 1))
)
(set! i 0)
(while (< i N)
(display (vector-ref Test i))
(set! i (+ i 1))
)
(newline)
(set! k 0)
(set! i 0)
(set! j 0)
(set! t 0)
(set! dem 0)
(while (< t N)
(if (and (not (= t 0)) (= i 0))
(set! jj t)
(set! jj 0))
(while (>= (vector-ref Test jj) 0)
(set! jj (+ jj 1))
)
(display "jj: ")
(display jj)
(newline)
(display "i: ")
(display i)
(newline)
(set! k (+ (vector-ref (vector-ref MaTrix i) jj) k))
(display "k: ")
(display k)
(newline)
(set! (vector-ref Test jj) i)
(set! ii 0)
(display "Test: ")
(while (< ii N)
(display (vector-ref Test ii))
(display " ")
(set! ii (+ ii 1))
)
(newline)
(set! dem (+ dem 1))
(if (= dem N)
(begin
(if (> k Max)
(begin
(set! Max k)
(display "Max: ")
(display Max)
(newline)
(set! ii 0)
(display "Result: ")
(while (< ii N)
(set! (vector-ref Result ii) (vector-ref Test ii))
(display (vector-ref Result ii))
(display " ")
(set! ii (+ ii 1))
)
(newline)
(set! i 0)
(while (< i N)
(set! (vector-ref Test i) -1)
(set! i (+ i 1))
)
(set! i 0)
(set! dem 0)
(set! k 0)
(set! t (+ t 1))))
(begin
(set! i 0)
(while (< i N)
(set! (vector-ref Test i) -1)
(set! i (+ i 1))
)
(set! i 0)
(set! dem 0)
(set! k 0)
(set! t (+ t 1))))
(begin
(set! i (+ i 1))
))
)
(newline)
(display "Divide the work plan: ")
(newline)
(set! i 0)
(while (< i N)
(display "Job ")
(display (+ i 1))
(display " - People ")
(display (+ (vector-ref Result i) 1))
(display " work")
(newline)
(set! i (+ i 1))
)
(display "Effective: ")
(display Max)
)
I want to solve with recursion and logic programming
Learning a completely new language (I.e. Haskell (SASL dialect) or Scheme (Lisp dialect) if you know Java (Algol dialect)) is harder than learning a new dialect of the same language family (I.e. learning Ruby when you know Java or Common Lisp if you know Scheme)
It seems you have proven it's true that you can write Fortran in any language.
while doesn't exist in Scheme, but since I also program Algol dialects I know how it's supposed to work. I guess it's definition is something like:
(define-syntax while
(syntax-rules ()
((_ expr body ...)
(let loop ()
(cond (expr body ... (loop))
(else 'undefined-return))))))
Also your code has lots of (set! (vector-ref ...) new-value) which doesn't work. After fixing this the code still didn't work.
It's not trivial to just transform a project to be functional. It's far easier to start with a problem and begin dividing it in parts using divide and conquer. Not all your code can be functional because that implies you cannot have output nor input. Instead you try keeping display and read in it's own procedures.
Using arrays are a means of optimization. By design they are not functional in Scheme. A functional array would produce a new array and leaving the old as it was when changing elements. I know Racket has arrays like that but not Scheme. It's better if you recuse lists instead.
The pattern you have in your code you initialize a counter with define and increment it's global value in while while checking for a certain limit. For this you can use named let eg. in this code that makes list of list.
(define N 10)
(define init-list (let zero-loop ((n N) (acc '()))
(if (zero? n)
acc ; return the accumulated list
(zero-loop (- n 1) (cons 0 acc))))) ; ==> undefine, init-list is (0 0 ...)
(let lol ((n N)) (acc '())
(if (zero? n)
acc
(lol (- n 1) (cons init-list acc)))) ; ==> ((0 0 0...) ...)
I'm unsure what you program is supposed to do so I'll stop here. You have to start writing Scheme in Scheme. If you are having problems with this you should begin with a tutorial. Perhaps follow the SICP video lectures or if you really want to be good, finish the SICP books exercises. In the video lectures you learn how to make a programming language like Prolog.