p077.scm 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. ;; Prime summations
  2. (define-module (solved p077))
  3. (use-modules (euler primes)
  4. (srfi srfi-1))
  5. ;; NOTE: for some reason gc does not remove prime-lst and prime-lst-generator...
  6. (define (n-prime-sum-number n)
  7. (define prime-lst '(0)) ; Have to make non-empty...
  8. (define prime-lst-generator! (make-list-generator (make-prime-generator)
  9. prime-lst))
  10. (define node-table (make-hash-table))
  11. (let lp ([i 1])
  12. (when (> i (last prime-lst))
  13. (add-node! node-table (make-prime-sum-node 0 (prime-lst-generator!))))
  14. (let ([nodes (hashq-ref node-table i)])
  15. (cond
  16. [(not nodes) (lp (1+ i))]
  17. [(> (length nodes) n) i]
  18. [else
  19. (for-each (λ (node)
  20. (add-next-generation! node-table node))
  21. nodes)
  22. (lp (1+ i))]))))
  23. (define* (make-list-generator item-generator #:optional (lst '(1)))
  24. (define first-call? #t)
  25. (λ ()
  26. (if first-call?
  27. (begin (set! first-call? #f)
  28. (list-set! lst 0 (item-generator))
  29. lst)
  30. (begin
  31. (list-cdr-set! lst (1- (length lst)) `(,(item-generator)))
  32. lst))))
  33. (define (add-node! table node)
  34. (let ([prev-nodes (hashq-ref table (get-sum node))])
  35. (if prev-nodes
  36. (hashq-set! table (get-sum node)
  37. (cons node prev-nodes))
  38. (hashq-set! table (get-sum node) `(,node)))))
  39. (define (make-prime-sum-node curr-sum primes)
  40. (list (+ curr-sum (last primes))
  41. primes))
  42. ;; TODO: need better name than parent
  43. (define (get-sum parent) (car parent))
  44. (define (get-primes parent) (cadr parent))
  45. (define (add-next-generation! table parent)
  46. (let lp ([curr-primes (reverse (get-primes parent))])
  47. (unless (null? curr-primes)
  48. (add-node! table (make-prime-sum-node (get-sum parent)
  49. (reverse curr-primes)))
  50. (lp (cdr curr-primes)))))