(#%require (only racket/base current-inexact-milliseconds))
;; Helpers
(define (range start end)
  (if (> start end)
      '()
      (cons start (range (+ start 1) end))))

(define arglist (range 0 1000))


;; Benchmark parameters
(define step (lambda (x) (* x 2)))
(define start 2)
(define end 70000)

(define (gen-iters start end)
  (if (> start end)
      (list start)
      (cons start (gen-iters (step start) end))))

(define (run-n-times proc n)
  (if (> n 0)
      (begin
        (proc)
        (run-n-times proc (- n 1)))))

(define iters (gen-iters start end))

(define (bench f iterations label)
  (let ((start (current-inexact-milliseconds)))
    (run-n-times f iterations)
    (let ((end (current-inexact-milliseconds)))
      (display "label ,")(display iterations)(display ", ")(display (- end start))(newline))))


(define (benchmark proc iters label)
  (for-each (lambda (iters) (bench proc iters label)) iters))

  
  
;; Jouw versie
(define (merge-n lst1 lst2 n)
  (define (get-sublist lst a)
    (if(or (= a 0) (null? lst))
       '()
       (cons (car lst) (get-sublist (cdr lst) (- a 1)))))
  
  (define (get-remainder lst a)
    (if(or (= a 0) (null? lst))
       lst
       (get-remainder (cdr lst) (- a 1))))
  
  (if (or (null? lst1) (null? lst2))
      (cond
        ((null? lst1) lst2)
        ((null? lst2) lst1))
      (append (get-sublist lst1 n) (get-sublist lst2 n) (merge-n (get-remainder lst1 n) (get-remainder lst2 n) n))))

;; Benchmark
(benchmark (lambda () (merge-n arglist arglist 1)) iters "first version")


;; Andere versie
(define (merge-n lst1 lst2 n)
  (define (get-sublist lst a)
    (if(or (= a 0) (null? lst))
       '()
       (cons (car lst) (get-sublist (cdr lst) (- a 1)))))
  
  (define (get-remainder lst a)
    (if(or (= a 0) (null? lst))
       lst
       (get-remainder (cdr lst) (- a 1))))

  (define (loop lst1 lst2 n)
    (if (or (null? lst1) (null? lst2))
        (cond
          ((null? lst1) lst2)
          ((null? lst2) lst1))
        (append (get-sublist lst1 n) (get-sublist lst2 n) (loop (get-remainder lst1 n) (get-remainder lst2 n) n))))
  (loop lst1 lst2 n))

;; Benchmark
(benchmark (lambda () (merge-n arglist arglist 1)) iters "second version")