utils.scm 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. (define-module (euler utils))
  2. (use-modules (srfi srfi-1)
  3. (srfi srfi-26)
  4. (wak foof-loop))
  5. (define-public (lst-index lst item)
  6. (let loop ([i 0] [curr-lst lst])
  7. (cond
  8. [(null? curr-lst) #f]
  9. [(equal? item (car curr-lst)) i]
  10. [else (loop (1+ i) (cdr curr-lst))])))
  11. (define-public (digits n)
  12. (map string->number
  13. (map string (string->list (number->string n)))))
  14. (define-public (digits->number digits)
  15. (string->number
  16. (string-concatenate
  17. (map number->string digits))))
  18. (define-public (number-length n)
  19. (string-length (number->string n)))
  20. ;;; TODO: try impl using compose
  21. (define-public (digits=? n1 n2)
  22. (apply equal? (map (cut sort <> <)
  23. (map digits (list n1 n2)))))
  24. (define-public (digits>? n1 n2)
  25. (> (number-length n1) (number-length n2)))
  26. (define-public (palendromic? s)
  27. (string=? s (string-reverse s)))
  28. (define-public (pandigital? n)
  29. (let ([digits (digits n)])
  30. (lset= = digits (iota (length digits) 1))))
  31. (define-public (fold-and proc lst)
  32. (loop continue ((for element (in-list lst)))
  33. => #t
  34. (if (proc element) (continue) #f)))
  35. (define-public (fold-or proc lst)
  36. (loop continue ((for element (in-list lst)))
  37. => #f
  38. (if (proc element) #t (continue))))
  39. (define-public (max-generic > . args)
  40. (fold (lambda (datum max-datum)
  41. (if max-datum
  42. (if (> datum max-datum) datum
  43. max-datum)
  44. datum))
  45. #f
  46. args))
  47. ;;; TODO: talk to irc about style forms
  48. (define-public (number-append n1 n2)
  49. (+ (* n1 (expt 10
  50. (number-length n2)))
  51. n2))
  52. (define-public (number-reverse n)
  53. (string->number (string-reverse (number->string n))))
  54. (define-public (permutation? n1 n2)
  55. (equal? (sort (digits n1) <)
  56. (sort (digits n2) <)))
  57. (define-public (list-comp start end)
  58. (let lp ([curr start] [acc '()])
  59. (if (> start end) (reverse acc)
  60. (lp (1+ start) (cons curr acc)))))
  61. ;; Find the index of value that is max based on compare-proc
  62. (define-public (list-maximum-index compare-proc vals)
  63. (let lp ([curr-index 1] [curr-max (car vals)] [curr-max-index 0] [vals (cdr vals)])
  64. (cond
  65. [(null? vals) curr-max-index]
  66. [(compare-proc (car vals) curr-max)
  67. (lp (1+ curr-index) (car vals) curr-index (cdr vals))]
  68. [else (lp (1+ curr-index) curr-max curr-max-index (cdr vals))])))
  69. (define-public (number->binary n)
  70. (let ([array-length (inexact->exact (floor (/ (log n) (log 2))))])
  71. (let loop ([i array-length] [remdr n] [b-list '()])
  72. (if (< i 0) (string-concatenate (reverse b-list))
  73. (let ([n-remdr (expt 2 i)])
  74. (if (<= n-remdr remdr)
  75. (loop (1- i) (- remdr n-remdr) (cons "1" b-list))
  76. (loop (1- i) remdr (cons "0" b-list))))))))
  77. ;;; Add hash-table foof-loop support
  78. (define-public (categorize list cat-proc vector-size)
  79. (loop ((for elt (in-list list))
  80. (with index 0 (cat-proc elt))
  81. (with vec (make-vector (1+ vector-size) '())
  82. (begin
  83. (vector-set! vec index
  84. (cons elt
  85. (vector-ref vec index)))
  86. vec)))
  87. => vec))
  88. (define (min-length vs)
  89. (let loop ((vs (cdr vs))
  90. (result (vector-length (car vs))))
  91. (if (null? vs)
  92. result
  93. (loop (cdr vs) (min result (vector-length (car vs)))))))
  94. (define-syntax-rule (assert-procedure f who)
  95. (unless (procedure? f)
  96. (error-from who "expected procedure, got" f)))
  97. (define-syntax-rule (assert-vector v who)
  98. (unless (vector? v)
  99. (error-from who "expected vector, got" v)))
  100. (define-syntax-rule (assert-vectors vs who)
  101. (let loop ((vs vs))
  102. (unless (null? vs)
  103. (assert-vector (car vs) who)
  104. (loop (cdr vs)))))
  105. (define (error-from who msg . args)
  106. (apply error
  107. (string-append (symbol->string who) ": " msg)
  108. args))
  109. (define-public vector-map-no-idx
  110. (case-lambda
  111. ((f v)
  112. (assert-procedure f 'vector-map)
  113. (assert-vector v 'vector-map)
  114. (let* ((len (vector-length v))
  115. (result (make-vector len)))
  116. (let loop ((i 0))
  117. (unless (= i len)
  118. (vector-set! result i (f (vector-ref v i)))
  119. (loop (+ i 1))))
  120. result))
  121. ((f v1 v2)
  122. (assert-procedure f 'vector-map)
  123. (assert-vector v1 'vector-map)
  124. (assert-vector v2 'vector-map)
  125. (let* ((len (min (vector-length v1) (vector-length v2)))
  126. (result (make-vector len)))
  127. (let loop ((i 0))
  128. (unless (= i len)
  129. (vector-set! result i (f (vector-ref v1 i) (vector-ref v2 i)))
  130. (loop (+ i 1))))
  131. result))
  132. ((f . vs)
  133. (assert-procedure f 'vector-map)
  134. (assert-vectors vs 'vector-map)
  135. (let* ((len (min-length vs))
  136. (result (make-vector len)))
  137. (let loop ((i 0))
  138. (unless (= i len)
  139. (vector-set! result i (apply f (vectors-ref vs i)))
  140. (loop (+ i 1))))
  141. result))))
  142. (define (vectors-ref vs i)
  143. (let loop ((vs vs) (xs '()))
  144. (if (null? vs)
  145. (reverse! xs)
  146. (loop (cdr vs) (cons (vector-ref (car vs) i)
  147. xs)))))