blob: b1d92d787fea2cdf957bf36e634c345cde061646 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
(define-module (pp)
#:use-module (srfi srfi-1)
#:export (pp
parse-line
count-occurrences
valid-password-p1?
valid-password-p2?))
(define (pp str p1?)
(count (lambda (x) x)
(map (lambda (line)
(let ((parsed (parse-line line)))
(if p1?
(valid-password-p1? (car parsed)
(cadr parsed)
(caddr parsed))
(valid-password-p2? (car parsed)
(cadr parsed)
(caddr parsed)))))
(string-split
(string-trim-both str char-set:whitespace)
#\newline))))
(define (parse-line str)
"Parses a line of the puzzle format
into a workable datastructure:
(passwd (char (min max)))"
(let* ((fields (string-split str char-set:whitespace))
(range (map string->number (string-split (car fields) #\-)))
(char (string-ref (cadr fields) 0))
(passwd (caddr fields)))
(list passwd
char
(cons (car range)
(cadr range)))))
(define (valid-password-p2? passwd char range)
"Wrapper for valid-password-p1?.
Prepares the input by indexing RANGE
into PASSWD, setting that as the new
PASSWD, and setting RANGE to (1 . 1)
Note the original problem specifies
that strings are NOT zero-indexed!"
(valid-password-p1? (string (string-ref passwd (1- (car range)))
(string-ref passwd (1- (cdr range))))
char
'(1 . 1)))
(define (valid-password-p1? passwd char range)
"Given PASSWD, checks that CHAR appears
within RANGE number of times. RANGE is a
cons pair."
(let ((occurrences (count-occurrences passwd char)))
(and (>= occurrences (car range))
(>= (cdr range) occurrences))))
(define (count-occurrences str char)
"Returns the number of times CHR
appears in STR."
(string-length (string-filter char str)))
|