POPL 25 Problems

PUBLIC 2026-01-16 16:45:37
popl iiit

#lang racket

(provide (all-defined-out))

;p1
(define (my-last lst)
  (foldr (lambda (x acc) (if (null? acc) x acc)) null lst))

;p2
(define (my-but-last lst)
  (let ((reversed (my-reverse lst)))
    (cond
      [(null? reversed) '()]
      [(<= (length reversed) 2) lst]
      [else (list (second reversed) (first reversed))])))


;p3
(define (element-at lst k)
  (cond
    [(null? lst) null]
    [(= k 1) (car lst)]
    [else (element-at (cdr lst) (- k 1))]))

;p4
(define (my-length lst)
  (foldl (lambda (x acc) (+ acc 1)) 0 lst))

;p5
(define (my-reverse lst)
  (foldl (lambda (x acc) (cons x acc)) '() lst))

;p6
(define (palindrome? lst)
  (equal? lst (my-reverse lst)))

;p7
(define (my-flatten lst)
  (if (null? lst)
      null
      (if (list? (car lst))
          (append (my-flatten (car lst)) (my-flatten (cdr lst)))
          (cons (car lst) (my-flatten (cdr lst))))))

;p8
(define (compress lst)
  (cond
    [(null? lst) null]
    [(null? (cdr lst)) lst]
    [(equal? (car lst) (car (cdr lst))) (compress (cdr lst))]
    [else (cons (car lst) (compress (cdr lst)))]))

;p9
(define (pack lst)
  (if (null? lst)
      null
      (let ([p (pack (cdr lst))])
        (if (null? p)
            (list (list (car lst)))
            (if (equal? (caar p) (car lst))
                (cons (cons (car lst) (car p)) (cdr p))
                (cons (list (car lst)) p))))))

;p10
(define (encode lst)
  (map (lambda (x) (cons (my-length x) (list (car x)))) (pack lst)))

;p11
(define (encode-modified lst)
  (map (lambda (x) (if (= (my-length x) 1)
                       (car x)
                       (cons (my-length x) (list (car x)))))
       (pack lst)))

;p12
(define (decode lst)
  (apply append (map (lambda (x)
                       (if (pair? x)
                           (make-list (car x) (cadr x))
                           (list x)))
                     lst)))

;p13
(define (encode-direct lst)
  (define (encode-helper lst current count result)
    (cond
      [(null? lst)
       (my-reverse (cons (if (= count 1)
                          current
                          (list count current))
                      result))]
      [(equal? (car lst) current)
       (encode-helper (cdr lst) current (+ count 1) result)]
      [else
       (encode-helper (cdr lst)
                      (car lst)
                      1
                      (cons (if (= count 1)
                                current
                                (list count current))
                            result))]))

  (if (null? lst)
      '()
      (encode-helper (cdr lst) (car lst) 1 '())))

;p14
(define (dupli lst)
  (if (null? lst)
      null
      (cons (car lst) (cons (car lst) (dupli (cdr lst))))))

;p15
(define (repli lst n)
  (if (null? lst)
      null
      (append (make-list n (car lst)) (repli (cdr lst) n))))

;p16
(define (drop lst n)
  (if (= n 1)
      '()
      (let loop ((lst lst) (count 1))
        (cond
          [(null? lst) '()]
          [(= count n) (loop (cdr lst) 1)]
          [else (cons (car lst) (loop (cdr lst) (+ count 1)))]))))

;p17
(define (split lst n)
  (if (null? lst)
      (list null null)
      (if (= n 0)
          (list null lst)
          (let ([s (split (cdr lst) (- n 1))])
            (list (cons (car lst) (car s)) (cadr s))))))

;p18
(define (slice lst i k)
  (if (null? lst)
      null
      (if (or (< k 1) (< i 1))
          null
          (if (<= k 0)
              null
              (if (<= i 1)
                  (cons (car lst) (slice (cdr lst) 1 (- k 1)))
                  (slice (cdr lst) (- i 1) (- k 1)))))))

;p19
(define (rotate lst n)
  (if (null? lst)
      lst
      (let* ((len (length lst))
             (n-normalized (modulo n len))
             (split-result (split lst n-normalized)))
        (append (cadr split-result) (car split-result)))))

;p20
(define (remove-at lst k)
  (if (null? lst)
      null
      (if (= k 1)
          (cdr lst)
          (cons (car lst) (remove-at (cdr lst) (- k 1))))))

;p21
(define (insert-at x lst k)
  (if (null? lst)
      (list x)
      (if (= k 1)
          (cons x lst)
          (cons (car lst) (insert-at x (cdr lst) (- k 1))))))

;p22
(define (my-range i k)
  (if (<= i k)
      (range i (+ k 1))
      (my-reverse (range k (+ i 1)))))

; helper function for p23
(define (list-ref lst i)
  (if (null? lst)
      (error 'list-ref "index out of bounds")
      (if (= i 0)
          (car lst)
          (list-ref (cdr lst) (- i 1)))))

;p23
(define (rnd-select lst n)
  (if (or (null? lst) (= n 0))
      null
      (let* ([len (length lst)]
             [i (random len)]
             [x (list-ref lst i)])
        (cons x (rnd-select (remove-at lst (+ i 1)) (- n 1))))))

;p24
(define (lotto-select n m)
  (if (or (< n 0) (< m 0) (> n m))
      '()
      (rnd-select (my-range 1 m) n)))

;p25
(define (rnd-permu lst)
  (rnd-select lst (length lst)))