RetroBASIC

Basicprogramming(.org) => Code and examples => Topic started by: ScriptBasic on September 24, 2016, 08:20:48 AM

Title: Random Character
Post by: ScriptBasic on September 24, 2016, 08:20:48 AM
Challenge:

Write a void argument function that will return a random character within the ranges of [A-Z] [a-z] [0-9].

Title: Re: Random Character
Post by: Mopz on September 24, 2016, 10:54:59 AM
Code: [Select]
function RandomChar$()
r = rnd(10 + 26 + 26)
if r < 10;          return chr(asc("0") + r)
elseif r < 10 + 26; return chr(asc("A") + r - 10)
else;               return chr(asc("a") + r - 10 - 26)
endif
endfunc

I'm guessing you have some ScriptBasic ace up your sleeve? :D
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 12:59:15 PM
IIF is the function:

Code: [Select]
#AppType Console
Randomize
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Print $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("0"), %Asc("9"))), $IIf(%RandInt(0, 1), $Chr(%RandInt(%Asc("A"), %Asc("Z"))), $Chr(%RandInt(%Asc("a"), %Asc("z")))))
Pause

Typical outputs:

U
s
L
7
i
0
q

Press any key to continue...


or

7
q
n
7
i
0
s

Press any key to continue...


I've no idea tho how even the distribution would be.
Title: Re: Random Character
Post by: Mopz on September 24, 2016, 01:21:25 PM
C'mon, John, show us yours!
Title: Re: Random Character
Post by: Tomaaz on September 24, 2016, 02:54:19 PM
Code: [Select]
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]
Title: Re: Random Character
Post by: Mopz on September 24, 2016, 03:02:38 PM
Code: [Select]
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]

Ah, that's a nice approach, very elegant! Why didn't I think of that :)
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 03:26:28 PM
Yeah, that one would have a much better distribution profile.

Cf.:

Code: [Select]
#AppType Console
Randomize

Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}

Pause

Typical output:

f
M
k
Y
Q
0
s
U

Press any key to continue...
Title: Re: Random Character
Post by: Tomaaz on September 24, 2016, 03:32:52 PM
Ah, that's a nice approach, very elegant! Why didn't I think of that :)

What about this one? ;)

Code: [Select]
def randchar
(("a".."z").to_a + ("A".."Z").to_a + (0..9).to_a)[rand(62)]
end

Not as ellegant and clear, but makes easier to modify the ranges. ;)
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 03:44:28 PM
Attempt #3:

Code: [Select]
#AppType Console
Randomize

Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)
Print Peek(@"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789" + RandInt(0, 61), $1)

Pause

Typical output:

v
1
P
t
1
W
R
8

Press any key to continue



In attempts #2 and #3, the string may be either a literal or a variable.
Title: Re: Random Character
Post by: Tomaaz on September 24, 2016, 04:01:24 PM
Where is John???  ;D
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 04:02:03 PM
Sleeping. He's an U.S. citizen, after all... ;)
Title: Re: Random Character
Post by: Mopz on September 24, 2016, 04:10:25 PM
Sleeping. He's an U.S. citizen, after all... ;)

Dammit, you can't just start a war and then disappear!
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 04:12:38 PM
Quote
Dammit, you can't just start a war and then disappear!

Unless you've been shot dead by a stray bullet. ;D


In the meantime, attempt #4:

Code: [Select]
#AppType Console
Randomize

Print randchar()
Print randchar()
Print randchar()
Print randchar()
Print randchar()
Print randchar()
Print randchar()
Print randchar()

Pause

Function randchar()
  Static a[] = Split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z", ",")
  Static b[] = Split("A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z", ",")
  Static c[] = Split("0,1,2,3,4,5,6,7,8,9", ",")
  Static d[] = ArrayMerge(a, b, c)
  Static e   = Count(d) - 1
 
  Return d[RandInt(0, e)]
End Function

Typical output:

C
m
f
R
O
1
B
T

Press any key to continue...


Note that all statics will be initialized only once at app start. Thereafter all runtime calls will only Return a fast random char from pre-initialized d[].
Title: Re: Random Character
Post by: jj2007 on September 24, 2016, 04:43:28 PM
Print "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"{RandInt(1, 62)}

