How to Merge 2 lists into one in racket - scheme

I have 2 dynamic lists that I would like to merge into one.
Say
'(1 2 3 4)
and
'(15 16)
and get
'(1 2 3 4 15 16)
How can this be done?

Use append for this:
(append '(1 2 3 4) '(15 16))
=> '(1 2 3 4 15 16)

Or, if you're merging two sorted lists and need to maintain the ordering in the result list:
(require srfi/1)
(define (merge-sorted-lists lhs rhs #:order (lt? <))
(let loop ((result '())
(lhs lhs)
(rhs rhs))
(cond ((null? lhs) (append-reverse result rhs))
((null? rhs) (append-reverse result lhs))
((lt? (car rhs) (car lhs))
(loop (cons (car rhs) result) lhs (cdr rhs)))
(else
(loop (cons (car lhs) result) (cdr lhs) rhs)))))
Examples:
> (merge-sorted-lists '(1 3 5 7) '(2 4 6 8))
'(1 2 3 4 5 6 7 8)
> (merge-sorted-lists '(7 5 3 1) '(8 6 4 2) #:order >)
'(8 7 6 5 4 3 2 1)

Related

Scheme recursive

Deos anyone know, how I can make this funktion recursive by inserting the function somewhere? I am not allowed to use implemented functions for lists except append, make-pair(list) and reverse.
(: split-list ((list-of %a) -> (tuple-of (list-of %a) (list-of %a))))
(check-expect (split-list (list 1 2)) (make-tuple (list 1) (list 2)))
(check-expect (split-list (list 1 2 3 4)) (make-tuple (list 1 3) (list 2 4)))
(check-expect (split-list (list 1 2 3)) (make-tuple (list 1 3) (list 2)))
(check-expect (split-list (list 1 2 3 4 5)) (make-tuple (list 1 3 5) (list 2 4)))
(check-expect (split-list (list 1 2 3 4 5 6)) (make-tuple (list 1 3 5) (list 2 4 6)))
(define split-list
(lambda (x)
(match x
(empty empty)
((make-pair a empty) (make-tuple a empty))
((make-pair a (make-pair b empty)) (make-tuple (list a) (list b)))
((make-pair a (make-pair b c)) (make-tuple (list a (first c)) (list b (first(rest c))))))))
Code for make-tuple:
(define-record-procedures-parametric tuple tuple-of
make-tuple
tuple?
(first-tuple
rest-tuple))
Here's a way you can fix it using match and a named let, seen below as loop.
(define (split xs)
(let loop ((xs xs) ;; the list, initialized with our input
(l empty) ;; "left" accumulator, initialized with an empty list
(r empty)) ;; "right" accumulator, initialized with an empty list
(match xs
((list a b rest ...) ;; at least two elements
(loop rest
(cons a l)
(cons b r)))
((cons a empty) ;; one element
(loop empty
(cons a l)
r))
(else ;; zero elements
(list (reverse l)
(reverse r))))))
Above we use a loop to build up left and right lists then we use reverse to return the final answer. We can avoid having to reverse the answer if we build the answer in reverse order! The technique used here is called continuation passing style.
(define (split xs (then list))
(match xs
((list a b rest ...) ;; at least two elements
(split rest
(λ (l r)
(then (cons a l)
(cons b r)))))
((cons a empty) ;; only one element
(then (list a) empty))
(else ;; zero elements
(then empty empty))))
Both implementations perform to specification.
(split '())
;; => '(() ())
(split '(1))
;; => '((1) ())
(split '(1 2 3 4 5 6 7))
;; => '((1 3 5 7) (2 4 6))
Grouping the result in a list is an intuitive default, but it's probable that you plan to do something with the separate parts anyway
(define my-list '(1 2 3 4 5 6 7))
(let* ((result (split my-list)) ;; split the list into parts
(l (car result)) ;; get the "left" part
(r (cadr result))) ;; get the "right" part
(printf "odds: ~a, evens: ~a~n" l r))
;; odds: (1 3 5 7), evens: (2 4 6)
Above, continuation passing style gives us unique control over the returned result. The continuation is configurable at the call site, using a second parameter.
(split '(1 2 3 4 5 6 7) list) ;; same as default
;; '((1 3 5 7) (2 4 6))
(split '(1 2 3 4 5 6 7) cons)
;; '((1 3 5 7) 2 4 6)
(split '(1 2 3 4 5 6 7)
(λ (l r)
(printf "odds: ~a, evens: ~a~n" l r)))
;; odds: (1 3 5 7), evens: (2 4 6)
(split '(1 2 3 4 5 6 7)
(curry printf "odds: ~a, evens: ~a~n"))
;; odds: (1 3 5 7), evens: (2 4 6)
Oscar's answer using an auxiliary helper function or the first implementation in this post using loop are practical and idiomatic programs. Continuation passing style is a nice academic exercise, but I only demonstrated it here because it shows how to step around two complex tasks:
building up an output list without having to reverse it
returning multiple values
I don't have access to the definitions of make-pair and make-tuple that you're using. I can think of a recursive algorithm in terms of Scheme lists, it should be easy to adapt this to your requirements, just use make-tuple in place of list, make-pair in place of cons and make the necessary adjustments:
(define (split lst l1 l2)
(cond ((empty? lst) ; end of list with even number of elements
(list (reverse l1) (reverse l2))) ; return solution
((empty? (rest lst)) ; end of list with odd number of elements
(list (reverse (cons (first lst) l1)) (reverse l2))) ; return solution
(else ; advance two elements at a time, build two separate lists
(split (rest (rest lst)) (cons (first lst) l1) (cons (second lst) l2)))))
(define (split-list lst)
; call helper procedure with initial values
(split lst '() '()))
For example:
(split-list '(1 2))
=> '((1) (2))
(split-list '(1 2 3 4))
=> '((1 3) (2 4))
(split-list '(1 2 3))
=> '((1 3) (2))
(split-list '(1 2 3 4 5))
=> '((1 3 5) (2 4))
(split-list '(1 2 3 4 5 6))
=> '((1 3 5) (2 4 6))
split is kind of a de-interleave function. In many other languages, split names functions which create sublists/subsequences of a list/sequence which preserve the actual order. That is why I don't like to name this function split, because it changes the order of elements in some way.
Tail-call-rescursive solution
(define de-interleave (l (acc '(() ())))
(cond ((null? l) (map reverse acc)) ; reverse each inner list
((= (length l) 1)
(de-interleave '() (list (cons (first l) (first acc))
(second acc))))
(else
(de-interleave (cddr l) (list (cons (first l) (first acc))
(cons (second l) (second acc)))))))
You seem to be using the module deinprogramm/DMdA-vanilla.
The simplest way is to match the current state of the list and call it again with the rest:
(define split-list
(lambda (x)
(match x
;the result should always be a tuple
(empty (make-tuple empty empty))
((list a) (make-tuple (list a) empty))
((list a b) (make-tuple (list a) (list b)))
;call split-list with the remaining elements, then insert the first two elements to each list in the tuple
((make-pair a (make-pair b c))
((lambda (t)
(make-tuple (make-pair a (first-tuple t))
(make-pair b (rest-tuple t))))
(split-list c))))))

Scheme: car and cdr

I'm reading this book:
http://www.shido.info/lisp/scheme3_e.html
I'm stuck on this exercise:
(car '((1 2 3) (4 5 6)))
The thing is, from my understanding, I must understand how do we get ((1 2 3) (4 5 6)) to get (car '((1 2 3) (4 5 6))) because car evaluates the first address.
I tried a few times but cannot get the exact "string" (I don't even know how to call them):
(cons (cons 1 (cons 2 (cons 3 '()))) (cons 4 (cons 5 (cons 6 '()))))
gives me
{{1 2 3} 4 5 6}
(cons (cons (cons 1 (cons 2 (cons 3 '()))) '()) (cons 4 (cons 5 (cons 6 '()))))
gives me
{{{1 2 3}} 4 5 6}
(cons (cons (cons 1 (cons 2 (cons 3 '()))) '()) (cons (cons 4 (cons 5 (cons 6 '()))) '()))
gives me
{{{1 2 3}} {4 5 6}}
At least I'm getting brackets for both parts...
The thing is, if each time I call car to get the first address, I need to formulate the result in my head to see the other side of the mountain, this seems to be an extremely difficult language to me...so I hope I'm wrong.
'((1 2 3) (4 5 6)) is (cons (cons 1 (cons 2 (cons 3 '()))) (cons (cons 4 (cons 5 (cons 6 '()))) '()))
> (cons (cons 1 (cons 2 (cons 3 '()))) (cons (cons 4 (cons 5 (cons 6 '()))) '()))
'((1 2 3) (4 5 6))
If we replace the inner lists with symbols because their value does not matter we get:
(car '((1 2 3) (4 5 6)))
(car '(X Y))
(car (cons 'X (cons 'Y '())))
Which by the reduction (car (cons A B)) => A produces 'X so the result is (cons 1 (cons 2 (cons 3 '()))) or '(1 2 3)

How to split a list into two parts in Scheme

Example: (split '(1 2 3 4) '3)
the Answer should be: ((1 2 3) 4)
The function required 1 list and 1 number, the output should be nested list
the nested list consist of all elements of "mylist" which are equal or less than the "num", and the greater number should be on the right of the list.
I tried but out put is only one list:
(define (split mylist num)
(cond
((null? mylist)'())
((list? (car mylist))(split(car mylist) num))
((> (car mylist) num)(split(cdr mylist) num))
(else(cons (car mylist) (split(cdr mylist) num)))))
A simple solution:
(define (split-list xs y)
(define (less x) (<= x y))
(define (greater x) (> x y))
(list (filter less xs)
(filter greater xs)))
An alternative:
(define (split-list xs y)
(define (less x) (<= x y))
(define-values (as bs) (partition less xs))
(list as bs))
(split-list '(1 2 3 4) 3)
Here's one possible solution, using built-in procedures in Racket:
(define (split mylist num)
(cons
(takef mylist (lambda (n) (<= n num)))
(dropf mylist (lambda (n) (<= n num)))))
For example:
(split '(1 2 3 4) 3)
=> '((1 2 3) 4)
(split '(1 2 3 4 5) 3)
=> '((1 2 3) 4 5)
This is roll your own version using named let. It makes one pass through the data and the result is in reverse order since it's the most effective.
(define (binary-bucket-sort lst threshold)
(let loop ((lst lst) (less-equal '()) (greater '()))
(cond ((null? lst)
(cons less-equal greater))
((<= (car lst) threshold)
(loop (cdr lst) (cons (car lst) less-equal) greater))
(else
(loop (cdr lst) less-equal (cons (car lst) greater))))))
(binary-bucket-sort '(1 5 9 2 6 10 3 7 9 8 4 0) 5)
; ==> ((0 4 3 2 5 1) . (8 9 7 10 6 9))
If you're comfortable with some of the more functional constructs in Racket, such as curry and the like, you can use this rather compact approach:
(define (split-list xs y)
(call-with-values (thunk (partition (curry >= y) xs)) cons))
> (split-list '(1 2 3 4 5 6 7) 3)
'((1 2 3) 4 5 6 7)

How to make two lists, one with even numbers and one with odd numbers, in scheme?

I have a problem.
For example:
We have one unsorted list:
(1 4 5 3 6 7)
Can you help me make 2 lists?
One odd numbered, increasing list:
(1 3 5 7)
and the other even numbered, decreasing list:
(6 4)
Don't use sort!
(define (split filter lst)
(let loop ((a '()) (b '()) (lst lst))
(if (null? lst)
(values a b)
(let ((cur (car lst)))
(if (filter cur)
(loop (cons cur a) b (cdr lst))
(loop a (cons cur b) (cdr lst)))))))
(split odd? '(1 2 3 4 5 6 7 8 9 10))
; ==> (9 7 5 3 1), (10 8 6 4 2)
Now, to make one that separates odds from evens and in a specific order would be simple.

Project for the game 'Oware'

I have a project about the game "Oware", we are supposed to write the game in the program Dr.Racket.
These are the rules for the game, they explain it pretty well, illustrating with pictures: http://www.awale.info/jugar-a-lawale/les-regles-de-lawale/?lang=en
Im kinda stuck on the first exercise, i have the method, but its not giving the numbers in the right order.
The first function we have to write is called "distribute" which should re-put x grains in the holes, giving the result in a form of a list consisting of the number of grains rest and the new numbers for the holes.
This is whats expected:
(distribute 5 '(2 3 1 5 5 2)) -> (0 (3 4 2 6 6 2))
(distribute 5 '(2 3 1)) -> (2 (3 4 2))
What I wrote:
(define distribue
(lambda (n l)
(if (or (= n 0) (null? l))
(list l n)
(cons (+ (car l) 1) (distribue (- n 1) (cdr l))))))
What it gives:
(distribue 5 '(2 3 1 5 5 2)) -> (3 4 2 6 6 (2) 0)
(distribue 5 '(2 3 1)) -> (3 4 2 () 2)
I was trying to change the list cons append, but never got the expected form of answer
How about
(define (distribue n l)
(define (iterator n p q)
(if (or (= n 0) (null? q))
(list n (append p q))
(iterator (- n 1) (append p (list (+ 1 (car q)))) (cdr q))))
(iterator n '() l))
where
(distribue 5 '(2 3 1 5 5 2))
(distribue 5 '(2 3 1))
returns
'(0 (3 4 2 6 6 2))
'(2 (3 4 2))
as required.

Resources