102.scm 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. ;; Triangle containment
  2. (use-modules (srfi srfi-1))
  3. (use-modules (rnrs io ports))
  4. (use-modules (ice-9 receive))
  5. ;; Question: should I show the outer or inner function below?
  6. (define (triangle-containment file)
  7. (length (filter contains-origin? (make-triangles file))))
  8. (define (containment-test triangle)
  9. (contains-origin? triangle))
  10. (define (contains-origin? triangle)
  11. (define
  12. (outer-loop sides axis-list)
  13. (newline)
  14. (display "(outer) axis-list: ")
  15. (display axis-list)
  16. (newline)
  17. (if (null? sides)
  18. axis-list
  19. (outer-loop (cdr sides)
  20. (inner-loop (car sides) axis-list))))
  21. (define
  22. (inner-loop side axis-list)
  23. (newline)
  24. (display "(inner) axis-list: ")
  25. (display axis-list)
  26. (newline)
  27. (cond
  28. ((null? axis-list) '())
  29. ((and (list? (car axis-list))
  30. (intersects? (car axis-list) side))
  31. (cons #t (inner-loop side (cdr axis-list))))
  32. (else (cons (car axis-list) (inner-loop side (cdr axis-list))))))
  33. (define (solution-interpreter solns)
  34. (fold (lambda (soln acc)
  35. (if (list? soln)
  36. (and acc #f)
  37. (and acc #t)))
  38. #t
  39. solns))
  40. (solution-interpreter (outer-loop (get-sides triangle) axis-list)))
  41. (define origin '(0 0))
  42. (define (intersects? axis line-seg)
  43. (let ((intersection-point (get-intersection-point axis line-seg)))
  44. (if (null? intersection-point)
  45. (and (coincident? axis line-seg)
  46. (within-bounds? origin axis line-seg))
  47. (within-bounds? intersection-point axis line-seg))))
  48. (define (line-line-intersection l1 l2)
  49. (letrec ((x1 (car (car l1))) ; TODO: use get-points function here
  50. (y1 (cadr (car l1)))
  51. (x2 (car (cadr l1)))
  52. (y2 (cadr (cadr l1)))
  53. (x3 (car (car l2)))
  54. (y3 (cadr (car l2)))
  55. (x4 (car (cadr l2)))
  56. (y4 (cadr (cadr l2)))
  57. (denom (- (* (- x1 x2) (- y3 y4))
  58. (* (- y1 y2) (- x3 x4)))))
  59. (newline)
  60. (display "l1, l2: ")
  61. (display (list l1 l2))
  62. (newline)
  63. (display "x1->y4: ")
  64. (display (list x1 x2 x3 x4 y1 y2 y3 y4))
  65. (newline)
  66. (display "denom: ")
  67. (display denom)
  68. (newline)
  69. (if (= 0 denom)
  70. '() ; Note we will have more logic to handle this case
  71. ;; TODO: clean this up...
  72. (list (exact->inexact (/ (- (* (- (* x1 y2)
  73. (* y1 x2))
  74. (- x3 x4))
  75. (* (- (* x3 y4)
  76. (* y3 x4))
  77. (- x1 x2)))
  78. denom))
  79. (exact->inexact (/ (- (* (- (* x1 y2)
  80. (* y1 x2))
  81. (- y3 y4))
  82. (* (- (* x3 y4)
  83. (* y3 x4))
  84. (- y1 y2)))
  85. denom))))))
  86. (define get-intersection-point line-line-intersection)
  87. ;; Intersection point tests...
  88. (display (get-intersection-point
  89. (list '(0 1) '(0 2))
  90. (list '(-340 495) '(-153 910))))
  91. ;; This should be 3
  92. (display (get-intersection-point
  93. (list '(0 0) '(0 1))
  94. (list '(-2 1) '(-1 2))))
  95. ;; This should be 3
  96. (display (get-intersection-point
  97. (list '(0 1) '(0 2))
  98. (list '(2 1) '(1 2))))
  99. (display (get-intersection-point
  100. (list '(1 1) '(3 3))
  101. (list '(1 3) '(3 1))))
  102. (display (get-intersection-point
  103. (list '(1 1) '(2 2))
  104. (list '(1 2) '(2 1))))
  105. (display (get-intersection-point
  106. (list '(0 1) '(0 2))
  107. (list '(2 2) '(1 2))))
  108. (define (coincident? axis line)
  109. (let loop ((axis-p (car axis))
  110. (line-p (car line)))
  111. (if (= 0 (car axis-p))
  112. (= 0 (car line-p))
  113. (loop (cdr axis-p) (cdr line-p)))))
  114. ;; TODO: consider renaming
  115. ;; Issues remain, although I think the issue is do to the intersection point logic...
  116. (define (within-bounds? p axis edge)
  117. (and (within-axis? p axis)
  118. (within-edge? p edge)))
  119. (define (within-axis? p axis)
  120. ;; NOTE: we are assuming a lot here...
  121. (let loop ((p p) (axis-p (car axis)))
  122. (if (= 0 (car axis-p))
  123. (loop (cdr p) (cdr axis-p))
  124. (or
  125. (and (>= (car axis-p) 0)
  126. (>= (car p) 0))
  127. (and (<= (car axis-p) 0)
  128. (<= (car p) 0))))))
  129. (define (within-edge? p line-seg)
  130. (display "intersection point: ")
  131. (display p)
  132. (newline)
  133. (display "line")
  134. (display line-seg)
  135. (newline)
  136. (let ((this
  137. (receive (x1 x2 y1 y2)
  138. (get-coordinates line-seg)
  139. (and
  140. (if (> x1 x2)
  141. (and
  142. (<= (car p) x1)
  143. (>= (car p) x2))
  144. (and
  145. (>= (car p) x1)
  146. (<= (car p) x2)))
  147. (if (> y1 y2)
  148. (and
  149. (<= (cadr p) y1)
  150. (>= (cadr p) y2))
  151. (and
  152. (>= (cadr p) y1)
  153. (<= (cadr p) y2)))))))
  154. (display this)
  155. this))
  156. (define (get-coordinates line-seg)
  157. (values (car (car line-seg))
  158. (car (cadr line-seg))
  159. (cadr (car line-seg))
  160. (cadr (cadr line-seg))))
  161. (define (get-sides triangle)
  162. (map (lambda (point)
  163. (delv point triangle))
  164. triangle))
  165. (define +x-axis (list '(1 0) '(2 0)))
  166. (define -x-axis (list '(-1 0) '(-2 0)))
  167. (define +y-axis (list '(0 1) '(0 2)))
  168. (define -y-axis (list '(0 -1) '(0 -2)))
  169. (define axis-list
  170. (list +x-axis
  171. -x-axis
  172. +y-axis
  173. -y-axis))
  174. (define (make-triangles file)
  175. (let ((port (open-input-file file)))
  176. (let loop ((line (get-line port)) (triangles '()))
  177. (if (eof-object? line)
  178. triangles
  179. (loop (get-line port)
  180. (cons (make-triangle line) triangles))))))
  181. ;; TODO: figure out what is preferred
  182. (define (make-triangle line)
  183. (let loop ((points (map string->number
  184. ((lambda (s) (string-split s #\,))
  185. line)))
  186. (vertices '()))
  187. (if (null? points) vertices
  188. (loop (drop points 2)
  189. (cons (take points 2) vertices)))))
  190. ;; (letrec (
  191. ;; (loop (lambda (points vertices)
  192. ;; (if (null? points) vertices
  193. ;; (loop (drop points 2)
  194. ;; (cons (take points 2) vertices))))))
  195. ;; (loop (map string->number (points line)) '())))
  196. ;; (define (contains-origin1? triangle)
  197. ;; (fold and #t
  198. ;; (fold (lambda (intersections acc)
  199. ;; (map or intersections acc))
  200. ;; '(#f #f #f #f)
  201. ;; (get-sides triangle))))
  202. ;;
  203. ;;
  204. ;;
  205. ;; (define (intersects c1 c2)
  206. ;; (or (and (<= 0 c1) (>= 0 c2))
  207. ;; (and (>= 0 c2) (<= 0 c2))))
  208. ;;
  209. ;;
  210. ;;
  211. ;;
  212. ;; (display (triangle-containment "input/p102.txt"))
  213. (define triangle1
  214. (list
  215. (list 1 2)
  216. (list 1 -2)
  217. (list -2 -2)))
  218. (define triangle2
  219. (list
  220. (list 2 2)
  221. (list 2 1)
  222. (list 1 1)))
  223. (define triangle3
  224. (list
  225. '(-340 495)
  226. '(-153 -910)
  227. '(835 -947)))
  228. (define triangle4
  229. (list
  230. '(-175 41)
  231. '(-421 -714)
  232. '(574 -645)))
  233. (define triangle5
  234. (list
  235. '(1 0)
  236. '(-1 0)
  237. '(2 0)))
  238. (define triangle6
  239. (list
  240. '(0 0)
  241. '(200 200 )
  242. '(410 200)))
  243. (define triangle7
  244. (list
  245. '(-1 -1)
  246. '(1 1 )
  247. '(3 4)))
  248. (display (containment-test triangle3))
  249. (display (containment-test triangle6))
  250. ;; (display (containment-test triangle4))
  251. ;; Hmmm, well i guess we can do a check to see if any of the points have the origin in them...
  252. (display (triangle-containment "input/p102.txt"))