newLISP Fan Club

Forum => newLISP in the real world => Topic started by: cameyo on June 17, 2024, 10:34:36 AM

Title: A simple(?) problem
Post by: cameyo on June 17, 2024, 10:34:36 AM
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
Title: Re: A simple(?) problem
Post by: rrq on June 25, 2024, 05:37:41 AM
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 :)
Title: Re: A simple(?) problem
Post by: cameyo on June 26, 2024, 11:36:06 AM
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
Title: Re: A simple(?) problem
Post by: rrq on June 26, 2024, 02:08:55 PM
Yeah. Way faster than mine :)

chhers