Up to Main Index Up to Journal for July, 2023 JOURNAL FOR WEDNESDAY 5TH JULY, 2023 ______________________________________________________________________________ SUBJECT: Rotating strings and 32-bit time problems DATE: Wed 5 Jul 22:22:11 BST 2023 Found another little coffee break teaser[1] today. The challenge was to write the smallest program to remove the first letter from a string and append it to the end, repeat until back at the original string. With the current Mere, I managed 56 bytes: >cat string-rot.mr o=s=input;l: println s=delete s 0 1+s[0];if s<>o;goto l >wc -c string-rot.mr 56 >mere string-rot.mr WolfMUD olfMUDW lfMUDWo fMUDWol MUDWolf UDWolfM DWolfMU WolfMUD > Except, this only works for the command line version. For Mere ICE you have to replace ‘input’ with the string you want to use :/ With my local Mere I can shave off 2 more bytes for 54 bytes, due to ‘delete’ changes due in the next release: >cat string-rot.mr o=s=input;l: println s=delete s 0+s[0];if s<>o;goto l > I have also been working on the Mere ICE documentation and fixing bugs. I did say in my last posting I was going to write about one of the issues. It should be noted that once I’ve implemented int64, int32, uint64 and uint32 this will not be an issue, but for now we only have int and uint… The issue I cam across was with the time built-in. On 32-bit platforms, using a 32-bit int and a time with micro-second precision, the largest timestamp from the Unix epoch is: 1970-01-01 00:35:47.483647 +0000 UTC Hrm, a 32-bit int can only hold 35 minutes and 47.483647 seconds :( I’ve brainstormed a few ideas. My current plan is to reduce the precision of time to seconds. This makes the largest 32-bit int timestamp: 2038-01-19 03:14:07 +0000 UTC Now why does that timestamp look so familiar? [2] But, that doesn’t really cut the mustard when it comes to benchmarking. For that I’ve added a new ‘elapse’ built-in. elapse returns a string keyed map containing the time elapsed since execution started: >cat elapse.mr println literal elapse >mere elapse.mr [string]( "fraction" 4880u, "hour" 0u, "minute" 0u, "second" 0u, "stamp" "0:00:00", "stampMilli" "0:00:00.000", "stampMicro" "0:00:00.000004", "stampNano" "0:00:00.000004880", ) > Example usage with the standard counter.mr benchmark: >cat counter.mr println("123456789%") x=0 loopx: if x++ % 100000 == 0; print "." if x < 1000000; goto loopx println "✓" println "Time " (elapse,["stampMicro"]) >mere counter.mr 123456789% ..........✓ Time 0:00:00.145968 > The ‘(elapse,["stampMicro"])’ syntax used above is horrible, nasty and plain weird. It only works because I know how Mere’s internals work. This should be fixed and looking pretty once proper functions are implemented. It would be clearer to write it as: t = elapse; println "Time " t["stampMicro"] The stamp, stampMilli, stampMicro and stampNano elements are for convenience. However, using the other elements you can format the data however you want: >cat elapse-format.mr sleep 1 x=0;delay: if x++ < 10000;goto delay t = elapse println literal t println println t["hour"]*3600000u + t["minute"]*60000u + t["second"]*1000u + t["fraction"]/1000000u, "ms" >mere elapse-format.mr [string]( "fraction" 3800064u, "hour" 0u, "minute" 0u, "second" 1u, "stamp" "0:00:01", "stampMilli" "0:00:01.003", "stampMicro" "0:00:01.003800", "stampNano" "0:00:01.003800064", ) 1003ms > As can be seen in the above, I’ve also added a ‘sleep’ built-in. Not sure if sleep will stay[3], but I’ve been using it for testing… This should suffice until the additional data types are implemented, hopefully way before before 2038 :P -- Diddymus [1] String Rotation: https://codegolf.stackexchange.com/questions/177221/string-rotation-output-string-repeatedly-moving-first-character-to-the-end [2] Year 2038 problem, Y2K38: https://en.wikipedia.org/wiki/Year_2038_problem [3] I actually want to switch all, or most, of the built-ins to a library. There are already 26 and I’d rather not go adding even more… Up to Main Index Up to Journal for July, 2023