I've written the following Scheme code:
(define (last-pair list1)
(if (null? cdr list1)
car list1
(last-pair (cdr list1))))
(define (rev list1)
(if (null? list1)
list1
(append (rev (cdr list1)) (list (car list1)))))
in a file called test.scm.
At terminal, I run:
load "test.scm"
Then I try:
(last-pair (list 1 2 3))
;Value 15: (3)
which is correct.
Then I try:
(rev (list 1 2 3))
;Unbound variable: rev
;To continue, call RESTART with an option number:
; (RESTART 4) => Specify a value to use instead of rev.
; (RESTART 3) => Define rev to a given value.
; (RESTART 2) => Return to read-eval-print level 2.
; (RESTART 1) => Return to read-eval-print level 1.
Seems that it's loading my file properly since it loads last-pair, but I'm not sure why I'm getting the above error...
Thanks!
You will need to write
(load "test.scm")
at the repl. Just load "test.scm" probably doesn't load the file.
I think there is a builtin last-pair which makes it confusing that your last-pair example works and the rev one doesn't.
Related
How would you write a procedure that multiplies each element of the list with a given number (x).If I give a list '(1 2 3) and x=3, the procedure should return (3 6 9)
My try:
(define (mul-list list x)
(if (null? list)
1
(list(* x (car list))(mul-list (cdr list)))))
The above code doesnt seem to work.What changes do I have to make ? Please help
Thanks in advance.
This is the text book example where you should use map, instead of reinventing the wheel:
(define (mul-list lst x)
(map (lambda (n) (* x n)) lst))
But I guess that you want to implement it from scratch. Your code has the following problems:
You should not call list a parameter, that clashes with the built-in procedure of the same name - one that you're currently trying to use!
The base case should return an empty list, given that we're building a list as output
We build lists by consing elements, not by calling list
You forgot to pass the second parameter to the recursive call of mul-list
This should fix all the bugs:
(define (mul-list lst x)
(if (null? lst)
'()
(cons (* x (car lst))
(mul-list (cdr lst) x))))
Either way, it works as expected:
(mul-list '(1 2 3) 3)
=> '(3 6 9)
For and its extensions (for*, for/list, for/first, for/last, for/sum, for/product, for/and, for/or etc: https://docs.racket-lang.org/reference/for.html) are very useful for loops in Racket:
(define (ml2 lst x)
(for/list ((item lst))
(* item x)))
Testing:
(ml2 '(1 2 3) 3)
Output:
'(3 6 9)
I find that in many cases, 'for' implementation provides short, simple and easily understandable code.
,i am doing my assignment in Scheme. I am using Scheme MIT Interpreter and https://repl.it/languages/scheme to test my code.
First question is
; - in? procedure takes an element ‘el’ and a list ‘lst’.
; - It returns a boolean value.
; - When el is in lst it returns true, otherwise returns false.
; - Examples:
; (in? 3 ’(2 5 3))
; evaluates to #t
; (in? 2 ’(1 (2) 5))
; evaluates to #f
; - If lst is not a list, it produces an error..
my code is
(define lst())
(define el())
(define in? (lambda (el lst)
(if(null? lst)
#f
(if (eq? (car lst el ))
#t
(in? el cdr lst )))
(error "ERROR")))
(in? 3'(2 5 3))
I got error in MIT Interpreter below
The procedure #[compiled-procedure 13 ("global" #x14) #x14 #x2620cd4] has been called with 3 arguments; it requires exactly 2 arguments. ;To continue, call RESTART with an option number: ;
(RESTART 1) => Return to read-eval-print level 1.
and when i test it in https://repl.it/languages/scheme
i got error like
Error: 2 is not a function [(anon)]
Why i am getting these errors?
Try this:
(define in?
(lambda (el lst)
(if (or (null? lst) (pair? lst))
(if (null? lst)
#f
(if (equal? (car lst) el )
#t
(in? el (cdr lst))))
(error "ERROR"))))
The usual tips apply: be careful with the parentheses, indent correctly your code, use equal? for equality comparisons, notice the correct way to test if the parameter is a list and make sure you understand how to pass parameters to a procedure and how to actually call a procedure. It works as expected now:
(in? 1 '(2 5 3))
=> #f
(in? 3 '(2 5 3))
=> #t
(in? 1 5)
=> ERROR
I tried reversing a list in scheme using the most basic concept I had about cons,cdr,car.
Here,l-orig is the list to be reversed and l-count acts as a counter.
My code goes here:
(define (rev l-orig l-count)
(
if (null? l-count)
(cons l-orig '())
(rev (cons (cdr l-orig) (car l-orig)) (cdr l-count))
)
)
(display (rev '(1 2 3 4 5) '(1 1 1 1 1)))
And the output is (((2 3 4 5) . 1))
Honestly speaking, I am a beginner in lisp and I need a simple help here.
If I intend to use this method, can anyone suggest me a correct way of doing it?
You're attempting to reverse a list using tail recursion, with the help of an accumulator parameter. The best way would be to traverse the original list and cons each of its elements at the head of the accumulator, which will be returned at the end:
(define (rev l-orig l-count)
(if (null? l-orig)
l-count
(rev (cdr l-orig) (cons (car l-orig) l-count))))
Notice that the accumulator starts as an empty list, which is perfect for consing each new element to it:
(rev '(1 2 3 4 5) '())
=> '(5 4 3 2 1)
Oscar's answer is right on. You can use a helper function so you don't need to pass in an empty accumulator every time:
(define (rev xs)
(rev-accum xs '()))
(define (rev-accum xs accum)
(if (null? xs)
accum
(rev-accum (cdr xs) (cons (car xs) accum))))
Racket is giving me a contract violation for the following code:
(define (fringe x)
(append (car x) (fringe (cdr x))))
Any ideas what's wrong with it?
It happens because (car x) is not returning a list (it's hard to tell for sure without knowing the actual value of x that's rising the error). append is an operation defined between two lists. If you want to add an element at the head of a list, use cons instead of append.
This is what I mean:
(append 1 '(2 3))
=> append: expected argument of type <proper list>; given 1
(append '(1) '(2 3))
=> '(1 2 3)
(cons 1 '(2 3)) ; the recommended way!
=> '(1 2 3)
So I have to remove the last element of a list in scheme.
For example, let's say I have a list (1 2 3 4). I need to return:
(1 2 3)
My idea:
reverse(list)
car(list)
reverse(list)
Is there a reverse function in scheme(racket)?
You wrote: "reverse, car, reverse". I believe you meant to write "reverse, cdr, reverse". There's nothing wrong with this solution; it's linear in the size of the list, just like any solution to this that uses the standard lists.
As code:
;; all-but-last: return the list, not including the last element
;; list? -> list?
(define (all-but-last l) (reverse (cdr (reverse l))))
If the multiple traversal of the list or the needless construction of another list copy bothers you, you can certainly avoid it, by writing the thing directly.
Given your almost-solution, I'm going to assume that this isn't homework.
Here's what it would look like, in racket:
#lang racket
(require rackunit)
;; all-but-last : return the list, except for the last element
;; non-empty-list? -> list?
(define (all-but-last l)
(cond [(empty? l) (error 'all-but-last "empty list")]
[(empty? (rest l)) empty]
[else (cons (first l) (all-but-last (rest l)))]))
(check-equal? (all-but-last '(3 4 5))
'(3 4))
There is a reverse, but using it would not be very efficient. I suggest the following recursive function.
(define (remove-last lst)
(if (null? (cdr lst))
'()
(cons (car lst) (remove-last (cdr lst)))))
(remove-last '(1 2 3 4)) ; returns '(1 2 3)
The if checks whether it is at the last element of the list.
SRFI 1 (activate in Racket using (require srfi/1)) has a drop-right function:
(drop-right '(1 2 3 4) 1) ; => (1 2 3)
I would do a recursive function that goes down the list and attaches the element (using cons) if the element after it is not the last, and appends nothing if it isn't.
I haven't done scheme for years though so that's as far as I can go.
Someone can run with how to implement it (unless it's homework then they probably shouldn't!)
I've done something simpler than: reverse(list), car(list), reverse(list) to get the last element, check out:
(define (last-one liste)
(if(null? (cdr liste))
null
(cons (car liste) (last-one (cdr liste)))
)
)
Those who are looking for another way can check this out:
(define (removing-last xx)
(remove (list-ref xx (- (length xx) 1)) xx))
I would write a simple recursion, altering the typical "empty? mylist" base case to "empty? (rest mylist)," so that I can return empty when the input list is only 1 element.
(define (removelast mylist)
(cond
[(empty? (rest mylist)) empty]
[(cons? mylist) (cons (first mylist) (removelast (rest mylist)))]))
(removelast (list 1 2 3 4 5))
By the way, this code is in Racket/PLT Scheme, a subset of Scheme.