Nice but not basic enough, Mike ;)

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  For_ ct=0 To 999
      Print Mid$("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789", Rand(62)+1, 1)
  Next
EndOfCode
Title: Re: Random Character
Post by: ScriptBasic on September 24, 2016, 04:44:44 PM
Quote
C'mon, John, show us yours!

Code: [Select]
RANDOMIZE(NOW)

FUNCTION RC
  n = RND % 62
  IF n < 10 THEN
    RC = n
  ELSE IF n < 36 THEN
    RC = CHR(n + 55)
  ELSE
    RC = CHR(n + 61)
  END IF
END FUNCTION

PRINT RC(),"\n"


jrs@laptop:~/sb/sb22/test$ scriba ranchr.sb
z
jrs@laptop:~/sb/sb22/test$ scriba ranchr.sb
Q
jrs@laptop:~/sb/sb22/test$ scriba ranchr.sb
b
jrs@laptop:~/sb/sb22/test$ scriba ranchr.sb
3
jrs@laptop:~/sb/sb22/test$




Title: Re: Random Character
Post by: B+ on September 24, 2016, 04:45:54 PM
Oh Basic!
Code: [Select]
def randChar() = mid("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", (rnd*62)\1 + 1, 1)
for i in seq(1, 1000, 1000) do ? randChar; " ";
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 04:56:13 PM
Code: [Select]
FUNCTION RandomCharacter
  RANDOMIZE(NOW)
........

You'd better take RANDOMIZE out of your function, John. It's an extremely slow routine and it should be done only once at app start. Then all the random function flavors will only have to fetch the next number from the (typically) 32K long sequence that RANDOMIZE pre-generated, cycling to the beginning of it when its end is reached (which actually turns the entire setup to pseudo random but still usable for most purposes).
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 05:09:59 PM
Oh Basic!
Nice but not basic enough, Mike ;)

You want basics? Well, I've got some. Attempt #5:

Code: [Select]
#AppType Console
Macro randChar() = Mid("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", (Rnd() * 62) \ 1 + 1, 1)

Randomize
For Dim i = 1 To 1000: ? randChar(), " ";: Next

Pause

Typical output:

9 K z y u k f h F 5 e a 1 5 L p c P d V o 8 K D i M H m K F h h 7 f Q G n i H W w J o S H X Q D 4 u
X r a S 4 D M F e F Y n w G G f l 0 r D e r e 9 n m q 8 g l v j 8 F l o B H f u n o F 8 A y F l N 4
7 H 2 3 6 v f Z b K 5 Y V F l q 5 P x Z n R p S j G o W D 7 I r M X L Q E m W E p b s G r i w x s v
A q 0 N o y P V m 9 L Y q e g 1 G 5 B d 9 M u l A S T P T S 5 n z I e e e l y T 0 I 1 K B 2 l F F R
S S Z i h S l L P e 5 O r t n g O q D 9 i g V u 2 7 L w i K E u B D k E 3 1 5 i u X u H 1 3 u O J 5
G u m m j 5 E d H h O m C z 7 4 o h y D M I N g m Z I X X m F N e M W C U O p w 6 w w F a Y r f J b
Y M s 0 U R L x q H n 7 x 0 x v J E 3 k z o q n x t Z O j 4 I Q u B g V b P 4 Q X T t 8 S 6 7 G Q c
D w 5 D v z T J N 1 G l 4 f H q R 1 F 5 w O C l 1 9 w Q Q P T 8 G x 5 U t h C z U I b h j X a H z 3
E 3 H p 8 X o e W k p r R Y e i X J h e b H K Q E s j u o u e A w s X C G k w a k D S A N S X w K 4
e b t y L 6 9 k g S l 3 h r Z q 0 X U 6 V z 7 a 3 m 5 E z D d f Y R S A w r r N F e V f I H U t n p
U b c K S J D g a e k m k w r x d 1 b 4 t 7 U 6 x A F J S 3 X v K v v k p 2 D t R c G F g X V 1 f D
q 0 o q 7 B u d f 8 B s W M S e C E L c p x u N 3 l o A Z 6 c S z Z z K P m z r g h C p Q j i 6 k n
D a 5 A M l Z S i O 8 y h P r 2 4 3 l Y Y G u R 4 W v D o x 5 U p m c h X o 6 A f o B h 5 H 2 W 9 a
R C V v m M R 6 6 T w 4 l q f 1 4 g G 2 z X d y r y I U Q K N f P X y F P b y e b F 0 T H P s N P c
y 7 F Q V j D i d p u N F s 4 E V Z Z 3 r A 2 y 7 Q L Q 3 g t i F 2 g P e F q k 5 o 7 C 9 f g p 6 s
s z 1 m Q d 4 T K W N k h J w k g e e q l 7 K B 1 6 k 2 l r 4 e Y e Z 2 5 h w C u k 5 l q K z J G H
I m P v 6 0 w n t 3 D W O A j h J 6 6 r B N l 1 3 x Q y h 6 6 3 c B C q w 9 3 M 4 w f b b q Q J m Q
1 m T O g g 3 u R U v p c u n a g S N g A Y Q s 9 W 3 k 0 Q E w k f r H h 6 8 f z 4 5 M F S E X F e
b b d S 7 P 7 X K s R 9 E d k N c C w O 1 E p P i Z T V 8 L w 1 p V 4 9 4 W f u 1 G t Z 1 r 9 L 8 U
8 t a 1 a u p W c 2 7 j S c C 4 S K W 3 v U 5 u z T J y K T C t q p e 0 t k y H B p 9 F D i X s s m



