RetroBASIC
Basicprogramming(.org) => Code and examples => Topic started 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].
-
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
-
IIF is the function:
#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.
-
C'mon, John, show us yours!
-
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]
-
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]
Ah, that's a nice approach, very elegant! Why didn't I think of that :)
-
Yeah, that one would have a much better distribution profile.
Cf.:
#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...
-
Ah, that's a nice approach, very elegant! Why didn't I think of that :)
What about this one? ;)
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. ;)
-
Attempt #3:
#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.
-
Where is John??? ;D
-
Sleeping. He's an U.S. citizen, after all... ;)
-
Sleeping. He's an U.S. citizen, after all... ;)
Dammit, you can't just start a war and then disappear!
-
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:
#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[].
-
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
-
C'mon, John, show us yours!
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$
-
Oh Basic!
def randChar() = mid("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", (rnd*62)\1 + 1, 1)
for i in seq(1, 1000, 1000) do ? randChar; " ";
-
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).
-
Oh Basic!
Nice but not basic enough, Mike ;)
You want basics? Well, I've got some. Attempt #5:
#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". ;)
-
Just using Tomaz way here, but in naalaa:
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?
-
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?
-
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?
-
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.
-
Perl. Using regular expressions, of course. ;)
sub randchar() {
until ($a =~ /[A-Za-z0-9]/) {
$a = chr(int(rand(128)));
}
return $a;
}
Or something even more Perlish. ;)
sub randchar() {
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))}
return $a;
}
Or...
sub randchar() {until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} return $a}
;D
-
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?
-
Not nearly as elegant as Tomaaz method but to add to rainbow of different ways this could be done:
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; " ";
-
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:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
Generating 100000000 random chars took 364 ms - see the result?
-
CMLua (more the BASIC than the Lua way ;)):
-- 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 ... ?
-
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 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.
-
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]
Nice. This is my BASIC version.
REPEAT
ch$ = CHR$(RANDOM(256))
UNTIL REGEX(ch$, "[[:alnum:]]")
PRINT ch$
-
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!
' 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...
-
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.
-
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.
-
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?
-
from random import *
def randchar():
return "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789"[randrange(61)]
Nice. This is my BASIC version.
REPEAT
ch$ = CHR$(RANDOM(256))
UNTIL REGEX(ch$, "[[:alnum:]]")
PRINT ch$
Looks more like Perl. ;)
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} print $a
-
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.
#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
-
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???
-
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
-
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.
-
Looks more like Perl. ;)
until ($a =~ /[^\W_]/) {$a = chr(int(rand(128)))} print $a
But it doesn't meet the criteria of the challenge.
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$
-
Nice. This is my BASIC version.
Attempt #6
#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...
:)
-
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? ;)
-
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)
-
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
...
.
.
.
-
Looks more like Perl. ;)
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.
-
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?
/**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
-
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.
-
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.
-
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:
- credits to Alex Bagayev for his AxRand algo
Could you possibly reveal his description of the algo and sources, if any, to us too?