summaryrefslogtreecommitdiff
path: root/password-philosophy/pp.scm
blob: 9431ffab353d602f173b691dc52682b83dd648c8 (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
(define-module (pp)
  #:use-module (srfi srfi-1)
  #:export (pp
	    parse-line
	    count-occurrences
	    valid-password?))

(define (pp str)
  (count (lambda (x) x)
	 (map (lambda (line)
		(let ((parsed (parse-line line)))
		  (valid-password? (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? 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)))