-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterface.scm
172 lines (144 loc) · 6.76 KB
/
interface.scm
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
;; This code is a direct interface to the computational portion of the code. Certain definitions like compute-with-output are designed to be run in a while loop that checks for user input.
;; all functions that have references to functions or values defined in dio-3d will mention them in the comment immediately above it
(load "./diophantine-3d.scm")
(use-srfis `(1))
(define helpstring
"Incorrect command. Currently supported commands are:
\tc : display where we're at
\tv : toggle verbosity, at the cost of slowing down
\tanything else: display this message. It's free!\n")
;; return the victorystring
(define (victorystring victorylist)
(format #f "Hooray! ~a yields ~a! Back to work.\n" victorylist solution))
;; given an attempt, display the result of the attempt, and return the comparison to the solution defined in dio-3d. needs to be generalized to write to any port (aka not using straight up display)
;; sum-list is sourced from dio-3d
;; solution is sourced from dio-3d
(define (verbose-attempt cubed-list)
(let ((result (sum-list cubed-list))) ; don't get confused here...
(display (format #f "\tTrying ~a yields ~a\n" cubed-list result))
(= result solution)))
;; given a list fresh from our enumerator, cube it, generate the coefficient family, and see if any attempt satisfies the predicate. return the result of the find attempt (if it's not false, then we've found an attempt)
;; this function is partly the reason we don't consolidate all these attempt procedures into one generic one, the family of solutions line can't be encapsulated well, and is relatively necessary
;; list-generate is sourced from dio-3d
(define (verbose-lump-attempt root-list)
(let ((attempt-list (list-generate root-list)))
(display (format #f "Attempting family of solutions for ~a\n" root-list))
(find
(lambda (attempt)
(verbose-attempt attempt))
attempt-list)))
;; given a list, display the result of the attempt ONLY if it is between the interval [-epsilon, +epsilon]
(define epsilon 100)
(define (semi-verbose-attempt cubed-list)
(let ((result (sum-list cubed-list)))
(if (> epsilon
(abs result))
(display (format #f "Trying ~a yields ~a\n" cubed-list result)))
(= result solution)))
(define (semi-verbose-lump-attempt root-list)
(let ((attempt-list (list-generate root-list)))
(find
(lambda (attempt)
(semi-verbose-attempt attempt))
attempt-list)))
;; quiet calculation
;; sum-list is sourced from dio-3d
(define (silent-attempt some-list)
(= solution
(sum-list some-list)))
;; calls quiet-attempt for each list in attempt-list, generated by list-generate in a similar manner as verbose-lump-attempt
(define (silent-lump-attempt root-list)
(let ((attempt-list (list-generate root-list)))
(find
(lambda (attempt)
(silent-attempt attempt))
attempt-list)))
(define input-port (standard-input-port))
;; big function. given parameters, check for input on the input-port (above) apply the list-procedure to the current list, with the comparison, then if it returns false, try again with a new list as defined by inc-list
;; parameters are:
;; a procedure that takes a list and a value and returns a boolean
;; the value (applied to the above proc)
;; a list
;; a procedure that takes a list and returns a new one (that can also be applied to this proc)
;; needs to also take an input/output port. wondering if that's a performance hit.
;; this function is tail-calling, but generalized. this isn't actually used at all, but I thought it was a neat solution, so I'll keep it here until i'm finished or it bothers me enough.
(define (try-until-input list-procedure compared-value current-list inc-list)
(cond ((char-ready? input-port)
(handle-input (read input-port)
(list list-procedure
compared-value
current-list
inc-list))) ; pass over control to handle-input, with a list of state
((list-procedure current-list compared-value)
(display (victorystring current-list))) ; we win!
(else
(try-until-input
list-procedure
compared-value
(inc-list current-list)
inc-list)))) ; try again with another list
;; using inc-3-pivot-list from dio-3d, verbose checks for input, then checks if verbose-lump-attempt returns #t, at which point we've found a solution, display it, and stop. otherwise call itself again with the list specified from increment-3-pivot-list.
(define (verbose-try-until-input current-list)
(cond ((char-ready? input-port)
(handle-input current-list))
((verbose-lump-attempt current-list)
(display (victorystring current-list)))
(else
(verbose-try-until-input
(increment-3-pivot-list current-list)))))
;; given a list, only display its result if the result falls under the defined epsilon. the epsilon is defined immediately above semi-verbose-attempt
(define (semi-verbose-try-until-input current-list)
(cond ((char-ready? input-port)
(handle-input current-list))
((semi-verbose-lump-attempt current-list)
(display (victorystring current-list)))
(else
(semi-verbose-try-until-input
(increment-3-pivot-list current-list)))))
;; silent try-until-input loop.
(define (silent-try-until-input current-list)
(cond ((char-ready? input-port)
(handle-input current-list))
((silent-lump-attempt current-list)
(display (victorystring current-list)))
(else
(silent-try-until-input
(increment-3-pivot-list current-list)))))
;; one-off-loop
;; calls verbose-lump-attempt on the list passed, if it returns true, we're done.
;; if it returns false, then go back to silently attempting solutions.
(define (one-off-loop current-list)
(if (verbose-lump-attempt current-list)
(display (victorystring current-list))
(silent-try-until-input (increment-3-pivot-list current-list))))
;; display the helpstring, then silently resume computing
(define (help-me current-list)
(display helpstring)
(silent-try-until-input current-list))
;; mapping of signals to procedures. all of these procedures check for input every time they're run, and call themselves.
(define signal-proc-pairing
(list
(list `v verbose-try-until-input)
(list `c one-off-loop)
(list `q silent-try-until-input)
(list `e semi-verbose-try-until-input)
))
(define (search-signal-proc-pairing signal)
(find
(lambda (signal-proc-pair)
(eq? signal
(car signal-proc-pair)))
signal-proc-pairing))
(define (find-proc-from-signal signal)
(let ((proc-pair (search-signal-proc-pairing signal)))
(if proc-pair
(cadr proc-pair)
#f)))
;; only gets called when char-ready? on input port holds true, so there should be no hanging
(define (handle-input state)
(let ((signal (read input-port)))
(drain-input input-port) ; annoying that I have to put this here...
(let ((proc (find-proc-from-signal signal)))
(if proc
(proc state)
(help-me state)))))