How to make sublists of a list in Lisp? - list

I want to make sublists of a given list when my first number is lower than my next number. I already wrote something but it's not working, it says 'NIL ist not a real number' I hope someone can help me further
(defun order(lst)
(cond ((null lst) nil)
(t (if (< (car lst) (cadr lst))
(cons (car lst) (cadr lst))) (order (rest lst)))))
(print(order '(1 4 5 12 22 34 7 9 0)))
//Output should be this -->((1 4 5) (12 22 34) (7 9) (0))

Since this seems like homework just some pointers:
Right now you are only forming a new list with cons that is exactly two long. Think about how you want the recursion to go to either extend this new list if necessary or include new elements before "closing" it.
You don't call any further recursion when you find a sorted pair. Your code just ends.
If the two compared elements are NOT sorted you do nothing with the old head, you just drop it. Overall there is no "outer" list generated in the course of your algorithm.
Right now cadr might run into the end of the list. So < will be called on a number and nil which leads to disaster.

Related

In Racket how do i sum the alternating values in a list using recursion

I am writing a function using recursion that is supposed to add the alternating values in a list. It's relatively simple to just write some code to add all the values in the list but I am struggling to only add the alternating values in the list. If possible I would strongly prefer the code written using recursion over higher-order functions for this problem.
My only guess for this problem is to manipulate the length of the list to only add the alternating values of the list or to possibly find a way to only add the odd elements in the list but I have no clue if this is even possible and if it was even possible i would have no clue where to even begin.
This is my code so far
(define (skip-sum L)
(cond
[(empty? L) 0]
[else (+ (first L) (skip-sum (rest L)))]))
This is what the results should look like. As you can see only the odd elements in the lists were summed showing only alternating values in the list were added.
(check-expect (skip-sum (list 4 6 8)) 12)
(check-expect (skip-sum (list 1 3 5 7 9 11)) 15)
(check-expect (skip-sum (list 2 10 4 12 6 14 8 12 10))30)
For instance for the second example the alternating values which were added are 1+5+9=15.
Here is a possibile recursive definition:
(define (skip-sum l)
(cond ((empty? l) 0)
((empty? (cdr l)) (car l))
(else (+ (car l) (skip-sum (cddr l))))))
Note that there are two cases to end the recursion: when the list is empty, or has only one element.
In the recursive case we simply sum the first element of the list with the result of calling the function on the list starting from the third one (and so ignoring the second one). In this way we skip every even element and obtain the correct sum.

Gathering elements in range of Min and Max values from a list in Scheme

I am new to Scheme and not currently using (Racket version), therefore I do not have such built in functions as filter and etc.
My task for now is to get elements out of my inputted list, and take out of it only those that are above my MinValue and below my MaxValue
In my "lst" variable for example I have (2 4 1 6 5 4 7 3)
In my "MinValue" I have 2
In my MaxValue I have 5
So that now after I apply something similar like
(remove (< # minVal) lst)
It technically should give remove and left out:
(2 4 4 3)
But I am getting the error:
READ from #<INPUT CONCATENATED-STREAM #<INPUT STRING-INPUT-STREAM> #<IO TERMINAL-STREAM>>: objects printed as # in view of *PRINT-LEVEL* cannot be read back in
Main questions:
Does Scheme has a specific defined variable like # that is iterating through the list when remove/remove-if functions are used, so I can use it?
Is there is a way to get this to work in such way:
(remove (< # minVal) lst)
Thanks!
tag "homework" should be there, but I cannot create it yet
Almost any Scheme I know of includes a filter procedure, it's not specific to Racket, you should be able to use it (remove is not the right tool for this job).
Simply pass a lambda that receives each element in turn and you can set any condition for determining which elements go in the output list:
(filter (lambda (e) (and (>= e 2) (< e 5)))
'(2 4 1 6 5 4 7 3))
=> '(2 4 4 3)
There is no # variable that iterates through a list and gives you each element in turn, to do that you have to explicitly traverse the list using recursion, or use one of the built-in procedures that expect a list and a lambda - the lambda's parameter represents each of the elements.
If for some reason you are not allowed to use filter, it's easy to implement it from scratch, and again notice that we don't need to use remove, and that pred gets called with each of the elements:
(define (filter pred lst)
(cond ((null? lst) '())
((pred (car lst))
(cons (car lst) (filter pred (cdr lst))))
(else (filter pred (cdr lst)))))

Recursively append the first element of the list to the rest of a list

I am quite new to scheme and I want to take a list such as (1 2 3 4) and send it to a function that will return (4 1 2 3). A second run would return (3 4 1 2) and so on creating a right shifted list with each call to the function.
The first way I figured out to solve this problem is to recursively swap the first and last values of the list. So in scheme I would append the car of the list with the cdr of the list and send the cdr of the list back to my function recursively until only one last swap can be made.
However I am not great with creating recursive functions and I'm having trouble doing it in a new language for me such as scheme. This is what I have tried so far to give an idea of where I want to head.
(define (rShift lst)
(if (null? lst)
'()
(append (cdr lst (car lst))(rShift (cdr lst)))))
The best you can do is take a look at the documentation of your interpreter to see what list functions are available, and construct a solution using them. For example, in Racket using the list procedures will accomplish a straightforward solution:
(define (rShift lst)
(cons ; stick together the solution
(last lst) ; pick the last item
(take lst (sub1 (length lst))))) ; pick all items except the last one
Let's give it a try:
(rShift '(1 2 3 4))
=> '(4 1 2 3)
(rShift (rShift '(1 2 3 4)))
=> '(3 4 1 2)
There are countless ways to solve this problem, I'll leave it to you to find the one that best suits your needs, but remember - always try to solve a problem in terms of the building blocks already at your disposal, and don't reinvent the wheel. Just for fun, here's another way, using reverse:
(define (rShift lst)
(let ((rev (reverse lst)))
(cons (car rev)
(reverse (cdr rev)))))
If you are intent on doing a recursive solution, then you need to ask yourself "what part of the problem can a solve that leaves an identical but smaller part of the problem remaining" and "how do I end the recursion".
For your problem you end the recursion when you have the last element which you then use to add to the front of the list. The problem is that recursing with 'right-shift' can't be sufficient because you need to keep around the list in order to put the last element on its front.
So:
(define (right-shift list)
(if (null? list)
'()
(let shifting ((list list) (result '()))
(if (null? (cdr list))
(cons (car list) (reverse result))
(shifting (cdr list) (cons (car list) result))))))
;; Hey look, it compiles... gosh I love interactive languages.
;; ... and works.
> (right-shift '(1 2 3 4))
(4 1 2 3)
> (right-shift (right-shift '(1 2 3 4)))
(3 4 1 2)

How do I write a procedure that randomly selects a pair from a list?

I'm creating a checkers game and I need a procedure that randomly selects a pair from a list of pairs.
I know its been a while since this question was asked
but maybe its useful for someone somewhere sometime.
You could also do:
(car ;; "car" picks the first element or the "head" of a list
(shuffle ;; well... shuffles
(yourList)))
(define select-random
(lambda (ls)
(let ((len (length ls))) ;; find out how long the list is
(list-ref ls (random len))))) ;; pick one from 0 to the end
A bit more succinctly solution:
(define (select-random my-lst)
(list-ref
my-lst
(random (length my-lst)))
)
> (select-random '(1 2 3 4))
3

Adding an element to List in Scheme

Below is my code which takes a car element of a list(carVal) and an list(initialized to empty) as parameters. I want to append the element to the list but the same is not working.
(define populateValues
(lambda (carVal currVal)
(append currVal(list carVal ))
(display currVal)))
The display shows empty list all the time () . Can anyone help me understand why?
Well, there is append! as a primitive, which solves most of your problems, as noted already, Scheme tends to frown on mutation, it is possible, but typically avoided, so all procedures that mutate have a ! (called a bang) at their end.
Also, set! does not mutate data, it changes an environment, it makes a variable point to another thing, the original data is left unchanged.
Mutating data in Scheme is quite cumbersome, but, to give you my own implementation of append! to see how it is done:
(define (append! lst . lsts)
(if (not (null? lsts))
(if (null? (cdr lst))
(begin
(set-cdr! lst (car lsts))
(apply append! (car lsts) (cdr lsts)))
(apply append! (cdr lst) lsts))))
Note the use of set-cdr!, which is a true mutator, it only works on pairs, it mutates data in memory, unlike `set!'. If a pair is passed to a function and mutated with set-cdr! or set-car!, it is mutated every-where in the program.
This obeys the SRFI append! spec which says that it should be variadic and that it should return an undefined value, for instance.
(define l1 (list 1 2 3 4))
(define l2 (list 2 3 4))
(define l3 (list 3 1))
(append! l1 l2 l3)
l1
l2
l3
Which displays:
(1 2 3 4 2 3 4 3 1)
(2 3 4 3 1)
(3 1)
As visible, append! can take an infinite number of arguments and it mutates them all but the last.
Scheme might not be the ideal language for you though. The use of append! as said before is nonstandard, instead, append is preferred, which does not mutate and is called for its return value. Which I implement as such:
(define (append . lsts)
(cond
((null? lsts) '())
((null? (car lsts)) (apply append (cdr lsts)))
(else (cons (caar lsts) (apply append (cdar lsts) (cdr lsts))))))
> (append (list 1 2 3) (list 4 5 6) (list 'granny 'porn))
(1 2 3 4 5 6 granny porn)
Which shows a more familiar Scheme style in the absence of mutation, heavy use of recursion
and no use of sequencing.
Edit: If you just want to add some elements to a list and not per se join two though:
(define (extend l . xs)
(if (null? l)
xs
(cons (car l) (apply extend (cdr l) xs))))
(define (extend! l . xs)
(if (null? (cdr l))
(set-cdr! l xs)
(apply extend! (cdr l) xs)))
(extend '(0 1 2 3) 4 5 6)
(define list1 '(0 1 2 3))
(extend! list1 4 5 6)
list1
Which does what you expect
append creates a new list, it does not modify an existing one.
This is because in general, Scheme (and Racket in this case) is a language that prefers functional style.
You could get somewhat closer with a set! -- but even that will disappoint you since it will modify only the local binding.
Note that in Racket in particular, lists are immutable, so there's nothing that can change a list.
Furthermore, even if you could modify a list this way, it's a very inefficient way to accumulate long lists, since you have to repeatedly scan the whole list.
Finally, if you have issues at this level, then I strongly recommend going over HtDP
(append foo bar) returns the concatenation of foo and bar. It doesn't change either foo or bar.
You have to update the value of currVal with set!. Your example should have
(set! currVal (append currVal (list carVal))
(display currVal)
You really need to think about what exact functionality you are looking for
If you want to mutate a referenced list in place, then you have to do the equivalent of append! (as noted in the other answers). But that is dangerous, BECAUSE you may have other code that is counting on the list being immutable, and if you are going to do that, your procedure needs to have a ! in the end to flag that danger.
A cheap approximation to what you want to do, in a more functional style, is:
(define (populateValues carVal currVal)
(let ((ll (append currVal (list carVal))))
(display ll)
ll))
Note that it makes a new list, does the append, displays the result, and RETURNS the new list as a value. This is a useful debugging technique if you don't have access to the intermediate value: bind to a varible, display or log it, and then return it.