P.S. Don't forget to RANDOMIZE, guys, else everywhere I write "Typical" you'll have to write "The only". ;)
Title: Re: Random Character
Post by: Mopz on September 24, 2016, 05:15:37 PM
Just using Tomaz way here, but in naalaa:

Code: [Select]
randomize time()

for y = 1 to 16
for x = 1 to 16
write RandomChar(), " "
next
wln
next

wait keydown

function RandomChar$()
return mid("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", rnd(62))
endfunc

Next assignment: Write a computer chess player with as few line of codes as possible ;)  Actually that'd be kind of fun. I wonder if writing a small PROLOG interpreter would do the trick in a nice and time consuming way?
Title: Re: Random Character
Post by: B+ on September 24, 2016, 06:45:52 PM
Quote
P.S. Don't forget to RANDOMIZE, guys, else everywhere I write "Typical" you'll have to write "The only". ;)

Not correct, I get different outputs without Randomize with SmallBASIC and in Just Basic docs, it says to use RANDOMIZE to get predictable/repeatable runs, eg for debugging. I can show more and different outputs without Randomize.

Append: Confirmed on SmallBASIC, when I Randomize with constant, I get repeated results.

On another front (maybe too philosophical):
If a chess player makes random but legal moves, is it really a chess player?
Title: Re: Random Character
Post by: Mike Lobanovsky on September 24, 2016, 08:28:04 PM
Not correct, I get different outputs without Randomize with SmallBASIC and in Just Basic docs, it says to use RANDOMIZE to get predictable/repeatable runs, eg for debugging. I can show more and different outputs without Randomize.

Sigh...

What's the use of RANDIMIZE at all if, as you say, your random functions yield different numbers every time you run them even as they are? ;) Go figure... Or ask the developers of those languages...

The C language and C-based BASICs would yield the same pseudo random sequence without RANDOMIZE because the seed for the random functions would remain the same. In other words, RANDOMIZE randomizes the seed and regenerates the sequence. Of course if RANDOMIZE uses the same constant argument, the new sequences will also be constant, albeit different from when used without an argument. RANDOMIZE TIMER is redundant in FBSL BASIC because that's what its RANDOMIZE would do on default -- much more often than randomizing with a constant argument.

So what exactly is incorrect in my logic?
Title: Re: Random Character
Post by: ScriptBasic on September 24, 2016, 08:43:57 PM
Quote
What's the use of RANDIMIZE at all if,

