part-02.scm 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. (import
  2. (except (rnrs base)
  3. let-values
  4. map
  5. error
  6. vector-map)
  7. (only (guile)
  8. lambda* λ
  9. simple-format
  10. current-output-port)
  11. (fileio)
  12. ;; (ice-9 pretty-print)
  13. (ice-9 peg)
  14. (prefix (peg-tree-utils) peg-tree:)
  15. ;; (ice-9 format)
  16. (srfi srfi-1)
  17. (pipeline)
  18. (debug)
  19. (list-helpers)
  20. (parallelism)
  21. (math))
  22. (define input-filename "input")
  23. ;; QLIST -- Merely adding a Q to avoid any name clashes, either actual
  24. ;; ones or in my mind.
  25. (define-peg-pattern COMMA none ",")
  26. (define-peg-pattern NUMBER all (+ (range #\0 #\9)))
  27. (define-peg-pattern QOPEN none "[")
  28. (define-peg-pattern QCLOSE none "]")
  29. (define-peg-pattern QLIST-ITEM body (or NUMBER QLIST))
  30. (define-peg-pattern QLIST-ALL-ITEMS all (* (and QLIST-ITEM (? COMMA))))
  31. (define-peg-pattern QLIST all (and QOPEN QLIST-ALL-ITEMS QCLOSE))
  32. (define parse-string-list
  33. (λ (str)
  34. (let ([tree (peg:tree (match-pattern QLIST str))])
  35. tree)))
  36. (define parsed-list->list
  37. (λ (plist)
  38. (let ([label (first plist)])
  39. (cond
  40. [(eq? label 'NUMBER)
  41. (string->number (second plist))]
  42. [(eq? label 'QLIST)
  43. (map parsed-list->list
  44. (peg-tree:tree-refs plist '(QLIST-ALL-ITEMS) #:equal-test eq?))]
  45. [else (error "unrecognized parsed list" plist)]))))
  46. (define list-transformer
  47. (λ (list-str)
  48. (-> list-str parse-string-list parsed-list->list)))
  49. (define less
  50. (λ (lst1 lst2)
  51. (define compare
  52. ;; Usage of a continuation for the equals case avoids having to
  53. ;; encode the results of <, =, > in 3 values like 1, 0, -1.
  54. (λ (lst1° lst2° equal-case-cont)
  55. ;; (simple-format #t "comparing:\n~a\n~a\n" lst1° lst2°)
  56. (cond
  57. [(and (null? lst1°) (null? lst2°)) (equal-case-cont)]
  58. [(null? lst2°) #f]
  59. [(null? lst1°) #t]
  60. ;; no list ran out of elements yet -- OK!
  61. [else
  62. (let ([elem1 (first lst1°)] [elem2 (first lst2°)])
  63. (cond
  64. ;; both contain a list as first element
  65. [(and (or (pair? elem1) (null? elem1))
  66. (or (pair? elem2) (null? elem2)))
  67. (compare elem1
  68. elem2
  69. ;; Build a new continuation. Compare this cdr,
  70. ;; but also keep the outer cdr compare
  71. ;; continuation.
  72. (λ ()
  73. (compare (cdr lst1°)
  74. (cdr lst2°)
  75. equal-case-cont)))]
  76. ;; both a number
  77. [(and (number? elem1) (number? elem2))
  78. ;; need to distinguish equals case
  79. (cond
  80. [(< elem1 elem2) #t]
  81. [(= elem1 elem2)
  82. (compare (cdr lst1°)
  83. (cdr lst2°)
  84. equal-case-cont)]
  85. [(> elem1 elem2) #f])]
  86. ;; transform into a list if not both a list
  87. [(and (number? elem1) (not (number? elem2)))
  88. (less (cons (list elem1) (cdr lst1°)) lst2°)]
  89. [(and (not (number? elem1)) (number? elem2))
  90. (less lst1° (cons (list elem2) (cdr lst2°)))]
  91. ;; both a list
  92. [(and (pair? elem1) (pair? elem2))
  93. (compare elem1
  94. elem2
  95. (λ () (less (cdr lst1°) (cdr lst2°))))]
  96. [else
  97. (simple-format #t "unrecognized situation while comparing: ~a with ~a\n" lst1 lst2)
  98. (error "unrecognized situation" lst1 lst2)]))])))
  99. (cond
  100. [(and (null? lst1) (null? lst2)) #t]
  101. [(null? lst1) #t]
  102. [(null? lst2) #f]
  103. [else
  104. (compare lst1
  105. lst2
  106. (λ () (less (cdr lst1) (cdr lst2))))])))
  107. (define distress-signal-package-1 '((2)))
  108. (define distress-signal-package-2 '((6)))
  109. (define sorted-lists
  110. (-> (get-lines-from-file input-filename)
  111. (filter (λ (line) (not (string-null? line))) #|arg|#)
  112. (parallel-map (λ (line _ind) (list-transformer line)) #|arg|#)
  113. ((λ (transformed-lists)
  114. (cons distress-signal-package-1
  115. (cons distress-signal-package-2
  116. transformed-lists))) #|arg|#)
  117. ((λ (lists-with-signal)
  118. (sort lists-with-signal less)) #|arg|#)))
  119. (-> (list distress-signal-package-1 distress-signal-package-2)
  120. (parallel-map
  121. (λ (signal _ind)
  122. (list-index (λ (elem) (equal? elem signal))
  123. sorted-lists)) #|arg|#)
  124. (map (λ (i) (+ i 1)) #|arg|#)
  125. product
  126. (simple-format #t "~a\n" #|arg|#))