Jump to content
carlsson

BASIC 10 Liner Contest 2021

Recommended Posts

Posted (edited)
22 hours ago, carlsson said:

That is curious. Which system are you developing for, again? Also does RND(1) generate a floating point number of an integer? Does RND(2) generate something else? I understand that the RND syntax is different for each BASIC dialect so you need to know how yours works.

 

Edit: Does AMS refer to the Amstrad CPC? I managed to get it to work as a single liner in the WinAPE emulator?

Yes, for my BASIC 10 Liner entry, I'm trying to create a 50/50 chance for the player when facing an opponent. The player can move left or right and the opponent must decide which way to attack, so if the player is lucky will avoid otherwise some energy is drained. The variable for deciding which way the attack takes place must be only -1 or 1, it cannot be 0. I tried variations in CPCBox, but it looks like the CPC needs to store the Random Number into an variable before it can be times by 2 to produce 0 or 2, but would be interested to see how you got around it, the closest I seem to get with a single line includes 0, which makes it unacceptable for what I need. :( The quickest solution to me seems to be n=RND*1:n=n*2-1 which gives me those 1 or -1 values.

Edited by AMSDOS
Adding my quickest solution.

Share this post


Link to post
Share on other sites
Posted (edited)

dmsc's solution works as well, at least in BASIC 1.1 running inside an ancient version of WinAPE. I am not sure why a different emulator would give different results, or otherwise I'm misunderstanding what you are trying to do.

 

Edit: Actually you don't need the (1) argument for RND in this dialect so that omits three characters, bringing it down to 13. However it seems that your RND generates integers, or otherwise you would get floating point numbers from -1 to 1.

 

winape-rnd.thumb.png.07a23cbd7e7aad16bec487d55ee8b25c.png

 

Edited by carlsson
  • Like 1

Share this post


Link to post
Share on other sites
6 minutes ago, carlsson said:

dmsc's solution works as well, at least in BASIC 1.1 running inside an ancient version of WinAPE. I am not sure why a different emulator would give different results, or otherwise I'm misunderstanding what you are trying to do.

 

Edit: Actually you don't need the (1) argument for RND in this dialect so that omits three characters, bringing it down to 13. However it seems that your RND generates integers, or otherwise you would get floating point numbers from -1 to 1.

 

winape-rnd.thumb.png.07a23cbd7e7aad16bec487d55ee8b25c.png

 

Hmm, okay. I wasn't sure if it would of worked due to the decimal number on account of me having BASIC in Integer mode (which improves performance), but that's not the case with this and the line can be shortened with:

a=(RND<0.5)*2+1

but seems to be the same length as my previous attempt. :D

Share this post


Link to post
Share on other sites

Yes, same number of characters but one assignment less for whatever execution time it takes to assign, retrieve and assign a variable again instead of keeping a complex calculation in temporary registers and accumulator. I wasn't aware that Locomotive BASIC could be set to integer mode, it explains a few things.

  • Like 1

Share this post


Link to post
Share on other sites

DEFINT is used to set variables to type INT, by default variables are type REAL, so it maybe common to see DEFINT a-z at the beginning, to set all variables to Type Integer. If an variable has to be another type such as a String Character, '$' following the variable can be used to specify a string type or if an REAL needs to be used '!' following the variable can be used. Another way of specifying Integer type is '%' following the variable name, though most people would say it's better to have DEFINT a-z at the beginning since there's no Bytes, Integers are mostly used variables and improves the BASIC program by telling BASIC variables will be Integer unless something else is found.

Share this post


Link to post
Share on other sites

Yeah, the A% syntax is commonly found elsewhere but those don't work with everything, e.g. usually FOR A%=1 TO 10 does not work while I presume if you use DEFINT A, it would still work except that no decimals are maintained.

 

At least we concluded that it is possible to get a random number -1 or 1 (or possibly more choices without involving zero) in a single statement.

Share this post