I used NOW as the seed for this example as the challenge was to return a single random character. If I were to generate a list of random characters, 1 second seeding isn't sufficient. I use the RANDOMIZE(gfx::Time()) SDL_gfx extension module function for millisecond resolution of randomness.


Title: Re: Random Character
Post by: Tomaaz on September 24, 2016, 09:00:16 PM
Perl. Using regular expressions, of course. ;)

Code: [Select]
sub randchar() {
until ($a =~ /[A-Za-z0-9]/) {
$a = chr(int(rand(128)));
}
return $a;
}

Or something even more Perlish. ;)

Code: [Select]
sub randchar() {
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))}
return $a;
}

Or...

Code: [Select]
sub randchar() {until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} return $a}

 ;D
Title: Re: Random Character
Post by: ZXDunny on September 24, 2016, 09:59:16 PM

Sigh...

What's the use of RANDIMIZE at all if, as you say, your random functions yield different numbers every time you run them even as they are? ;) Go figure... Or ask the developers of those languages...

Well, that's how SpecBAS does it - the random seed at startup is determined by system time in ms. This way every time a program is run, you get random numbers, not a sequence. If you want a sequence, you use the RANDOMIZE keyword - with no parameter it sets the seed to the timer. With a numeric parameter, it uses that as the seed.

That's kinda the point, no?
Title: Re: Random Character
Post by: B+ on September 24, 2016, 10:55:55 PM
Not nearly as elegant as Tomaaz method but to add to rainbow of different ways this could be done:

Code: [Select]
dim c()
for i in seq(48, 57, 10) do append c, i
for i in seq(65, 90, 26) do append c, i
for i in seq(97, 122, 26) do append c, i
 
def rndChr = chr( c( (rnd * 62)\1 ) )

for i in seq(1, 1000, 1000) do ? rndChr; " ";

Title: Re: Random Character
Post by: jj2007 on September 24, 2016, 11:23:17 PM
an extremely slow routine

Ah, speed, the magic word... 8)

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  NumBytes=100000000
  Let edi=New$(NumBytes)
  Let esi="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"
  PrintCpu 0
  Rand()                  ; RANDOMIZE using rdtsc
  NanoTimer()
  For_ ecx=0 To NumBytes-1
      mrm [edi+ecx], [esi+Rand(62)]
  Next
  Print Str$("Generating %i random chars took", ecx), Str$(" %i ms", NanoTimer(ms))
  FileWrite "Random.txt", edi
  Inkey " - see the result (y)?"
  If_ eax=="y" Then ShEx "Random.txt"
EndOfCode


Output:
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
Generating 100000000 random chars took 364 ms - see the result?
Title: Re: Random Character
Post by: Cybermonkey on September 25, 2016, 08:43:25 AM
CMLua (more the BASIC than the Lua way  ;)):
Code: [Select]
-- random char
function randomchar()
 char = mid ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",int (rnd()*62)+1,1)
 return char
end

cls()
for y=0,25, 2 do
 for x=0,64,2 do
    locate (x,y,randomchar())
  end
end

Hm, if we omit the numbers, what do you think how many trials are needed to get the beginning of Shakespeare's Hamlet ... ?
Title: Re: Random Character
Post by: Mike Lobanovsky on September 25, 2016, 12:29:33 PM
Hm, if we omit the numbers, what do you think how many trials are needed to get the beginning of Shakespeare's Hamlet ... ?

You mean "Who's there?"  ;D  Actually not too many to be infeasible. :)

