I am writing a very simple program for Pascal's triangle in scheme (exercise from SICP). I wrote this code and its getting an error message The object () is not applicable.
(define (pascal-triangle n)
(define (get-value list position)
(define (get-sum-iter prevList counter)(
cond
((= counter (- position 1))
(+ (car prevList) (car (cdr prevList))))
(else (get-sum-iter (cdr prevList) (+ counter 1)))
))
(get-sum-iter list 0)
)
(define (create-list prevList size)
(define (create-list-iter currList counter)(
cond
((or (= counter (- size 1))
(= counter 0))
(create-list-iter (cons 1 currList) (- counter 1)))
((> counter 0)
create-list-iter
(cons (get-value prevList counter)
currList)
(- counter 1))
(else currList)
))
(create-list-iter () (- size 1))
)
(define (pascal-triangle-iter resultList counter)
(cond
((> counter n) resultList)
(else
(pascal-triangle-iter
(cons create-list
((cond
((null? resultList) resultList)
(else (car resultList)))
counter)
resultList)
(+ counter 1)))
)
)
(pascal-triangle-iter () 1)
)
In my function definition of pascal-triangle-iter I expect the first parameter to be a list of list. but when I'm calling it I am just passing an empty list and not list of list. My guess is that this is the cause of the error The object () is not applicable But when how do I initialize and empty list of list?
Thanks to everyone specially #barmar and #adabsurdum to helping me. The problem was the my parenthesis were off. The list construction was fine. The following code works fine for me (MIT Scheme on Mac OS)
; pascal triangle recursive
(define (pascal-triangle n)
(define (get-value list position)
(define (get-sum-iter prevList counter)(
cond
((= counter (- position 1)) (+ (car prevList) (car (cdr prevList))))
(else (get-sum-iter (cdr prevList) (+ counter 1)))
))
(get-sum-iter list 0)
)
(define (create-list prevList size)
(define (create-list-iter currList counter)(
cond
((or (= counter (- size 1)) (= counter 0)) (create-list-iter (cons 1 currList) (- counter 1)))
((> counter 0) (create-list-iter (cons (get-value prevList counter) currList) (- counter 1)))
(else currList)
))
(create-list-iter '() (- size 1))
)
(define (emptyOrFirst list)(
cond
((null? list) '())
(else (car list))
))
(define (pascal-triangle-iter resultList counter)
(cond
((> counter n) resultList)
(else (pascal-triangle-iter (cons (create-list (emptyOrFirst resultList) counter) resultList) (+ counter 1)))
)
)
(pascal-triangle-iter '() 1)
)
Related
I am trying to check for balanced parenthesis in scheme with a string as given input but what I have is not working correctly and I do not know why. Any insight on what I need to change? Thanks.
(define (balanced? st)
(define lst (string->list st))
(display lst)
(if (equal? (string-length st) 0)
#t
(counter lst 0)
))
(define (counter lst count)
(cond
((and (= count 0) (= (length lst) 0) #t))
((and (not(= count 0)) (= (length lst) 0) #f))
((equal? (first lst) "(") (counter (cdr lst) (+ count 1)))
((equal? (first lst) ")") (counter (cdr lst) (- count 1)))
(counter (cdr lst) count)
)
)
The last clause of cond needs else as the condition.
(define (counter lst count)
(cond
((and (= count 0) (= (length lst) 0) #t))
((and (not(= count 0)) (= (length lst) 0) #f))
((equal? (first lst) "(") (counter (cdr lst) (+ count 1)))
((equal? (first lst) ")") (counter (cdr lst) (- count 1)))
(else (counter (cdr lst) count))
)
)
Your code has counter as the last condition, then it calls (cdr lst) and discards the value, and returns count.
Here is my version, tested in mit-scheme:
(define balanced
(lambda (input break ret)
(if (null? input)
(ret 'eos)
(if (char=? (car input) #\()
(balanced
(cdr input)
break
(lambda (rest)
(assert
(or (eq? rest 'eos)
(char=? #\) (car rest))))
(if (eq? rest 'eos)
(break)
(balanced (cdr rest) break ret))))
(if (char=? (car input) #\))
(ret input)
(balanced (cdr input) break ret))))))
Here is an unit test:
(define test
(lambda (input)
(display input)
(display " => ")
(balanced
(string->list input)
(lambda ()
(display "error"))
(lambda (rest)
(display (if (eq? rest 'eos) "OK" "error"))))
(newline)))
Input test:
(test "(")
(test ")")
(test "()")
(test "((")
(test "))")
(test ")(")
(test "(abc)")
(test "(a(b)c)")
(test "(")
(test ")")
(test "(a)b)")
(test "(a(b)")
(test "(a(b)c))(")
(test "(a(b)c)()")
% mit-scheme --silent < balanced.scm
( => error
) => error
() => OK
(( => error
)) => error
)( => error
(abc) => OK
(a(b)c) => OK
( => error
) => error
(a)b) => error
(a(b) => error
(a(b)c))( => error
(a(b)c)() => OK
I want to get a list which has nth version deleted from the original list. I could manage following code which is imperative:
(define (list-removeN slist n)
(define outl '())
(for ((i (length slist)))
(when (not (= i n))
(set! outl (cons (list-ref slist i) outl))))
(reverse outl))
What can be the functional equivalent of this? I tried for/list, but I have to insert #f or at that position, removing which is not ideal because #f or may occur at other positions in list also.
You can do it recursively with an accumulator. Something like
#lang racket
(define (remove-nth lst n)
(let loop ([i 0] [lst lst])
(cond [(= i n) (rest lst)]
[else (cons (first lst) (loop (add1 i) (rest lst)))])))
(remove-nth (list 0 1 2 3 4 5) 3)
(remove-nth (list 0 1 2 3) 3)
(remove-nth (list 0 1 2) 0)
This produces
'(0 1 2 4 5)
'(0 1 2)
'(1 2)
You could do it with for/list but this version traverses the list twice because of the length call.
(define (remove-nth lst n)
(for/list ([i (length lst)]
[elem lst]
#:when (not (= i n)))
elem))
There's also split-at, but again this may not be as optimal as it creates two lists and appends them.
(define (remove-nth lst n)
(let-values ([(left right) (split-at lst n)])
(append left (rest right))))
A typical roll your own implementation that is recursive and uses O(n) time and O(n) space.
(define (remove-nth lst i)
(let aux ((lst lst) (i i))
(cond ((null? lst) '()) ;; what if (< (length lst) i)
((<= i 0) (cdr lst)) ;; what if (< i 0)
(else (cons (car lst)
(aux (cdr lst) (sub1 i)))))))
A interative version that uses append-reverse from srfi-1. O(n) time and O(1) space.
(define (remove-nth lst i)
(let aux ((lst lst) (i i) (acc '()))
(cond ((null? lst) (reverse acc)) ;; what if (< (length lst) i)
((<= i 0) (append-reverse acc (cdr lst))) ;; what if (< i 0)
(else (aux (cdr lst) (sub1 i) (cons (car lst) acc))))))
I try to write function which add some number to every element in the list and then makes sum of all this terms.
(define (num-to-sumtup num)
(lambda (tup)
(cond
((null? tup) 0)
(else (+ (car tup) num (num-to-sumtup ())) ;; here I need to get reference on the inner function
is it possible?
You don't need to make it a anonymous procedure. It may have a name in the scope of num-to-sumtup. Here are some examples of ways to do it. The simples way to do this would be to use the rec syntax which is defined in the SRFI-31.
#!r6rs
(import (rnrs base)
(srfi :31))
(define (num-to-sumtup num)
(rec (recur tup)
(cond
((null? tup) 0)
(else (+ (car tup) num (recur (cdr tup)))))))
((num-to-sumtup 10) '(1 2 3 4 5)) ; ==> 65
You can also do this with define:
(define (num-to-sumtup num)
(define (sum-list tup)
(cond
((null? tup) 0)
(else (+ (car tup) num (sum-list (cdr tup))))))
sum-list); we return the locally named procedure
Using higher order procedures and cut from SRFI-26.
#!r6rs
(import (rnrs base)
(rnrs lists) ; fold-left
(srfi :26)) ; cut
(define (num-to-sumtup num)
(lambda (tup)
(fold-left (cut + <> <> num) 0 tup)))
Yes, it is possible. num-to-sumtup Takes a number as argument, and returns a function, that takes a list. So you execute it to get the function, and then execute that function.
(define (num-to-sumtup num)
(lambda (tup)
(cond
((null? tup) 0)
(else
(+ (car tup) num ((num-to-sumtup num) (cdr tup)))))))
;Value: num-to-sumtup
((num-to-sumtup 10) '(1 2 3 4 5))
;Value: 65
In the spirit of sylwester's answer here's another option
(define (num-to-sup num)
(lambda (tup)
(foldl (lambda (x y) (+ num x y)) 0 tup)))
I get NZEC with the following code for INVCNT
; for lists of length > 2 inversions are the same as the number of elements
; against which the first is greater + the inversions of the remaining
(define (inversions l)
(cond ((< (length l) 2) 0)
(else (+ (length (filter (lambda (x) (> (car l) x)) (cdr l)))
(inversions (cdr l))))))
(use-modules (ice-9 rdelim))
(define (call-n-times proc n)
(if (= 0 n)
'()
(cons (proc) (call-n-times proc (- n 1)))))
(define (solve)
(write-line (inversions (call-n-times read (read)))))
(call-n-times solve (read))
Any hints, please?
Filtering accross a very long list can run you into the maximum recusion error (specs say up to ten million) Instead of using '(length (filter ...' use a fold
(define (inversion L)
(let loop ((accumulator 0) (L L))
(if (null? L)
accumulator
(loop
(+ accumulator
(fold
(lambda (init next)
(if (> (car l) next)
(+ init 1)
init))
0
(cdr L)))
(cdr L)))))
Second though this would be easier to read pulling out that fold into it's own function
(define (inversions-from-car L)
(fold
(lambda (init next)
(if (> (car l) next)
(+ init 1)
init))
0
(cdr L)))
(define (inversion L)
(let loop ((accumulator 0) (L L))
(if (null? L)
accumulator
(loop
(+ accumulator
(inversions-from-car L)
(cdr L)))))
This looks like a good problem to play with data structures, because as written, it's n^2 complexity.
I think you can get it down to n(log n)
Say create a sorted tree on the list of value paired with the # of nodes to the left.
for this set
'(2 3 8 6 1) -> '(1 2 3 6 8) ->
(*tree (*entry 3 2 2)
(*tree (*entry 2 1 1)
(*tree (*entry 1 0 1)
()
())
())
(*tree (*entry 8 1 1)
(*tree (*entry 6 0 1)
()
())
()))
*tree and *entry are just type-tage
*tree should have an entry, a left and a right
*entry should have a value, #left, and number)
Start by finding the the FIRST in the orginal list with a zero accumulator
'(2 3 8 6 1)
If the value of the enrty matched to FIRST, add #left to the accumulator
If the value is entry is more than FIRST recurse on the left branch of the tree with accumulator
If the value of the entry is less then FIRST , recurse on the right branch with #left added to the accumulator
If it's a null-tree throw an error
Then you need to update the tree.
If the value of the entry equal to FIRST, mutate the entry to reduce the number by one
If the value is entry is more then FIRST, mutate the entry toreduce #left by one and recurse on the left branch
If the value of the entry is less than first , recurse on the right branch
If it's a null-tree throw an error
You can combine these rules into a single traversal
Additionally add the rule that if #left is 0 and number is zero, then if the right branch is null mutate this tree to the empty-tree else the right-branch.
Here's a rough (untested version of the idea)
(define (rev-sorted-list->count-list L) ;;sort should be resverse of
;; final desired order
(let loop ((value (car L)) (count 1) (L (cdr L)) (acc '()))
(cond ((null? L) '())
((= value (car l))
(loop value (+ 1 count) (cdr L) acc))
(else
(loop (car l) 1 (cdr L) (cons (cons value count) acc))))))
(define (make-tree count c-L)
(let* ((middle (ceiling (+ 1 count) 2))
(left-count (- middle 1))
(right-count (-count middle))
(left (if (= 0 left-count)
null-tree
(make-tree left-count c-L)))
(entry+right
(let loop ((index 1) (L c-L))
(if (= index middle)
L
(loop (+ 1 index) (cdr L)))))
(entry
(make-entry
(caar entry+right)
left-count
(cdar entry+right))))
(build-tree
entry
left
(if (= 0 right-count)
null-tree
(make-tree right-count (cdr entry+right))))))
;;form left branches from starting points
;;;form right from stopping points
;;never mutating c-L or copies
;;if count = 0 then null tree
(define (build-tree entry left right)
(list '*tree entry left right)
(define (entry tree)
(cadr tree)
(define (left-branch tree)
(caddr tree))
(define (right-branch tree)
(cadddr tree))
(define null-tree (list '*tree '()))
(define (null-tree? tree)
(null? (entry tree)))
(define (make-entry value Nleft count)
(let ((vec (make-vector 3)))
(begin (vector-set! vec 0 value)
(vector-set! vec 1 Nleft)
(vector-set! vec 2 count)
vec)))
;;might meessage passing function here
(define (entry-value entry)
(vector-ref entry 0))
(define (entry-Nleft entry)
(vector-ref entry 1))
(define (entry-Nleft-set! entry int)
(vector-set! entry 1 int))
(define (entry-count entry)
(vector-ref entry 2))
(define (entry-count-set! entry int)
(vector-set! entry 2 int))
(define (inversions! Test-List Search-Tree)
(let loop ((acc 0) (L Test-list) (T Search-tree))
(cond ((null? L) acc)
((null-tree? T) (error "null tree "
"in inner loop of inversion!"))
((= (car L) (entry-value (entry T)))
(entry-count-set! (entry T)
(- (entry-count (entry T)) 1))
(if (and (= 0 (entry-count (entry T)))
(= 0 (entry-Nleft (entry T))))
(set-cdr! T (right-branch T))
'skip)
(loop (+ acc (entry-Nleft (entry T)))
(cdr L)
Search-tree))
((< (car L) (entry-value (entry T)))
(entry-Nleft-set! (entry T)
(- (entry-Nleft (entry T)) 1))
(loop acc L (left-branch T)))
((> (car L) (entry-value (entry T)))
(loop (+ acc (entry-Nleft (entry T)))
L
(right-branch T))))))
I'd like to add the even items in a list and have the following algorithm I wrote to achieve the objective.
The error I am getting is:
+: expects type <number> as 2nd argument, given: #<void>; other arguments were: 4
The code:
(define (mylength alist cnt)
(if (null? alist)
0
(if (= (modulo cnt 2) 0)(+ (car alist) (mylength (cdr alist) (+ cnt 1)))))
(if (= (modulo cnt 2) 1)(mylength (cdr alist) (+ cnt 1))))
Could you please advise on the
i) error
ii) logic of the algorithm
Thanks!
First, indent your code properly:
(define (mylength alist cnt)
(if (null? alist) ;
0 ; this section is wasted because
(if (= (modulo cnt 2) 0) ; it's not the last expression
(+ (car alist) (mylength (cdr alist) (+ cnt 1))))) ;
(if (= (modulo cnt 2) 1) ; this if is the last expression, but
(mylength (cdr alist) (+ cnt 1)))) ; if it's false you get #<void>
You shouldn't have if expressions that don't have both the true and false branches. You have to remember that this isn't C, and anything that's not the last expression will be run and then thrown away.
Combine the last two if statements into one if statement:
(define (mylength alist cnt)
(if (null? alist)
0
(if (= (modulo cnt 2) 0)
(+ (car alist) (mylength (cdr alist) (+ cnt 1)))
(mylength (cdr alist) (+ cnt 1)))))
Edit: When I wrote "anything that's not the last expression will be run and then thrown away", I meant:
(begin
(+ 2 2)
(+ 4 1)
(+ 1 0)
(+ 1 1)) => 2
(let ((x 5))
(add1 x)
(+ x 2)
(* x 2)) => 10
((lambda ()
(if #t 3)
(if #f 0 4)
(if #t 2))) => 2
The other answer is completely right, but your interface is not very scheme-y. This is a more common form with tail recursion.
; Assumes given a list of numbers. Returns sum of even indices.
(define (mylength alist)
(let helper ((alist alist) (acc 0))
(cond
((null? alist) acc)
((null? (cdr alist)) (+ acc (car alist)))
(else (helper (cddr alist) (+ acc (car alist)))))))