Link to post
Share on other sites
Posted (edited)
12 hours ago, AMSDOS said:

Yes, for my BASIC 10 Liner entry, I'm trying to create a 50/50 chance for the player when facing an opponent. The player can move left or right and the opponent must decide which way to attack, so if the player is lucky will avoid otherwise some energy is drained. The variable for deciding which way the attack takes place must be only -1 or 1, it cannot be 0. I tried variations in CPCBox, but it looks like the CPC needs to store the Random Number into an variable before it can be times by 2 to produce 0 or 2, but would be interested to see how you got around it, the closest I seem to get with a single line includes 0, which makes it unacceptable for what I need. :( The quickest solution to me seems to be n=RND*1:n=n*2-1 which gives me those 1 or -1 values.

I'm only working in Atari Basic, so not sure.  

 

In Atari, this takes up more characters but is MUCH faster (almost 30% faster).

 

A=(PEEK(53770)<128)*2-1

 

Edited by erichenneke

Share this post


Link to post
Share on other sites
11 hours ago, carlsson said:

Yeah, the A% syntax is commonly found elsewhere but those don't work with everything, e.g. usually FOR A%=1 TO 10 does not work while I presume if you use DEFINT A, it would still work except that no decimals are maintained.

 

At least we concluded that it is possible to get a random number -1 or 1 (or possibly more choices without involving zero) in a single statement.

I hadn't really thought about it before. A% works within a FOR loop and as BASIC will determine it to be an Integer, will perform faster as opposed to if 'A' variable being a decimal number. If I apply a STEP to that FOR loop, the STEP can be a Decimal Number to the accuracy of .5, if it's any lower it won't work on an Integer based variable, the loop becomes Infinite. This obviously doesn't happen if the variable is of Decimal Type. So this is probably why .5 is acceptable in the RND statement.

  • Like 2

Share this post


Link to post
Share on other sites
54 minutes ago, erichenneke said:

I'm only working in Atari Basic, so not sure.  

 

In Atari, this takes up more characters but is MUCH faster (almost 30% faster).

 

A=(PEEK(53770)<128)*2-1

 

It's a nifty trick having a spot in memory to have a random number. I'm unsure where they come from on my machine, some people use a Refresh Register 'r' as a Seed, which randomly takes a number from 0..127 I think, while others argue more (machine) code should be used to select a number across the 0..255 range, which is valid, though the question sort of becomes 'How Random do you want it?'. In BASIC I think it's using the Refresh Register as an Reference since without any RANDOMIZE a pattern emerges, though the Systems Clock can also be used with RANDOMIZE to produce a Seed for RND, though some people argue it's still not accurate enough an impose RANDOMIZE RND after a RANDOMIZE TIME. Personally, I think it's better to RANDOMIZE TIME*RND instead in case RANDOMIZE is referring to the Refresh Register.

Share this post


Link to post
Share on other sites

Yeah. On computers with a jiffy timer, sampling the lowest 8 bits often is good enough random for BASIC since it runs so slow, but for the 10Liners speed tends to be secondary, code size more important.

 

It reminds me of the time I made a crap game that must not use the RND keyword, so I implemented an own PRNG using a lagged Fibonacci function, I think it is called. It worked well and seems to have a fairly good pool of random numbers before it loops, but took a lot of code to implement of course and would be useless to have in this particular contest.

  • Like 2

Share this post


Link to post
Share on other sites
Posted (edited)

@carlsson

RE: random number -2, -1, 1, 2

 

Expanding on @dmsc method for atari basic

 

a=(rnd(0)<.5)*2-1:a=a+a*(rnd(0)<.5)

 

is one more character than

 

a=int(rnd(0)*4)*2-3:a=a-(a=3)+(a=-3)

 

but i'm sure there is a better idea.

Edited by thank you
no need for 0.5
  • Like 1

Share this post


Link to post
Share on other sites