(http://philosophical-bestiary.narod.ru/img/gallery/beskonechnye_obezyani_01_1.jpg)
Title: Re: Random Character
Post by: Mike Lobanovsky on September 25, 2016, 01:30:19 PM
... If you want a sequence, you use the RANDOMIZE keyword - with no parameter it sets the seed to the timer. With a numeric parameter, it uses that as the seed.

That's kinda the point, no?

Yes, it is. That's what FBSL would do too:

... if RANDOMIZE uses the same constant argument, the new sequences will also be constant, albeit different from when used without an argument. RANDOMIZE TIMER is redundant in FBSL BASIC because that's what its RANDOMIZE would do on default -- much more often than randomizing with a constant argument.

Well, that's how SpecBAS does it - the random seed at startup is determined by system time in ms. This way every time a program is run, you get random numbers, not a sequence...

That's kinda the point, no?

No, at least not to my point. FBSL i) incorporates an own ANSI C module, and ii) is designed to extensively use 3rd party DLLs usually written in C and linked against msvcrt.dll (system standard as opposed to crtdll.dll which isn't). FBSL BASIC calls to RANDOMIZE, RANDINT and RND are guaranteed to generate the exact same results as its own DynC and 3rd party calls to srand() and rand() at all times for 100% compatibility reasons.

How much do we want our data refined for us?

And ... what compatibility does SpecBAS claim, Paul? :)

........
Ah, speed, the magic word... 8)
........
  Rand()                  ; RANDOMIZE using rdtsc
........

What will you do with your Rand() under Windows 98 on a 486 chip, Jochen? FBSL runs on and under everything that's at least Windows 95 RC2 (with socket support) and has 32MB of RAM. :)

(http://i1240.photobucket.com/albums/gg490/FbslGeek/FBSL_in_Win98.png) (http://s1240.photobucket.com/user/FbslGeek/media/FBSL_in_Win98.png.html)

I used NOW as the seed for this example as the challenge was to return a single random character. If I were to generate a list of random characters, 1 second seeding isn't sufficient. I use the RANDOMIZE(gfx::Time()) SDL_gfx extension module function for millisecond resolution of randomness.

In fact, all these minutiae are extremely platform dependent, John. For any serious work with random numbers like e.g. cryptography, a specialized 3rd party library would be highly advisable.
Title: Re: Random Character
Post by: Peter on September 25, 2016, 02:52:38 PM
Code: [Select]
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]

Nice. This is my BASIC version.

Code: [Select]
REPEAT
    ch$ = CHR$(RANDOM(256))
UNTIL REGEX(ch$, "[[:alnum:]]")
PRINT ch$
Title: Re: Random Character
Post by: B+ on September 25, 2016, 03:12:10 PM
Hm, if we omit the numbers, what do you think how many trials are needed to get the beginning of Shakespeare's Hamlet ... ?

You mean "Who's there?"  ;D  Actually not too many to be infeasible. :)

(http://philosophical-bestiary.narod.ru/img/gallery/beskonechnye_obezyani_01_1.jpg)

If there is monkey business to be done, I am your primate!
Code: [Select]
' Act1.bas  SmallBASIC 0.12.6 [B+=MGA] 2016-09-25

def randChar() = mid("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", (rnd*62)\1 + 1, 1)

startHamlet = "Act1"
build = ""
while build <> startHamlet
  rCh = randChar
  trials ++
  if trials % 1000 = 999 then cls: print trials, build
  if rCh = mid(startHamlet, len(build) + 1, 1) then build = build + rCh else build = ""
wend
? "It took ";trials;" trials to build ";build;"."
pause

This code needs more speed for anything more ambitious, hint, hint...
Title: Re: Random Character
Post by: B+ on September 25, 2016, 03:47:25 PM
How many spaces have to be added to get a distribution of word lengths that matches Shakespeare's or general use?

Append: It is not going to work well that way.
Title: Re: Random Character
Post by: ZXDunny on September 25, 2016, 08:18:40 PM
And ... what compatibility does SpecBAS claim, Paul? :)

I'd say I'm about 90 - 95% compatible with the original Sinclair BASIC, barring some insurmountable issues such as colour depth and memory layout. So far all the programs I've tested that were written for the original hardware work exactly as they should with some very minor modifications for aforesaid colour issues.
Title: Re: Random Character
Post by: ScriptBasic on September 25, 2016, 08:37:49 PM
And ... what compatibility does SpecBAS claim, Paul? :)

I'd say I'm about 90 - 95% compatible with the original Sinclair BASIC, barring some insurmountable issues such as colour depth and memory layout. So far all the programs I've tested that were written for the original hardware work exactly as they should with some very minor modifications for aforesaid colour issues.

That's an amazing accomplishment Paul!

