Author Topic: RaspberryBASIC.org Forum  (Read 99523 times)

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #90 on: December 08, 2019, 09:21:54 AM »
Python 3 update.  This is as tight as I can get it at the moment.

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. r = ""
  4. a = [None] * 1000001
  5. b = bytearray(26)
  6.  
  7. for x in range(1000001):
  8.     b[x % 26] = (x % 26) + 65
  9.     a[x] = x
  10.     if x % 26 == 25:
  11.         r += b.decode()[::-1]
  12.  
  13. print("r LEN: {}".format(len(r)))
  14. print("Front: {}".format(r[:26]))
  15. print("Back:  {}".format(r[-26:]))
  16. print("UBVal: {}".format(a[1000000]))

riveraa@rpi:~/tmp $ /usr/bin/time ./mil2.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
1.32user 0.08system 0:01.41elapsed 99%CPU (0avgtext+0avgdata 27212maxresident)k
0inputs+0outputs (0major+5993minor)pagefaults 0swaps

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #91 on: December 08, 2019, 09:32:58 AM »
AIR,

I used the same concept you did for BaCon to speed up its dynamic result 'string'.

Not exactly.  I'm not writing to or reading from a file in the filesystem.  I'm still accessing a string, as an object in memory that exposes methods usually associated with files.

AIR.

Offline jalih

  • Advocate
  • Posts: 111
Re: RaspberryBASIC.org Forum
« Reply #92 on: December 08, 2019, 09:52:04 AM »
The only rule is you can't use fixed size buffers. Storage needs to be dynamic.

Most of the libraries use some sort of pre-defined buffer size and grow that buffer only if capacity is reached. It makes no sense to use fully dynamic buffer as allocating new buffer and copying current buffer contents is a very costly operation to do 38461 times in this challenge!

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: RaspberryBASIC.org Forum
« Reply #93 on: December 08, 2019, 10:31:05 AM »
Challenge Rules

1. Create an upper case A-Z  character based on the FOR index.

2. Capture the characters in a dynamic reusable string.

3. Maintain a dynamic result string / object / ...

4. Reverse the result.

ScriptBasic is still challenge compliant.

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #94 on: December 08, 2019, 11:47:52 AM »
Another Python3 update:

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. def main():
  4.     r = ""
  5.     a = [None] * 1000001
  6.     b = bytearray(26)
  7.     decode = bytearray.decode
  8.     blah = range(1000001)
  9.  
  10.     for x in blah:
  11.         b[x % 26] = (x % 26) + 65
  12.         a[x] = x
  13.         if x % 26 == 25:
  14.             r += decode(b[::-1])
  15.  
  16.     print("r LEN: {}".format(len(r)))
  17.     print("Front: {}".format(r[:26]))
  18.     print("Back:  {}".format(r[-26:]))
  19.     print("UBVal: {}".format(a[1000000]))
  20.  
  21.  
  22.  
  23. if __name__ == "__main__":
  24.     main()

riveraa@rpi:~/tmp $ /usr/bin/time ./mil4.py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.93user 0.13system 0:01.06elapsed 99%CPU (0avgtext+0avgdata 27276maxresident)k
0inputs+0outputs (0major+5997minor)pagefaults 0swaps


AIR.

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #95 on: December 08, 2019, 12:47:23 PM »
Last Python update:

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. def main():
  4.     t = []
  5.     r =""
  6.     a = [None] * 1000001
  7.     b = bytearray(26)
  8.     decode = bytearray.decode
  9.     blah = range(1000001)
  10.     append = list.append
  11.  
  12.     for x in blah:
  13.         b[x % 26] = (x % 26) + 65
  14.         a[x] = x
  15.         if x % 26 == 25:
  16.             append(t, decode(b[::-1]))
  17.  
  18.     r = ''.join(t)
  19.  
  20.     print("r LEN: {}".format(len(r)))
  21.     print("Front: {}".format(r[:26]))
  22.     print("Back:  {}".format(r[-26:]))
  23.     print("UBVal: {}".format(a[1000000]))
  24.  
  25.  
  26.  
  27. if __name__ == "__main__":
  28.     main()

r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.90user 0.09system 0:01.00elapsed 99%CPU (0avgtext+0avgdata 29532maxresident)k
0inputs+0outputs (0major+6508minor)pagefaults 0swaps


AIR.

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: RaspberryBASIC.org Forum
« Reply #96 on: December 08, 2019, 01:04:09 PM »
Now I'm glad I had that second cup of coffee before updating the Python post.  :)

Is that doing the reverse on the fly rather than waiting until the result string is built?

