You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
1.9 KiB
Scheme

(define-module (deliberate utils)
#:use-module (srfi srfi-1)
#:export (const-list range reorder string-count zip))o
(define (const-list length value)
(if (= length 0)
'()
(cons value (const-list (- length 1) value))))
;; Return a list of integers in the half-open interval [low, high)
(define (range low high)
(if (eq? low high)
'()
(cons low (range (+ 1 low) high))))
;; Combine lists component-wise
;; Similar to python zip()
;;
;; Parameters:
;; args: Any number of lists
;;
;; Returns:
;; A list. The nth element is a list of the
;; nth elements of each argument
;;
(define (zip . args)
(if (or (nil? args) (memq '() args))
'()
(cons (map car args)
(apply zip (map cdr args)))))
;; Reorder one list by another
;; A reordering is applied to lst such that the same reordering would
;; Put rank in asending oder.
;;
;; Parameters:
;; lst: The list to reorder
;; ranks: The list to sort by
;;
;; Returns:
;; A reordered copy of lst
;;
(define (reorder lst ranks)
(let* ((pairs (zip lst ranks))
(ranked-pairs
(filter (lambda (pair) (not (eq? #f (cadr pair))))
pairs))
(sorted-pairs
(sort ranked-pairs (lambda (a b) (< (cadr a) (cadr b))))))
(map car sorted-pairs)))
;; Same as string-count but assumes parameter is sorted
(define (string-count-sorted sorted)
(if (nil? sorted)
'()
(let* ((elt (car sorted))
(total-length (length sorted))
(rest (find-tail (lambda (x) (not (equal? x elt))) sorted))
(rest-length (if rest (length rest) 0)))
(cons (cons elt (- total-length rest-length))
(string-count-sorted rest)))))
;; Counts the number of times each string appears in a list
;;
;; Parameters:
;; values: The list
;;
;; Returns:
;; An alist of the form ((string1 . count1) ...)
;;
(define (string-count values)
(let ((sorted (sort values string<)))
(string-count-sorted sorted)))