A simple(?) problem

Started by cameyo, June 17, 2024, 10:34:36 AM

Previous topic - Next topic

cameyo

Write a function that generates a random integer within a closed interval and with predefined digits.

For example:
Range: (1 200)
Digits: 1 2 3
Possible numbers: 1 2 3 11 21 31 12 22 32 13 23 33
 111 211 311 121 221 321 131 231 331 112 212 312 122 222
 322 132 232 332 113 213 313 123 223 323 133 233 333
Numbers in the range: 1 2 3 11 21 31 12 22 32 13 23 33
 111 112 113 121 122 123 131 132 133
Random Number: Any of the numbers in the range

rrq

#1
This one is straight-forward but probably a bit slow
(define    (randint RANGE DIGITS)
  (letn ((digits (fn (X) (map int (unique (explode (string X))))))
         (wrong (fn (X) (difference (digits X) DIGITS)))
         (S (clean wrong (apply sequence RANGE))))
    (S (rand (length S)))))

EDIT: simplify by using "apply"

EDIT 2: recusive digitization might be faster (?)
EDIT 3: changed back to use stringifying; looks nicer :)

cameyo

Thanks Ralph.
This is my solution:
(define (create-valid-numbers current)
  (if (<= current max-val)
      (begin
        (if (and (>= current min-val) (<= current max-val))
            (push current valid-numbers))
        ; creates numbers recursively
        (dolist (d digits)
          (create-valid-numbers (+ (* current 10) d))))))

(define (random-integer min-val max-val digits)
  (let (valid-numbers'())
    (dolist (d digits) (create-valid-numbers d))
    (valid-numbers (rand (length valid-numbers)))))

(random-integer 1 300 '(1 2 3))
;-> 21

(time (println (random-integer 1 90000000 '(1 2 3 4 5 6 7))))
;-> 44377532
;-> 6875.421

rrq

Yeah. Way faster than mine :)

chhers