You can't get any greyer with that submission.
« Last Edit: December 08, 2019, 01:10:12 PM by John »

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #97 on: December 08, 2019, 01:24:33 PM »
Yes doing it on the fly, the reversed() function is stupidly inefficient especially with large strings.

I'm doing the reversal with  "[::-1]", after generating the upper case alphabet.



Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #98 on: December 08, 2019, 01:43:12 PM »
Hope you took the time for a third cup of coffee, John.   8)

FINAL PYTHON SUBMISSION

Code: Python
  1. #!/usr/bin/python3
  2.  
  3. def main():
  4.     t = []
  5.     r =""
  6.     a = [None] * 1000001
  7.     b = bytearray(26)
  8.     decode = bytearray.decode
  9.     blah = range(1000001)
  10.     append = list.append
  11.  
  12.     for x in blah:
  13.         alpha = x % 26
  14.         b[alpha] = alpha + 65
  15.         a[x] = x
  16.         if alpha == 25:
  17.             append(t, decode(b[::-1]))
  18.  
  19.     r = ''.join(t)
  20.  
  21.     print("r LEN: {}".format(len(r)))
  22.     print("Front: {}".format(r[:26]))
  23.     print("Back:  {}".format(r[-26:]))
  24.     print("UBVal: {}".format(a[1000000]))
  25.  
  26.  
  27.  
  28. if __name__ == "__main__":
  29.     main()

r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.59user 0.09system 0:00.68elapsed 99%CPU (0avgtext+0avgdata 29452maxresident)k
0inputs+0outputs (0major+6390minor)pagefaults 0swaps


I realized that I was calculating the modulo of 'x' multiple times; assigned it to a variable and it made a huge difference!

AIR.

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: RaspberryBASIC.org Forum
« Reply #99 on: December 08, 2019, 02:30:06 PM »
Saved by a litter box change.

I'll have it posted shortly.


pi@RPi4B:~/python-dev/examples $ timex python3 1mil3-2,py
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
0.68user 0.08system 0:00.78elapsed 99%CPU (0avgtext+0avgdata 29952maxresident)k
0inputs+0outputs (0major+6541minor)pagefaults 0swaps
pi@RPi4B:~/python-dev/examples $

« Last Edit: December 08, 2019, 02:54:40 PM by John »

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #100 on: December 08, 2019, 03:23:34 PM »
The only rule is you can't use fixed size buffers. Storage needs to be dynamic.

Most of the libraries use some sort of pre-defined buffer size and grow that buffer only if capacity is reached. It makes no sense to use fully dynamic buffer as allocating new buffer and copying current buffer contents is a very costly operation to do 38461 times in this challenge!

You can mitigate some of this if you use some sort of mutable dynamic buffer/array/list/etc.

For my final Python submission, I switched from using straight strings to using a list, which is analogous to an array and added to it in place.  While the size was extended when needed, copying the existing data wasn't needed.

BTW, your 8th submission only runs 1 out of 4 times on my system; the error is the same as before.

Here's the timeing on my RasPi for a successful run:

riveraa@rpi:~/tmp $ timex ./r3
r LEN: 999986
Front: ZYXWVUTSRQPONMLKJIHGFEDCBA
Back:  ZYXWVUTSRQPONMLKJIHGFEDCBA
UBVal: 1000000
1.70user 0.15system 0:01.85elapsed 99%CPU (0avgtext+0avgdata 53088maxresident)k
0inputs+0outputs (0major+12363minor)pagefaults 0swaps


AIR.

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: RaspberryBASIC.org Forum
« Reply #101 on: December 08, 2019, 03:36:50 PM »
Is a StringBuilder a buffer under the covers that one populates / resets with calls to it?

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: RaspberryBASIC.org Forum
« Reply #102 on: December 08, 2019, 03:39:59 PM »
I'm waiting for Jalih to show us a 8th submission that lives within the generous rules stated. Exposed buffer code will surely get you busted.

Offline AIR

  • BASIC Developer
  • Posts: 932
  • Coder
Re: RaspberryBASIC.org Forum
« Reply #103 on: December 08, 2019, 03:50:05 PM »
Is a StringBuilder a buffer under the covers that one populates / resets with calls to it?

Basically, yes.

Read this for some insight:  https://www.thecodingdelight.com/java-stringbuilder-class/

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: RaspberryBASIC.org Forum
« Reply #104 on: December 08, 2019, 04:03:48 PM »
What open the door for me with StringBuilder in the Java submission was the string reverse example I found. Appling it to the rest of the code made all the difference.