use-modules : ice-9 pretty-print . #:select : pretty-print . pp ice-9 rdelim srfi srfi-1 srfi srfi-26 srfi srfi-197 define : pipe . fs cond : null? fs lambda args : apply values args : null? : cdr fs car fs else lambda args fold lambda (f acc) (f acc) apply (car fs) args cdr fs define : string-paras input define : combine line acc let : new? : car acc paras : cdr acc if : string-null? line cons #t paras if : or new? : null? paras cons #f : cons (list line) paras cons #f : cons (cons line (car paras)) (cdr paras) chain string-split input #\newline fold combine (cons #t '()) _ cdr _ filter (compose not null?) _ map reverse _ reverse _ define : prep input define : list->pair xs cons (car xs) (cadr xs) define : go db let : ranges : car db ids : map string->number : cdr db chain . ranges map pipe cut string-split <> #\- cut map string->number <> . list->pair . _ cons _ ids chain string-paras input list->pair _ go _ define : merge ranges define : cmp p r let : pl : car p pr : cdr p rl : car r rr : cdr r cond : = pl rl < pr rr else : < pl rl define : combine range stack if : null? stack cons range stack let* : l : car range r : cdr range prev : car stack prevl : car prev prevr : cdr prev if : < (+ prevr 1) l cons range stack cons (cons prevl (max prevr r)) (cdr stack) chain sort ranges cmp fold combine '() _ reverse _ define : all-fresh-ids ranges define : width range chain (- (cdr range) (car range)) (+ 1 _) chain map width ranges apply + _ define : main args let* : db : prep : read-delimited "" ranges : car db ids : cdr db pp : all-fresh-ids : merge ranges main : command-line