Sort procedure in scheme - sorting

How can i write my own Sort procedure in scheme which takes in a procedure and sorts it based on the procedure!
If we can,What is the procedure?
example- (sort '(2 4 9 5 3) >) yields (9 5 4 3 2)
And can anyone suggest a procedure for searching each element of one list in a second list!

It's pretty straightforward. You just give the variable to hold the predicate a name and implement the sort strategy of you liking..
;; implements a 2 element sort
(define (my-sort2 lst <)
(let ((fst (car lst)) (snd (cadr lst)))
(if (< snd fst)
(list snd fst)
lst ))) ; already in correct order
(sort '(1 2) >) ; ==> (2 1)
(sort '(1 2) <) ; ==> (1 2)
In a slightly more advanced sorting algorithm you need not know both (< snd fst) and (< fst scd) so that in the case both are these are false you have the third option that they are the same.
Now run along to find the sorting algorithm that you'd like to implement. For few elements even professional libraries use Insertion sort and often for the larger data sets merge sort or quick sort are good choices.
Many of the sorting algorithms are faster if they are done in fixed sized vectors for longer lists. Thus most libraries actually first makes a mutable vector with the values, does the sort in place, then turns it back into a list. In Scheme implementations like DrRacket you can right click their sort and open the defining file to see how it's done. Needless to say its quite advanced in order to do well in most cases.

Related

Use cons in front of arguments in racket/scheme

I know cons is for building pairs, like (cons 2 (cons 3 empty)), but I don't understand the code here that use cons after empty. Isn't cons built for numbers? How can cons take 2 arguments? If they can take 2 arguments, how does it evaluate them? and can someone please translate the code after [(empty? lst) empty] please.
(define (removed2 lst)
(cond
[(empty? lst) empty]
[(not (member? (first lst) (rest lst)))
(cons (first lst) (removed2 (rest lst)))]
[else (removed2 (rest lst))])
I suggest you read a good book or a tutorial on Scheme, you're asking for explanations of some of the most basic concepts, that should be well-understood before starting to code in Scheme. For instance, this chapter is a great starting point. I'll address your questions:
I know cons is for building pairs, like (cons 2 (cons 3 empty))
Indeed, you can build pairs of anything you want… pairs of numbers, pairs of pairs, you name it.
But I don't understand the code here that use cons after empty.
In this case, empty means the empty list '(). So, we can build a pair where the first element is an atom (a number in this case) and the second is an empty list - and that's how we build proper lists in Scheme!
Isn't cons built for numbers?
No, it's for building pairs of anything, including other pairs.
How can cons take 2 arguments? If they can take 2 arguments, how does it evaluate them?
And why not? as you've already stated, cons is for building pairs. A pair is made up of two things, so cons takes 2 arguments. It evaluates each of them in turn and then sticks them together to form a pair. You should really, really read the documentation.
And can someone please translate the code after [(empty? lst) empty] please
That's just asking if the list we're recursively traversing is empty, if it is, then it returns an empty list - the base case of any recursive procedure that returns a list. The procedure is simply building a list as a result, for that is consing elements to pairs, and the last pair ends with an empty list, producing a proper list. Basically, this is how you build a list in Scheme:
(cons 1 (cons 2 (cons 3 empty)))
=> '(1 2 3)

How to write a scheme procedure for mean and median of a list?

I need to write a basic scheme procedure that can find the median of a list and another for the mean.
This is what I've come up with so far:
Mean:
(define (mean lst)
(if (null? lst) ()
(+ 1 (car lst) (mean (cdr lst))))
I know I need to divide my the length somewhere but not sure how to do so. My thought process for this is to add each element to the stack of the list and then divide my the length of the list?
Median:
I'm not sure where to start for median.I know I need to determine if the list has an odd number of elements or even, so to do that I've come up with
(define (median lst)
(if (integer? (/ (length lst) 2) ;which is the one for even
I don't know if I need another procedure to get me to the middle of the list?
The median procedure was already discussed here.
Calculating the mean is simple, just add all the elements and divide by the length of the list, the only special case to take care of is when the list is empty (because that will lead to a division by zero: the length is zero!), return an appropriate value indicating this.
By now you should definitely know how to add all the elements in a list, check with your instructor in case of doubts, but it's a basic operation, it shouldn't be a problem.

Moving first element moved to the end of the list - Scheme

I am having trouble writing a function that will move the first element to the end of the list every time it is called. I have tried using a combination of reverse and cdr to cut off the elements at either end, but cannot figure out how to add the elements to the correct end. Any help would be appreciated. Thanks!
Correct outcomes:
(first_to_last '(1 2 3))
(2 3 1)
(first-to-last (first-to-last '(1 2 3)))
(3 1 2)
I think you're over-doing the reversing, personally.
What we want is a list consisting of cdr x with car x appended to the end. The one trick here is that car x isn't a list, so we want to convert it to a list before appending it:
(define (first-to-last x) (append (cdr x) (list (car x))))
If you wanted to stick to the fundamentals, cons is the really fundamental way to put things together into lists, but it would be a bit more work. You'd basically end up defining something essentially identical to append in terms of cons. That's pretty easy but kind of pointless, given that append already exists.
Edit: I guess if you want to use reverse for some reason or other, you could do something like this:
(define (first-to-last x) (reverse (cons (car x) (reverse (cdr x)))))
It's a bit longer and strikes me as kind of clumsy, but it ought to work anyway.

Implementing a "Pythonic" map in Scheme: bad idea?

In Scheme, the function (map fn list0 [list1 .. listN]) comes with the restriction that the lists must have the same number of elements. Coming from Python, I'm missing the freedom of Python list comprehensions, which look a lot like map above, but without this restriction.
I'm tempted to implement an alternative "my-map", which allows for lists of differing size, iterating through the first N elements of all lists, where N is the length of the shortest list.
For example, let num be 10 and lst be (1 2 3). With my-map, I hope to write expressions like:
(my-map + (circular-list num) lst)))
And get:
(11 12 13)
I have an easier time reading this than the more conventional
(map + (lambda (arg) (+ num arg)) lst)
or
(map + (make-list (length lst) num) lst)
Two questions:
As a Scheme newbie, am I overlooked important reasons for the restriction on `map`?
Does something like `my-map` already exist in Scheme or in the SRFIs? I did take a look at srfi-42, but either it's not what I'm looking for, or it was, and it wasn't obvious.
First, note that map does allow empty lists, but of course if there's one empty list then all of them should be empty.
Second, have a look at the srfi-1 version of map -- it is specifically different from the R5RS version as follows:
This procedure is extended from its R5RS specification to allow the arguments to be of unequal length; it terminates when the shortest list runs out.
Third, most Scheme programmers would very much prefer
(map (lambda (arg) (+ num arg)) lst)
My guess is that Scheme is different from Python in a way that makes lambda expressions become more and more readable as you get used to the language.
And finally, there are some implementations that come with some form of a list comprehension. For example, in Racket you can write:
(for/list ([arg lst]) (+ num arg))

How to declare a variable inside a Scheme function?

Is it possible to do so? Let's say I want to get the last element of a list, I would create a variable i = 0, and increment it until it equals to length. Any idea? An example would be greatly appreciated.
Thanks,
There are several ways to declare a variable; the cleanest one is let:
(let ((x some-expr))
; code block that uses x
But you don't need this to get the last element of a list. Just use recursion:
(define (last xs)
(if (null? (cdr xs))
(car xs)
(last (cdr xs))))
Note: if you want, you can use a variable to cache cdr's result:
(define (last xs)
(let ((tail (cdr xs)))
(if (null? tail)
(car xs)
(last tail))))
Yes, it's possible to define local variables in scheme, either using let or define inside a function. Using set!, it's also possible to reassign a variable like you imagine.
That being said, you should probably not solve your problem this way. In Scheme it's generally good practice to avoid set! when you don't need to (and in this case you definitely don't need to). Further iterating over a list using indices is usually a bad idea as scheme's lists are linked lists and as such random access O(n) (making the last function as you want to implement it O(n^2)).
So a simple recursive implementation without indices would be more idiomatic and faster than what you're planning to do and as such preferable.

Resources