(define-module (dhhieft) #:use-module (srfi srfi-1) #:export (dhhieft string->vowels three-vowels? repeated-char? favorable-string? long-distance-match?)) (define (dhhieft str p2?) (count (lambda (x) x) (map (lambda (str) (favorable-string? str p2?)) (string-split (string-trim-both str char-set:whitespace) #\newline)))) (define (favorable-string? str p2?) "Returns #t or #f depending on if STR meets the requirements defined in the problem definition. If p2? is true, uses the problem two definition of favorable." (let ((gap (if p2? 1 0))) (and (repeated-char? str gap) (if p2? (long-distance-match? str) (and (three-vowels? str) (not (or (string-contains str "ab") (string-contains str "cd") (string-contains str "pq") (string-contains str "xy")))))))) (define (long-distance-match? str) "Given STR, returns #t if a substring of size two is repeated multiple times in STR, non-overlapping." (if (< (string-length str) 3) #f (let loop ((str (substring str 2)) (pair (substring str 0 2))) (cond ((string-contains str pair) #t) ((< (string-length str) 3) #f) (#t (loop (substring str 1) (string-append (substring pair 1) (substring str 0 1)))))))) (define (repeated-char? str gapsize) "Given STR, returns a boolean indicating if the string contains a repeated character. GAPSIZE is the number of characters to skip when making repeated char comparisons." (let loop ((lst (string->list str))) (cond ((>= (1+ gapsize) (length lst)) #f) ((equal? (car lst) (list-ref lst (1+ gapsize))) #t) (#t (loop (cdr lst)))))) (define (three-vowels? str) "Given STR, returns a boolean indicating if the string contains at least three vowels." (>= (string-length (string->vowels (string-downcase str))) 3)) (define (string->vowels str) "Given STR, returns STR with all non-vowel characters removed." (string-filter (char-set #\a #\e #\i #\o #\u) str))