Scheme code cond error in Wescheme - scheme

Although the following code works perfectly well in DrRacket environment, it generates the following error in WeScheme:
Inside a cond branch, I expect to see a question and an answer, but I see more than two things here.
at: line 15, column 4, in <definitions>
How do I fix this? The actual code is available at http://www.wescheme.org/view?publicId=gutsy-buddy-woken-smoke-wrest
(define (insert l n e)
(if (= 0 n)
(cons e l)
(cons (car l)
(insert (cdr l) (- n 1) e))))
(define (seq start end)
(if (= start end)
(list end)
(cons start (seq (+ start 1) end))))
(define (permute l)
(cond
[(null? l) '(())]
[else (define (silly1 p)
(define (silly2 n) (insert p n (car l)))
(map silly2 (seq 0 (length p))))
(apply append (map silly1 (permute (cdr l))))]))

Another option would be to restructure the code, extracting the inner definitions (which seem to be a problem for WeScheme) and passing around the missing parameters, like this:
(define (insert l n e)
(if (= 0 n)
(cons e l)
(cons (car l)
(insert (cdr l) (- n 1) e))))
(define (seq start end)
(if (= start end)
(list end)
(cons start (seq (+ start 1) end))))
(define (permute l)
(cond
[(null? l) '(())]
[else (apply append (map (lambda (p) (silly1 p l))
(permute (cdr l))))]))
(define (silly1 p l)
(map (lambda (n) (silly2 n p l))
(seq 0 (length p))))
(define (silly2 n p l)
(insert p n (car l)))
The above will work in pretty much any Scheme implementation I can think of, it's very basic, standard Scheme code.

Use local for internal definitions in the teaching languages.
If you post your question both here and at the mailing list,
remember to write you do so. If someone answers here, there
is no reason why persons on the mailing list should take
time to answer there.
(define (insert l n e)
(if (= 0 n)
(cons e l)
(cons (car l)
(insert (cdr l) (- n 1) e))))
(define (seq start end)
(if (= start end)
(list end)
(cons start (seq (+ start 1) end))))
(define (permute2 l)
(cond
[(null? l) '(())]
[else
(local [(define (silly1 p)
(local [(define (silly2 n) (insert p n (car l)))]
(map silly2 (seq 0 (length p)))))]
(apply append (map silly1 (permute2 (cdr l)))))]))
(permute2 '(3 2 1))

Related

Arity Mismatch: where to put parameter

With my code I need to use multiple functions and combine them into one that will evaluate to the nth prime number between a and b. The functions I need to use are gen-consecutive filter value-at-position.
The problem with my code is that with the function gen-consecutive requires 3 parameters a function (f) and a and b which acts as a range, and I am not sure where to put the f argument in my nth-prime-between function.
I keep getting the error "gen-consecutive: arity mismatch" and that it expected 3 arguments (f a b) instead of just 2 arguments (a b)
Here is my code:
(define (nth-prime-between a b n)
(value-at-position filter prime? (gen-consecutive a b)) n)
Here is the other functions:
(define (gen-consecutive f a b)
(if (> a b)
'()
(cons (f a) (gen-consecutive f (+ a 1) b))))
(define (filter f lst)
(cond ((null? lst) '())
((f (car lst))
(cons (car lst) (filter f (cdr lst))))
(else
(filter f (cdr lst)))))
(define (value-at-position lst k)
(cond ((null? lst) lst)
((= k 1) (car lst))
(else (value-at-position (- k 1) (cdr lst)))))
There are 3 mistakes in your program!
I do NOT have a function prime?, therefore I used odd? instead
(define (nth-prime-between a b n)
;; missing parenthesis for the function filter
;; n is value of the function
;; (value-at-position filter odd? (gen-consecutive a b)) n)
(value-at-position (filter odd? (gen-consecutive a b)) n))
;; kill the parameter f
;;
;; (define (gen-consecutive f a b)
;; (if (> a b)
;; '()
;; (cons (f a) (gen-consecutive f (+ a 1) b))))
(define (gen-consecutive a b)
(if (> a b)
'()
(cons a (gen-consecutive (+ a 1) b))))
(define (filter f lst)
(cond ((null? lst) '())
((f (car lst))
(cons (car lst) (filter f (cdr lst))))
(else
(filter f (cdr lst)))))
(define (value-at-position lst k)
(cond ((null? lst) lst)
((= k 1) (car lst))
;; the sequence of (- k 1) and (cdr lst) is wrong
;; (else (value-at-position (- k 1) (cdr lst)))))
(else (value-at-position (cdr lst) (- k 1)))))
(define (odd? N)
(if (= (remainder N 2) 0)
#f
#t))
(nth-prime-between 1 10 3)
The deeper problem with task is:
When you call (nth-prime-between 1000 10000 2),
you must test 9000 numbers with (prime? n). Probably, it is enough to test 10 numbers.
By the way, there exists intervals of any length with no prime numbers in it.
To test a number N with with prime? you need to know the prime numbers less the (square-root N). Where will you store them?
If it is serious task, you can write a program using the sieve of Eratosthenes with a clever stopping condition.

First n elements of a list (Tail-Recursive)

After figuring out the recursive version of this algorithm, I'm attempting to create an iterative (tail-recursive) version.
I'm quite close, but the list that is returned ends up being reversed.
Here is what I have so far:
(define (first-n-iter lst n)
(define (iter lst lst-proc x)
(cond
((= x 0) lst-proc)
(else (iter (cdr lst) (cons (car lst) lst-proc) (- x 1)))))
(if (= n 0)
'()
(iter lst '() n)))
i.e. Calling (first-n-iter '(a b c) 3) will return (c b a).
Could someone suggest a fix? Once again, I'd like to retain the tail-recursion.
note: I'd prefer you not suggest just calling (reverse lst) on the returned list..
You can do the head sentinel trick to implement a tail recursive modulo cons
(define (first-n-iter lst n)
(define result (cons 'head '()))
(define (iter tail L-ns x)
(cond
((= x 0) (cdr result))
((null? L-ns)
(error "FIRST-N-ITER input list " lst " less than N" n))
(else
(begin (set-cdr! tail (list (car L-ns)))
(iter (cdr tail) (cdr L-ns) (- x 1))))))
(iter result lst n))
(first-n-iter '(a b c d e f g h i j k l m n o p q r s t u v w x y z) 8))
;Value 7: (a b c d e f g h)
Also added a cond clause to catch the case where you try to take more elements than are actually present in the list.
You could flip the arguments for your cons statement, list the last (previously first) arg, and change the cons to append
(define (first-n-iter lst n)
(define (iter lst acc x)
(cond
[(zero? x) acc]
[else (iter (cdr lst) (append acc (list (car lst))) (sub1 x))]))
(iter lst empty n))
which will work as you wanted. And if you're doing this as a learning exercise, then I think that's all you need. But if you're actually trying to make this function, you should know that it's been done already-- (take lst 3)
Also, you don't need your if statement at all-- your check for (= x 0) would return '() right away, and you pass in (iter lst '() n) as it is. So the (if (= n 0) ... ) is doing work that (cond [(= x 0)...)' would already do for you.

Scheme - application: not a procedure error

I'm coding a function in scheme but I'm getting a "application: not a procedure;
expected a procedure that can be applied to arguments" error. I assume that I haven't used the conditional statements correctly:
(define find-allocations
(lambda (n l)
(if (null? l)
'()
(cons ((if (<=(get-property (car l) 'capacity) n)
(cons (car l) (find-allocations (- n (get-property (car l) 'capacity)) (cdr l)))
'()))
(if (<=(get-property (car l) 'capacity) n)
(cons (car l) (find-allocations (n (cdr l))))
'())))))
If anyone can point out my error that'd be much appreciated.
Try this:
(define find-allocations
(lambda (n l)
(if (null? l)
'()
(cons (if (<= (get-property (car l) 'capacity) n)
(cons (car l) (find-allocations (- n (get-property (car l) 'capacity)) (cdr l)))
'())
(if (<= (get-property (car l) 'capacity) n)
(cons (car l) (find-allocations n (cdr l)))
'())))))
It's a very common mistake when learning Scheme: writing unnecessary parentheses! Remember: in Scheme a pair of () means function application, so when you write something - anything like this: (f), Scheme tries to apply f as if it were a procedure, in your code you had a couple of places where this was happening:
((if (<=(get-property (car l) 'capacity) n) ; see the extra, wrong ( at the beginning
(find-allocations (n (cdr l)))) ; n is not a function, that ( is also mistaken

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

How to Assign Mulitpule Caulated Value Into List in Scheme

Okay this is my 4th question today on Scheme, still pretty new to Scheme, as I needed for one of my sub-function I asked earlier in the day.
Basically this will return me the difference of 2 lists. Say you've got (1,5) and (5,1) this function should return me 8. As that's the distance between l to w
Here is what I have. Note: if I change the (list (- (car l) (car w))) into (write ..... ) the function will work, but outputs 2 number which I have no idea how to use those number as inputs of my other function.
So I try to put it into list, but doesn't really work out, it returns me with no error but weird stuff
(define (difference l w) ; calc heuristic function estimation
(if (> (car l) (car w))
(list (- (car l) (car w)))
(if (< (car l) (car w))
(list (- (car w) (car l)))))
(if (< (list-ref l 1) (list-ref w 1))
(list (- (list-ref l 1) (list-ref w 1)))
(if (> (list-ref l 1) (list-ref w 1))
(list (- (list-ref w 1) (list-ref l 1)))))
)
Here is the code returned me
> (difference '(9 1) '(3 1))
#<procedure:...0\assigment 2.ss:50:3>
Any ideas? try to use lambda end-up the same thing.
Well first of all, there's a typo in your code...
(lits (- (car w) (car l)))))
should be...
(list (- (car w) (car l)))))
EDIT: Would something like this work?
(define (difference lst1 lst2)
(if (> (car lst1) (car lst2))
(+ (- (car lst1) (car lst2)) (difference (cdr lst1) (cdr lst2)))
(+ (- (car lst2) (car lst1)) (difference (cdr lst1) (cdr lst2))))
)
I know it's an old question, but I just wrote something like this. Here's my solution
(define (difference l1 l2)
(apply + (map abs (map - l1 l2))))

Resources