Re: Is there something wrong with random function?
Jean Louis <[email protected]> Thu, 16 Nov 2017 20:22:05 +0300
| Newsgroups | gmane.lisp.clisp.general |
|---|---|
| Message-ID | <[email protected]> |
Hello Pascal,
That is nice to see, beautiful.
I have just modified it little so that I can get 6
digits, as I actually just need a string of
digits to construct web slugs with strings and
avoid having same slugs.
(defun random-number (&key (digits 6))
"Returns the random number with 6 digits by default"
(setf *random-state* (make-random-state))
(let ((fstr (make-array '(0) :element-type 'base-char :fill-pointer 0 :adjustable t)))
(with-output-to-string (s fstr)
(dotimes (ti digits fstr)
(format s "~A" (random 10))))))
Jean
On Thu, Nov 16, 2017 at 02:45:22PM +0100, Pascal Bourguignon wrote:
>
>
> > On 16 Nov 2017, at 14:16, <[email protected]> <[email protected]> wrote:
> >
> > Jean Louis wrote:
> >
> > (defun random-number (&key (digits 6))
> > "Returns the random number with 6 digits by default"
> > (setf *random-state* (make-random-state))
> > (let ((fstr (make-array '(0) :element-type 'base-char :fill-pointer 0 :adjustable t)))
> > (with-output-to-string (s fstr)
> > (dotimes (ti digits)
> > (princ (character (write-to-string (random 10))) s)))
> > (read-from-string fstr)))
> >
> > Don already found the bug, but nobody commented about style.
> > This function is overly convoluted. Think again about what you want to achieve.
> > What you're doing above is
> > Number -> print -> string -> character -> print -> collecting-stream -> adjustable-string -> number
> > Ouch. Just go straight to your goal.
>
>
>
> (defun random-number (&key (digits 6))
> "Returns the random number with 6 digits by default"
> (random (expt 10 6)))
>
> However, this is wrong! For example:
>
> (setf *print-base* 3)
> (random-number)
> ;; --> 102222200011 ;; NOT 6 digits!!!
>
> Instead, let's add a base parameter (and take *print-base* by default):
>
> (defun random-number (&key (digits 6) (base *print-base*))
> "Returns the random number with 6 digits by default"
> (random (expt base 6)))
>
> (random-number)
> ;; --> 112101
>
> (loop repeat 10 collect (random-number))
> ;; --> (879023 606819 686060 963306 143047 550980 621150 144785 90563 830616)
>
>
> (defun replength (n &key (base *print-base*))
> (ceiling (log n base)))
>
> (defun subrep (num start end &key (base *print-base*))
> "Digits are indexed from least significant."
> (check-type num integer)
> (check-type start (integer 0))
> (check-type end (integer 0))
> (check-type base (integer 2))
> (if (< start end)
> (rem (truncate num (expt base start))
> (expt base (- end start)))
> 0))
>
> (loop for start below 10
> collect (subrep 123456789 start (+ start 3)))
> ;; --> (789 678 567 456 345 234 123 12 1 0)
>
> (loop for start below 10
> collect (subrep -123456789 start (+ start 3)))
> ;; --> (-789 -678 -567 -456 -345 -234 -123 -12 -1 0)
>
>
> (defun sign (n)
> (check-type n real)
> (cond ((minusp n) -1)
> ((plusp n) +1)
> (t 0)))
>
> (defun concatrep (a b &key (base *print-base*) length2)
> (check-type a integer)
> (check-type b integer)
> (check-type base (integer 2))
> (check-type length2 (or null (integer 0)))
> (let* ((length2 (or length2 (replength b)))
> (factor (expt base length2)))
> (* (sign a)
> (+ (* (abs a) factor)
> (mod (abs b) factor)))))
>
> (concatrep -123 456)
> ;; --> -123456
> (concatrep -123 12 :length2 3)
> ;; --> -123012
> (concatrep 123 -3 :length2 3)
> ;; --> 123003
>
> (let ((*print-base* 5))
> (prin1-to-string (subrep (concatrep #5r1234 #5r4321) 2 6)))
> ;; --> "3443"
>
>
>
>
> --
> __Pascal J. Bourguignon__
> Try the IBM Flex font: IBM has freed itself from the tyranny of Helvetica https://qz.com/1124664/ibm-plex-with-its-first-ever-custom-corporate-font-ibm-is-freeing-itself-from-the-tyranny-of-helvetica/
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
clisp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-list