2

I've just started to learn Racket and I need to create a procedure that merge two list randomly.

This is my code:

#lang racket
(define merge-randomly
   (lambda (lst1 lst2)
      (cond ((and (null? lst1) (null? lst2)) null)
            ((null? lst1) lst2)
            ((null? lst2) lst1)
            (else
               (cond ((> (random) 0.5) (cons (cons (car lst1) (car lst2)) (merge-randomly (cdr lst1) (cdr lst2))))
                     (else (cons (cons (car lst2) (car lst1)) (merge-randomly (cdr lst1) (cdr lst2))))
               )
            )
      )
   )
)

I need to use with list like these two:

(define l1 '((1 2 3) (7 8 9)))
(define l2 '((4 5 6)))

I need to create a new list like this one:

'((4 5 6) (1 2 3) (7 8 9))

But I get this list:

'(((4 5 6) 1 2 3) (7 8 9))

I'm doing something wrong, probably here, (cons (cons (car lst1) (car lst2)), or here, (cons (cons (car lst2) (car lst1)), at the else instruction in first cond.

How can I get the list I want to get?

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • I'm wondering, is "randomly" what you really want in the end? Functions that branch randomly like this, while they aren't intrinsically bad, they are harder to write Unit Tests for. If you're learning Racket I would recommend writing functions which you can unit-test easily, or even which you can write examples for before writing the body of the function. – Alex Knauth Oct 28 '18 at 14:06
  • @AlexKnauth Thanks for your comment. How can I write unit test for Racket? I'm studying at the university and I'm doing what the professor is asking for. I think that if I append both lists will be good enough. – VansFannel Oct 28 '18 at 14:50
  • The normal way is using [`check-equal?`](https://docs.racket-lang.org/rackunit/api.html#%28def._%28%28lib._rackunit%2Fmain..rkt%29._check-equal~3f%29%29) from RackUnit. – Alex Knauth Oct 28 '18 at 15:05

2 Answers2

1

Your guess is correct. The format for cons is this:

(cons first-element rest-of-the-list)

So, when you use (const '(4 5 6) '(1 2 3)), it returns ((4 5 6) 1 2 3).

The correct format for what you are trying to do would be:

(cons (car lst1) (cons (car ls2) (merge-randomly (cdr lst1) (cdr lst2))))

and similarly for the second case.

Here's what the final function should look like:

(define merge-randomly
   (lambda (lst1 lst2)
      (cond ((and (null? lst1) (null? lst2)) null)
            ((null? lst1) lst2)
            ((null? lst2) lst1)
            (else
               (cond ((> (random) 0.5) (cons (car lst1) (cons (car lst2) (merge-randomly (cdr lst1) (cdr lst2)))))
                     (else (cons (car lst2) (cons (car lst1) (merge-randomly (cdr lst1) (cdr lst2)))))
               )
            )
      )
   )
)
merlyn
  • 2,273
  • 1
  • 19
  • 26
0

The problem is with (cons (cons (car lst1) (car lst2)) ...). Change it to (cons (car lst1) (cons (car lst2) ...).

PS Your closing parentheses are not idiomatically placed.

hkBst
  • 2,818
  • 10
  • 29