fork download
  1. ; phone numbers and prime factors
  2.  
  3. (define rand
  4. (let* ((a 6364136223846793005)
  5. (c 1442695040888963407)
  6. (m 18446744073709551616)
  7. (seed (current-time)))
  8. (lambda args
  9. (when (pair? args) (set! seed (modulo (car args) m)))
  10. (set! seed (modulo (+ (* a seed) c) m))
  11. (/ seed m))))
  12.  
  13. (define randint
  14. (case-lambda
  15. ((n) (floor (* (rand) n)))
  16. ((first past) (+ (floor (* (rand) (- past first))) first))))
  17.  
  18. (define (uniq-c eql? xs)
  19. (if (null? xs) xs
  20. (let loop ((xs (cdr xs)) (prev (car xs)) (k 1) (result '()))
  21. (cond ((null? xs) (reverse (cons (cons prev k) result)))
  22. ((eql? (car xs) prev) (loop (cdr xs) prev (+ k 1) result))
  23. (else (loop (cdr xs) (car xs) 1 (cons (cons prev k) result)))))))
  24.  
  25. (define (last xs)
  26. (if (or (null? xs) (null? (cdr xs))) xs
  27. (last (cdr xs))))
  28.  
  29. (define (cycle . xs) (set-cdr! (last xs) xs) xs)
  30.  
  31. (define wheel
  32. (cons 1 (cons 2 (cons 2 (cycle 4 2 4 2 4 6 2 6)))))
  33.  
  34. (define (factors n)
  35. (let loop ((n n) (f 2) (w wheel) (fs (list)))
  36. (if (< n (* f f)) (reverse (cons n fs))
  37. (if (zero? (modulo n f)) (loop (/ n f) f w (cons f fs))
  38. (loop n (+ f (car w)) (cdr w) fs)))))
  39.  
  40. (define (omega n)
  41. (let loop ((fs (factors n)) (prev 0) (count 0))
  42. (if (null? fs) count
  43. (if (= (car fs) prev)
  44. (loop (cdr fs) prev count)
  45. (loop (cdr fs) (car fs) (+ count 1))))))
  46.  
  47. (define (rand-phone) (randint #e1e9 #e1e10))
  48.  
  49. (define (phones n)
  50. (do ((n n (- n 1))
  51. (xs (list) (cons (omega (rand-phone)) xs)))
  52. ((zero? n) (uniq-c = (sort xs <)))))
  53.  
  54. (display (phones 100)) (newline)
Success #stdin #stdout 9.64s 10456KB
stdin
Standard input is empty
stdout
((1 . 3) (2 . 22) (3 . 30) (4 . 27) (5 . 16) (6 . 2))