p061.scm 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ; Cyclic Figurate Numbers
  2. (define-module (unsolved p061))
  3. (use-modules (srfi srfi-1)
  4. (ice-9 control)
  5. (ice-9 receive))
  6. (define (triangle n)
  7. (/ (* n (+ n 1)) 2))
  8. (define (square n)
  9. (* n n))
  10. (define (pentagonal n)
  11. (/ (* n (- (* 3 n) 1)) 2))
  12. (define (hexagonal n)
  13. (* n (- (* 2 n) 1)))
  14. (define (heptagonal n)
  15. (/ (* n (- (* 5 n) 3)) 2))
  16. (define (octagonal n)
  17. (* n (- (* 3 n) 2)))
  18. (define (get-n-digit-set proc n)
  19. (let loop ((i 1) (set '()))
  20. (let* ((curr-val (proc i))
  21. (curr-val-length (string-length (number->string curr-val))))
  22. (if (> curr-val-length n)
  23. set
  24. (loop (1+ i)
  25. (if (< curr-val-length n)
  26. set
  27. (cons curr-val set)))))))
  28. (define (get-n-digit-sets proc-list n)
  29. (map (lambda (proc)
  30. (get-n-digit-set proc n))
  31. proc-list))
  32. ;; really not sure about this program style...
  33. (define (find-six-cyclic-4-digit-numbers-in proc-list return)
  34. (define sets (reverse (get-n-digit-sets proc-list 4)))
  35. (define (min-set-loop min-set rest)
  36. (if (null? min-set) '()
  37. (begin ;; can i put the return somewhere else?
  38. (find-cyclic-nums-loop (list (car min-set)) rest)
  39. (min-set-loop (cdr min-set) rest))))
  40. (define (find-cyclic-nums-loop cyclic-set candidate-sets)
  41. (let loop ((i 0))
  42. (cond
  43. ((= (length cyclic-set) (length sets)) ;; review cond behavior
  44. (if (cyclic? (first cyclic-set) (last cyclic-set))
  45. (begin (display cyclic-set) (newline) (return cyclic-set)) cyclic-set))
  46. ((>= i (length candidate-sets)) cyclic-set) ;; returning to previous function
  47. (else (begin
  48. (find-next-cyclic-num cyclic-set
  49. (list-ref candidate-sets i)
  50. (append (take candidate-sets i) ;; double check this
  51. (drop candidate-sets (1+ i))))
  52. (loop (1+ i)))))))
  53. ;; should i use fold here?
  54. (define (find-next-cyclic-num cyclic-set candidate-set rest)
  55. (let loop ((candidate-set candidate-set))
  56. (cond
  57. ((null? candidate-set) #f)
  58. ((cyclic? (car cyclic-set) (car candidate-set))
  59. (begin
  60. (find-cyclic-nums-loop (cons (car candidate-set) cyclic-set) rest)
  61. (loop (cdr candidate-set))))
  62. (else (loop (cdr candidate-set))))))
  63. (receive (min-set rest)
  64. (extract-min-set sets)
  65. (display (length rest))
  66. (newline)
  67. (min-set-loop min-set rest)
  68. ))
  69. (define (cyclic? val1 val2)
  70. (string=? (string-take (number->string val1) 2)
  71. (string-take-right (number->string val2) 2)))
  72. (define (set-analysis cyclic-set sets)
  73. (let loop ((cyc-set cyclic-set))
  74. (if (null? cyc-set) (begin (display cyclic-set) (newline))
  75. (if (unique? (car cyc-set) sets)
  76. (loop (cdr cyc-set))
  77. (display "failed")))))
  78. (define (unique? value sets)
  79. (display
  80. (map (lambda (set)
  81. (fold
  82. (lambda (val acc)
  83. (+ acc (if (= val value) 1 0)))
  84. 0
  85. set))
  86. sets))
  87. (newline)
  88. (<= 1
  89. (fold +
  90. 0
  91. (map (lambda (set)
  92. (fold
  93. (lambda (val acc)
  94. (+ acc (if (= val value) 1 0)))
  95. 0
  96. set))
  97. sets))))
  98. (define (extract-min-set sets)
  99. (let ((ordered-sets
  100. (fold (lambda (set ordered-sets)
  101. (if (< (length set) (length (car ordered-sets)))
  102. (cons set ordered-sets)
  103. (append ordered-sets (list set))))
  104. (list (car sets))
  105. (cdr sets))))
  106. (values (car ordered-sets) (cdr ordered-sets))))
  107. (define (something?)
  108. (fold + 0
  109. (call/ec
  110. (lambda (return)
  111. (find-six-cyclic-4-digit-numbers-in
  112. (list triangle square pentagonal hexagonal heptagonal octagonal)
  113. return)))))
  114. (define (something-else?)
  115. (let ((candidate-sets '(1 2 3 4)))
  116. (display (list-ref candidate-sets 2)) (newline)
  117. (append (take candidate-sets 2) ;; double check this
  118. (drop candidate-sets (1+ 2)))))