Is your belief that Sinclair BASIC should live forever as an example of its excellence or is this just a serious hobby that makes you happy? I'm not trying to be a jerk asking these questions. All I'm asking is what makes a retro BASIC programmer tick?



Title: Re: Random Character
Post by: Tomaaz on September 25, 2016, 08:46:05 PM
Code: [Select]
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]

Nice. This is my BASIC version.

Code: [Select]
REPEAT
    ch$ = CHR$(RANDOM(256))
UNTIL REGEX(ch$, "[[:alnum:]]")
PRINT ch$

Looks more like Perl.  ;)
Code: [Select]
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} print $a

Title: Re: Random Character
Post by: Mike Lobanovsky on September 25, 2016, 09:33:57 PM
You mean "Who's there?"  ;D  Actually not too many to be infeasible. :)
This code needs more speed for anything more ambitious, hint, hint...

Actually I seem to have been too optimistic saying what I said. While getting "Who's " printed out is fairly straight forward (in C and case insensitive, of course, for speed reasons), "Who's t" hasn't yet been seen by me at all.

Code: [Select]
#AppType Console

hamlet()

Pause

DynC hamlet()
  #define randChar() "?' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[rand() % 55]
  #define startHamlet "Who's " // "there?"
 
  void main()
  {
    char build[13];
    int rCh, pos = 0, trials = 0;
   
    memset(build, 0, 13);
    srand(time());
   
    while (_stricmp(build, startHamlet) && ++trials) {
      rCh = randChar();
      if (toupper(rCh) == toupper(startHamlet[pos]))
        build[pos++] = rCh;
      else {
        memset(build, 0, pos);
        pos = 0;
      }
    }
    printf("It took %d trials to build '%s'.\n", trials, build);
  }
End DynC
Title: Re: Random Character
Post by: B+ on September 25, 2016, 10:14:18 PM
Hi Mike,

I am curious, dropping the numbers and loosing the case sensitivity and I assume you are inserting the apostrophe, so

26 ^ (number of letters to match)

26 ^ 5 ~ 12 million +/- random luck, should get to whost faster???

Title: Re: Random Character
Post by: Mike Lobanovsky on September 25, 2016, 10:37:03 PM
Hi Mike,

I am curious, dropping the numbers and loosing the case sensitivity and I assume you are inserting the apostrophe, so

26 ^ (number of letters to match)

26 ^ 5 ~ 12 million +/- random luck, should get to whost faster???

Hehe,

Using #define randChar() "?' ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rand() % 29] and a lot of random luck (close to 1.9G trials), I'm finally seeing the attached.

Guess I have to go to unsigned long long's to count the trials for "Who's th". :D
Title: Re: Random Character
Post by: ZXDunny on September 25, 2016, 10:46:57 PM
Is your belief that Sinclair BASIC should live forever as an example of its excellence or is this just a serious hobby that makes you happy? I'm not trying to be a jerk asking these questions. All I'm asking is what makes a retro BASIC programmer tick?

A little from column A, a little from column B.

Seriously though, Sinclair BASIC wasn't that amazing - it was slower than BBC BASIC (though quicker than C64) and the underlying hardware meant that the graphics were quite restricted. What made it a joy to code was things like its string slicing, which was incredibly flexible without using up tokens for LEFT$/RIGHT$/MID$ - or any tokens at all for that matter - and easy access to user defined character sets/graphics. To do anything interesting the BBC user had to delve into VDU commands which was in no way intuitive or accessible. Even the enormous flexibility of the FOR .. NEXT system was nowhere to be seen in other implementations - you could set up a loop and have multiple NEXTs for that same loop...

But as for me being a "retro BASIC programmer?" Well, yes, that I am - despite being a professional programmer, I do love BASIC. I started with it when I was very, very young and no matter what I did it was never fast enough; sprites and speedy graphics or sound were exclusively the domain of the assembly programmer. Of course, new faster CPUs were always on the horizon and I envisaged a day when the CPU would be fast enough that I could program in BASIC producing games and applications at the level of MC back then.

