Pin number randomization with REBOL

Justin just asked me to help generate random numbers because he was not sure about how to do it in Excel.

Actually it was as straightforward as =RANDOM(0,999999) but it didn't show the leading zeros.

Meanwhile I was trying to do it in REBOL with moderate success because I didn't use the 'random function often in the past.

>> random "0123456789"
== "8501327964"
>> random/only "0123456789"
== #"5"
>> #"0" - 1 + random 10    
== #"4"
As you see, REBOL understands how to randomize a string datatype, which is useful if we want to use a different set of characters, but we can do a more C-like approach too, which relies on the ASCII code allocation of the numerical digits. I think the 1st is more readable, though the /only refinement is not obvious... Let's throw this into a loop now:
>> loop 4 [n: copy "" loop 6 [append n random/only "0123456789"] print n]
823908
689004
036218
012585
There are leading zeros but no sequence number plus we have to save the results into a comma separated file (im not sure why...), so this is what I came up with:
i: 0 write %pins.csv rejoin collect [ loop 40 [n: copy "" loop 6 [append n random/only "0123456789"]
  keep rejoin [copy/part tail join "000" i: i + 1 -4 "," n "^/"]]]

"Looks quite functional" -- drew the conclusion Justin

Well, a little bit it is if there weren't any assignments in it, right?...

He also said Haskell is so much cleaner and has built-in number formatting too :) ... but we weren't able to create an example on the spot, because GHC-6.12.3-i386.pkg is 117 MB as opposed to REBOL, which is ~200 kilo-fucking-byte only!

But I should definitely check out Haskell some time, especially to make me understand the source code of DARCS to some extent.

I don't like ugly and bloated code, so let's clean it up a bit. 1st, number formatting. What does zero padding really mean?

We can imagine it as having a string of zeros and overwriting the end of this string with the digits of the actual number, OR we can think of it as joining the 2 and having a look at the last chars only.

The 1st technique would require heavier position calculations, while the second is more straightforward slicing&dicing. Strictly for fun, let's try to generalize the solution, which I don't advise, since we are not exploiting simplifications allowed by the luckily well defined constraints.

>> pad: 4   repeat i 5 [print skip  tail insert/dup mold i + 7 "0" pad   (- pad)]
0008
0009
0010
0011
0012

Final result:

write %pins.csv collect [ repeat i 40 [
  keep skip tail join "000" i -4   keep ","
  loop 6 [keep random/only "1234567890"]   keep "^/"
] ]

And the file content looks like this:

0001,460405
0002,364105
0003,464132
...
0039,227674
0040,789309

Other REBOLers out there, please correct me if I'm showing a bad examples.

334 views and 1 response

  • Sep 25 2010, 3:12 AM
    (Facebook) responded:
    Nice solution :)
    My version:
    write %pins.csv rejoin collect [for i 1 10 1 [n: to-string random 999999 keep rejoin [copy/part "000" (4 - length? to-string i) i "," copy/part "000000" (6 - length? n) n "^/"]]]