I came up with this one, 26 characters (Microsoft syntax): A=INT(INT(RND(1)*4)*1.5)-2

 

It probably is a way to make it even shorter, without sacrificing the even distribution of the four random numbers.

Share this post


Link to post
Share on other sites

If RND is a function that returns a float between 0 and .99999999 and N is any integer, then:

A=INT(1+RND*N)*(-1)^(RND<0.5)

returns numbers from this list -N, ..., -3, -2, -1, 1, 2, 3, ..., N

 

Share this post


Link to post
Share on other sites
5 minutes ago, vitoco said:

If RND is a function that returns a float between 0 and .99999999 and N is any integer, then:

A=INT(1+RND*N)*(-1)^(RND<0.5)

returns numbers from this list -N, ..., -3, -2, -1, 1, 2, 3, ..., N

 

Shorter:

A=-1^(RND<.5)*INT(1+RND*N)

TurboBasic XL syntax, BTW.

 

  • Like 2

Share this post


Link to post
Share on other sites

Excellent, I did not think of scaling that way carlsson.

 

I did try to think of using ^ but I'm not so good at this.

 

Anyway I like to see the better ideas.

Share this post


Link to post
Share on other sites

Yes, a thread like this one is both fun and useful in trading optimization tricks. Some of these last examples perhaps are quite synthetic but we've gone from "it is not possible to generate a random number -1 or 1 in a single statement" to "it is actually possible to generate a random number in the sequence -N to +N in a single statement".

  • Like 1

Share this post


Link to post
Share on other sites

I discovered by accident, I was able to produce a series of 1s and -1s when I altered @vitoco -3 to +3 formula to:

 

A=(-1)^(RND<0.5)

 

:D

 

Share this post


Link to post
Share on other sites
1 minute ago, AMSDOS said:

I discovered by accident, I was able to produce a series of 1s and -1s when I altered @vitoco -3 to +3 formula to:

 

A=(-1)^(RND<0.5)

 

:D

 

Didn't the minus sign act as unary minus? I mean, does this work for you?

A=-1^(RND<.5)

(just to save some chars)

Share this post


Link to post
Share on other sites
6 minutes ago, AMSDOS said:

I discovered by accident, I was able to produce a series of 1s and -1s when I altered @vitoco -3 to +3 formula to:

 

A=(-1)^(RND<0.5)

 

:D

 

Nice.  In Atari Basic it must have the (0) argument on the RND to work.  However, I found that you do NOT need the parenthesis around the -1 in this case.

 

So in Atari Basic, this works...

A=-1^(RND(0)<.5)

 

 

 

  • Like 1

Share this post


Link to post
Share on other sites
2 minutes ago, erichenneke said:

 

 

So in Atari Basic, this works...

A=-1^(RND(0)<.5)

 

 

 

This is cool and it works, but it's very slow.

 

Share this post


Link to post
Share on other sites
1 minute ago, Preppie said:

This is cool and it works, but it's very slow.

 

yeah, i was just going to say the same thing. 

Share this post


Link to post
Share on other sites
7 minutes ago, vitoco said:

Didn't the minus sign act as unary minus? I mean, does this work for you?

A=-1^(RND<.5)

(just to save some chars)

No, I tried that, but I just got -1s, anything else it's Divison by Zero or Improper Argument error. I thought it was going to be shorter to what I had earlier, but it's 1 character longer, so a bit annoying.

Share this post


Link to post
Share on other sites

random acts different on emulators rather than real hardware sometimes.... consider that also

  • Like 1

Share this post


Link to post
Share on other sites
2 minutes ago, AMSDOS said:

No, I tried that, but I just got -1s, anything else it's Divison by Zero or Improper Argument error. I thought it was going to be shorter to what I had earlier, but it's 1 character longer, so a bit annoying.

I was surprised it worked, but on Atari Basic it does...

image.thumb.png.42a592eab707b8e867f97442d7c95dce.png

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...