Of course, as CPUs increased in power so did the applications we demanded of them and that never happened. I moved on from BASIC to Pascal, C, Asm in various flavours etc. And one day I decided that I would write a BASIC interpreter that brought my favourite dialect up to scratch.

Hence, I wrote a z80 emulator - which when paired with the right ROM Image ran the BASIC. After that I added hooks into that ROM image to allow an editor to pass BASIC code in and out. Then I cranked the speed up, but the graphics were lacking (256x192 at 1 BPP with overlaid attribute colours). So after that, I wrote SpecBAS which fulfills all my needs.

I'd never written an interpreter before, so it was interesting to see how others solved the problems they came up against and compare to mine. I enjoy (as you already know) taking programs in other dialects and seeing if SpecBAS can achieve the same things.

So yes, it's a hobby. My paid work is in very low level languages and rarely goes up above C or Pascal level, but what takes me several hundred lines in those I can do in about three in SpecBAS, and that's where I get my fun.
Title: Re: Random Character
Post by: ScriptBasic on September 25, 2016, 10:58:10 PM
Quote
Looks more like Perl.  ;)
Code: [Select]
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} print $a

But it doesn't meet the criteria of the challenge.

Code: [Select]
DECLARE SUB pl_Init ALIAS "pl_Init" LIB "sbperl"
DECLARE SUB pl_Eval ALIAS "pl_Eval" LIB "sbperl"
DECLARE SUB pl_Destroy ALIAS "pl_Destroy" LIB "sbperl"

pl_Init
pl_code = """
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} print $a,'\n'
"""
pl_Eval pl_code
pl_Destroy


jrs@laptop:~/sb/sb22/perl$ scriba tomaaz_perl.sb

jrs@laptop:~/sb/sb22/perl$ scriba tomaaz_perl.sb
"
jrs@laptop:~/sb/sb22/perl$ scriba tomaaz_perl.sb
~
jrs@laptop:~/sb/sb22/perl$ scriba tomaaz_perl.sb
p
jrs@laptop:~/sb/sb22/perl$



Title: Re: Random Character
Post by: Mike Lobanovsky on September 25, 2016, 11:53:32 PM
Nice. This is my BASIC version.

Attempt #6

Code: [Select]
#APPTYPE CONSOLE
#OPTION IMPLICIT

RANDOMIZE
REPEAT 8
  DO
    ch = CHR(RANDINT(1, 255))
  LOOP UNTIL REGEXEC(ch, "[a-zA-Z0-9]")
  PRINT ch;
END REPEAT
PAUSE

Typical output:

EmHOo74t
Press any key to continue...


:)
Title: Re: Random Character
Post by: Mike Lobanovsky on September 26, 2016, 12:38:42 AM
I am curious ... ~ 12 million +/- random luck, should get to whost faster???

Ideally yes but seriously, those simplistic randomizers we're using are very weak indeed. For example, my

#define randChar() "?' ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rand() % 29]

uses C standard rand() that generates 32K integers in the range of 0 <= n < RAND_MAX with more or less uniform distribution of n across the 32K integer range. But as soon as we start chomping its output in order to get the limits we'd like, we would in fact be distorting its distribution dramatically. In other words, we would inevitably elevate the risk of generating a sequence of repeated, rather than random, characters at our randChar()'s output, which would consequently nullify most of our builds because the original "Who's there?" has no repeated characters at all.

That's why I said we can play with all sorts of rnd()/rand()/randint() in our BASIC sandbox just for fun as much as we like but, if we want to do anything serious, we should resort to specialized 3rd party libraries. But are all BASICs present here equipped well enough to face this kind of a challenge? ;)
Title: Re: Random Character
Post by: ScriptBasic on September 26, 2016, 03:59:46 AM
I'm happy with the RANDOMIZE / RND functions in Script BASIC if properly seeded. I think you can get a good visual of the random effect by looking at the One Line Graphic (http://retrogamecoding.org/board/index.php?topic=476.msg3648#msg3648) post I made. (see attached image) The images were generated in the same way with one full intensity alpha channel and the attached image randomizes the alpha channel.  Another example of SB randomness is THIS (http://files.allbasic.info/Win7_GUI/alpha_circles.png) example. (done in 3 hundredths of a second on my old PoS laptop)
Title: Re: Random Character
Post by: B+ on September 26, 2016, 06:32:01 AM
Mike, I think you hit the lottery! 29 ^ 7 matches is 11 digits long, your trials are only 10 digits long.

