Elementary cellular automaton/Random number generator: Difference between revisions

Content added Content deleted
(→‎{{header|Racket}}: conforming output)
Line 232: Line 232:


;; This is the RNG automaton
;; This is the RNG automaton
(define ng/30 (CA-next-generation 30))
(define (CA30-random-generator
#:rule (rule 30) ; rule 30 is random, maybe you're interested in using others
(define (random-usable-bits) (random (fxlshift 1 usable-bits/fixnum-1)))
;; width of the CA... this is implemented as a number of words plus, maybe, another word
(define CA30-rand
;; containing the spare bits
(let ((v ; seed CA state -- I'd expect the period of a wider automaton to be larger
#:bits (bits 256))
; maybe even as high as 2^(30*4) -- who knows?
(fxvector (random-usable-bits) (random-usable-bits) (random-usable-bits) (random-usable-bits))))
(let*-values (([full-words more-bits] (quotient/remainder bits usable-bits/fixnum))
([wrap-rule] (and (positive? more-bits) (wrap-rule-truncate-left-word more-bits)))
([next-gen] (CA-next-generation 30 #:wrap-rule wrap-rule))
([v] (make-fxvector (+ full-words (if more-bits 1 0)))))
(fxvector-set! v 0 1) ; this bit will always have significance
(define (next-word)
(define (next-word)
(define-values (v+ o) (ng/30 v 0))
(define-values (v+ o) (next-gen v 0))
(set! v v+)
(begin0
(fxvector-ref v 0))
(fxvector-ref v 0)
(set! v v+)))
;; make sure all bits have affected each other
(for ((i (* usable-bits/fixnum-1 (fxvector-length v)))) (next-word))
(lambda (bits)
(lambda (bits)
(for/fold ((acc 0))
(for/fold ((acc 0)) ((_ (in-range bits)))
((_ (in-range bits)))
;; the CA is fixnum, but this function returns integers of arbitrary width
;; the CA is fixnum, but this function returns integers of arbitrary width
(bitwise-ior (arithmetic-shift acc 1) (bitwise-and (next-word) 1))))))
(bitwise-ior (arithmetic-shift acc 1) (bitwise-and (next-word) 1))))))


(module+ main
(module+ main
;; To match the other examples on this page, the automaton is 30+30+4 bits long
(CA30-rand 32)
(CA30-rand 32)
;; (i.e. 64 bits)
(define C30-rand-64 (CA30-random-generator #:bits 64))
(CA30-rand 32)
;; this should be the list from "C"
(CA30-rand 32)
(for/list ((i 10)) (C30-rand-64 8))
; we also do big numbers...
; we also do big numbers...
(number->string (CA30-rand 256) 16)
(number->string (C30-rand-64 256) 16)
(number->string (CA30-rand 256) 16)
(number->string (C30-rand-64 256) 16)
(number->string (CA30-rand 256) 16)
(number->string (C30-rand-64 256) 16)
(number->string (CA30-rand 256) 16))</lang>
(number->string (C30-rand-64 256) 16))</lang>


{{out}}
{{out}}


<pre>(220 197 147 174 117 97 149 171 100 151)
<pre>2849574621
"ecd9fbcdcc34604d833950deb58447124b98706e74ccc74d9337cb4e53f38c5e"
1863474554
"9c8b6471a4bc2cb3508f10b6635e4eb959ad8bbe484480695e8ddb5795f956a"
2735907428
"6d85153a987dad6f013bc6159a41bf95b9d9b14af87733e17c702a3dc9052172"
1999558413
"fc6fd302f5ea8f2fba6f476cfe9d090dc877dbd558e5afba49044d05b14d258"</pre>
"790cffff341e073a195bec90d411437b80ede7be3953765b3059c158eb12bbc5"
"c014dc24b52f5c7e305dd2b4e7b753af1107b88f8055dd1c3cdb81f806e62fb2"
"414ff56f551747b740e7fb4d0613cd9d645db546e783cbf77d026724e1e8ee5"
"9a3224043946601f7181c1a6efdeed5fb45f8deb76c339bfff73ad281160bc7d"</pre>

Random. Obviously <code>:-)</code>


=={{header|Ruby}}==
=={{header|Ruby}}==