summaryrefslogtreecommitdiff
path: root/trebuchet/t.scm
blob: 8bc7385007ea36ee671afb67775195e37395cc94 (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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
(define-module (t)
  #:use-module (srfi srfi-1)
  #:export (t
	    spelt->numbers
	    starts-with?
	    parse-int
	    replace-elements
	    find-true))


(define numbers '((#\1 . ((#\o #\n #\e) . 3))
		  (#\2 . ((#\t #\w #\o) . 3))
		  (#\3 . ((#\t #\h #\r #\e #\e) . 5))
		  (#\4 . ((#\f #\o #\u #\r) . 4))
		  (#\5 . ((#\f #\i #\v #\e) . 4))
		  (#\6 . ((#\s #\i #\x) . 3))
		  (#\7 . ((#\s #\e #\v #\e #\n) . 5))
		  (#\8 . ((#\e #\i #\g #\h #\t) . 5))
		  (#\9 . ((#\n #\i #\n #\e) . 4))))


(define (t str convert?)
  (apply + (map (lambda (line)
		  (let ((lst (string->list line)))
		    (parse-int
		     (if convert?
			 (spelt->numbers lst)
			 lst))))
		(string-split
		 (string-trim-both str char-set:whitespace)
		 #\newline))))

(define (parse-int lst)
  "Given LST of characters, return a
two-digit integer representing containing
the first and last digits in LST."
  (let ((digits (filter (lambda (x) (char-numeric? x))
			lst)))
    (string->number
     (string (car digits)
	     (last digits)))))

(define (spelt->numbers lst)
  "Loops through the string, replacing
numbers that are spelt-out with their
digit counterparts."
  (let loop ((lst lst) (result '()))
    (if (null? lst)
	result
	(let ((index
	       (find-true
		(map (lambda (num-pair)
		       (starts-with? lst num-pair))
		     numbers))))
	  (when index
	    (set! lst (replace-elements lst (list-ref numbers index))))
	  (loop (cdr lst)
		(append result (list (car lst))))))))

(define (find-true lst)
  "Given LST of boolean values,
returns the index of the first #t value,
or false otherwise."
  (let ((sublist (member #t lst)))
    (if sublist
        (- (length lst) (length sublist))
        #f)))

(define (starts-with? lst num-pair)
  "Returns #t if LST starts with CADR
NUM-PAIR"
  (let ((sub-length (cddr num-pair)))
    (and (>= (length lst) sub-length)
	 (equal? (list-head lst sub-length) (cadr num-pair)))))

(define (replace-elements lst num-pair)
  "Given LST, removes LENGTH elements from
the front and replaces them with CHAR.

As an edit, we should NOT remove ALL letters,
because some letters are shared between
spelt numbers (twone). As a safety, we are
safe always leaving one."
  (cons (car num-pair) (list-tail lst (1- (cddr num-pair)))))