Can not random numbers be extended by using random numbers to fill digit spots.
digit 1 is random number
digit 2 is random number
...
.
.
.
Title: Re: Random Character
Post by: Tomaaz on September 26, 2016, 07:13:11 AM
Quote
Looks more like Perl.  ;)
Code: [Select]
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} print $a

But it doesn't meet the criteria of the challenge.


It does when it's run in Perl. I don't know about your Perl extension for SB. It looks like regular expressions don't work with it. Also, '\n' will not print a newline in Perl. You need to use double quotes "\n" (for example print "$a\n"). So, there is something strange about the way your extension work.
Title: Re: Random Character
Post by: Mike Lobanovsky on September 26, 2016, 11:13:58 AM
I'm happy with the RANDOMIZE / RND functions in Script BASIC if properly seeded. I think you can get a good visual of the random effect by looking at the One Line Graphic (http://retrogamecoding.org/board/index.php?topic=476.msg3648#msg3648) post I made.

John,

If you don't believe me then probably you'd believe what Peter Verhas has to say in this regard?

Quote from: SB sources
/**RND
=section math
=display RND()

Returns a random number as generated by the C function T<rand()>. Note that this random number generator usually provided by the libraries implemented for the C compiler or the operating system is not the best quality ones.
If you need really good random number generator then you have to use some other libraries that implement reliable RND functions.
*/
COMMAND(RND)
#if NOTIMP_RND
NOTIMPLEMENTED;
#else

  /* this is an operator and not a command, therefore we do not have our own mortal list */
  USE_CALLER_MORTALS;
  RETURN_DOUBLE_VALUE( rand() )

#endif
END

/**RANDOMIZE
=section math
=display RANDOMIZE

Seed the random number generator. If the command is presented without argument the random number generator is seed with the actual time. If argument is provided the random number generator is seed with the argument following the keyword T<RANDOMIZE>.
*/
COMMAND(RANDOMIZA)
#if NOTIMP_RANDOMIZA
NOTIMPLEMENTED;
#else
  time_t timer;
  srand(time(&timer));

#endif
END

COMMAND(RANDOMIZE)
#if NOTIMP_RANDOMIZE
NOTIMPLEMENTED;
#else
  time_t timer;
  NODE nItem;
  VARIABLE ItemResult;

  nItem = PARAMETERNODE;
  if( nItem ){
    ItemResult = _EVALUATEEXPRESSION_A(nItem);
    ASSERTOKE;
    if( ItemResult )
      srand(GETLONGVALUE(ItemResult));
    else
      srand(time(&timer));
    }else{
    srand(time(&timer));
    }

#endif
END
Title: Re: Random Character
Post by: jj2007 on September 26, 2016, 04:35:02 PM
if we want to do anything serious, we should resort to specialized 3rd party libraries.

There is a good overview here (http://www.cacert.at/cgi-bin/rngresults) - a few thousand. MasmBasic's built-in Rand() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030) is also in the list.
Title: Re: Random Character
Post by: ScriptBasic on September 26, 2016, 04:47:31 PM
Quote
If you don't believe me then probably you'd believe what Peter Verhas has to say in this regard?

I never said I didn't believe you or Peter. All I said is I'm happy with the results I have obtained with SB randomizing. If there comes a day where a better resolution (like the gfx_time() replacement for NOW) RND then I'll create an C extension module function for it.



Title: Re: Random Character
Post by: Mike Lobanovsky on September 26, 2016, 09:54:01 PM
MasmBasic's built-in Rand() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030) is also in the list.

Wow, that's real cool, Jochen!

My compliments! :)


P.S.  I'm not a member of the MASM community and thus have no access to the thread you're referring to:
Quote from: JJ
- credits to Alex Bagayev for his AxRand algo
Could you possibly reveal his description of the algo and sources, if any, to us too?