[VA] Short & Sweet Math Challenges #23: "May the 4th Be With You !" Special

05102018, 09:55 PM
Post: #9




[VA] Short & Sweet Math Challenges #23  My Solutions & Comments
Hi, all: Time to wrap up this S&SMC#23. Sadly, it seems it failed to grasp the attention of forum members judging by the scarcity of solutions/comments posted. I naively thought that there would be a considerable number of HP71B and Star Wars fans here that would welcome this homage to the unofficial Star Wars' Day, May the 4th, but only JF Garnier took notice and contributed his always valuable and interesting solutions and comments. Also, although the very last Step (Step the Sixth) can be solved with every HP calc model out there from the HP10C upwards (at least for 45 digits if not all 1012), no one posted anything on it, not even JF, a real pity. Anyway, these are my original solutions plus assorted comments: Step the First: "Write a program which accepts from the user an integer N from 1 to 19 and outputs the Nth digit of Log(10), the natural logarithm of 10 (= 2.302585092994045684 to 19digit accuracy)." My original solution is this 1line program (48 bytes): 1 DISP (PEEK$("0CFCD",4)&"4"&PEEK$("0D19A",14))[20VAL(DISP$)][1,1] Let's see: > 1 [RUN] 2 > 2 [RUN] 3 >18 [RUN] 8 >19 [RUN] 4 The HP71B 64 Kb ROM which holds the entire operating system and BASIC language includes a number of explicit mathematical constants to a high precision and we can make use of that fact to obtain the prestored constants without the need to compute them anew, thus saving lots of time. It's just a question of knowing their address within the ROM. My solution uses PEEK to assemble the 19digit value of Log(10) from the ROM, in reverse order, and then uses the stringslicing operator applied twice in succession not to a string variable but directly to the resulting string expression to obtain the digits from the one specified by the user to the end of the string, and once more to isolated the precise digit. The digit position specified by the user isn't stored in a variable (via INPUT, for instance) but taken directly from the display via DISP$. This fulfills the novariables requirement. Lessons learnt:  the use of PEEK$ to extract mathematical constants from the HP71B System ROM.  the use of DISP$ to obtain a value from the user without storing it in a variable  the use of the stringslicing operator [] applied directly to a string expression  the fact that the [] operator can be applied more than once in succession Step the Second: "Write a program which accepts from the user an integer N from 1 to 32 and outputs the Nth digit of Pi/2 (= 1.5707963267948966192313216916397 to 32digit accuracy)." My original solution is this 3line program (152 bytes): 1 DESTROY ALL @ X=33VAL(DISP$) @ A$=PEEK$("0DB0F",16)&PEEK$("0DA91",15) @ C=1 2 FOR I=1 TO 31 @ N=VAL(A$[I,I]) @ N$=STR$(N+N) @ IF LEN(N$)=1 THEN N$="0"&N$ 3 A$[I,I]=STR$(VAL(N$[2])+C) @ C=VAL(N$[1,1]) @ NEXT I @ DISP (A$&STR$(C))[X,X] Let's see: > 1 [RUN] 1 > 2 [RUN] 5 >31 [RUN] 9 >32 [RUN] 7 On the surface this seems exactly like the previous Step, only with another constant instead of Log(10). The difference is that while the 19digit value of Log(10) does appear in the ROM, the 32digit value of Pi/2 does not. However, the value of Pi/4 does so it's simply a matter of retrieving it from the ROM and multiply it times 2 within the requirements, in particular not using standard math functions and no arithmetical operator except + or , which my solution does digitbydigit. Once assembled, the required digit at the location specified by the user is retrieved and output. Lessons learnt:  some constants not in the ROM can be easily derived from the ones available there Step the Third: "Solve right from the command line the following equation: Sqrt(x+1) + Sqrt(x+2) + Sqrt(x+3) + ... + Sqrt(x+98) + Sqrt(x+99) + Sqrt(x+100) = 700" My original solution is this 2line commandline expression (117 characters in all): >DESTROY ALL @ DIM T$[1400] @ FOR I=1 TO 100 @ T$=T$&"+SQR(FVAR+"&STR$(I)&")" @ NEXT I >VAL("FNROOT(0,0,"&T$[2]&"700)") 3.28838856035 (correct 12digit value: 3.28838856020) The first command line dimensions a string to hold the full equation, which is then assembled into it in a simple loop, and then the second line simply completes the following expression which uses the FNROOT root from the Math ROM to solve the equation with identical initial guesses, 0 and 0. Finally, the entire expression is evaluated using VAL, immediately obtaining the root, 3.28838856035. The assembled expression which VAL evaluates is this 1307character string: FNROOT(0,0,SQR(FVAR+1)+SQR(FVAR+2)+SQR(FVAR+3)+SQR(FVAR+4)+SQR(FVAR+5)+SQR(F VAR+6)+SQR(FVAR+7)+SQR(FVAR+8)+SQR(FVAR+9)+SQR(FVAR+10)+SQR(FVAR+11)+SQR(FVAR +12)+SQR(FVAR+13)+SQR(FVAR+14)+SQR(FVAR+15)+SQR(FVAR+16)+SQR(FVAR+17)+SQR(FVA R+18)+SQR(FVAR+19)+SQR(FVAR+20)+SQR(FVAR+21)+SQR(FVAR+22)+SQR(FVAR+23)+SQR(FV AR+24)+SQR(FVAR+25)+SQR(FVAR+26)+SQR(FVAR+27)+SQR(FVAR+28)+SQR(FVAR+29)+SQR(F VAR+30)+SQR(FVAR+31)+SQR(FVAR+32)+SQR(FVAR+33)+SQR(FVAR+34)+SQR(FVAR+35)+SQR( FVAR+36)+SQR(FVAR+37)+SQR(FVAR+38)+SQR(FVAR+39)+SQR(FVAR+40)+SQR(FVAR+41)+SQR (FVAR+42)+SQR(FVAR+43)+SQR(FVAR+44)+SQR(FVAR+45)+SQR(FVAR+46)+SQR(FVAR+47)+SQ R(FVAR+48)+SQR(FVAR+49)+SQR(FVAR+50)+SQR(FVAR+51)+SQR(FVAR+52)+SQR(FVAR+53)+S QR(FVAR+54)+SQR(FVAR+55)+SQR(FVAR+56)+SQR(FVAR+57)+SQR(FVAR+58)+SQR(FVAR+59)+ SQR(FVAR+60)+SQR(FVAR+61)+SQR(FVAR+62)+SQR(FVAR+63)+SQR(FVAR+64)+SQR(FVAR+65) +SQR(FVAR+66)+SQR(FVAR+67)+SQR(FVAR+68)+SQR(FVAR+69)+SQR(FVAR+70)+SQR(FVAR+71 )+SQR(FVAR+72)+SQR(FVAR+73)+SQR(FVAR+74)+SQR(FVAR+75)+SQR(FVAR+76)+SQR(FVAR+7 7)+SQR(FVAR+78)+SQR(FVAR+79)+SQR(FVAR+80)+SQR(FVAR+81)+SQR(FVAR+82)+SQR(FVAR+ 83)+SQR(FVAR+84)+SQR(FVAR+85)+SQR(FVAR+86)+SQR(FVAR+87)+SQR(FVAR+88)+SQR(FVAR +89)+SQR(FVAR+90)+SQR(FVAR+91)+SQR(FVAR+92)+SQR(FVAR+93)+SQR(FVAR+94)+SQR(FVA R+95)+SQR(FVAR+96)+SQR(FVAR+97)+SQR(FVAR+98)+SQR(FVAR+99)+SQR(FVAR+100)700) and as you can see, both FNROOT and VAL have no problem in dealing with expressions of any length whatsoever, they're limited only by available RAM, not by the 96character limit of the commandline itself. The same is true of INTEGRAL. An alternative for the second command line would be the following: >FNROOT(0,0,VAL(T$[2])700) which is a slightly shorter (just 6 characters less) but much slower. Matter of fact the first version is 2.2 times faster, the reason being that the first expression parses the long expression to evaluate only once, then has FNROOT working with the parsed expression, while the second version has FNROOT executing VAL repeatedly as many times as needed to find and refine the root and thus parsing the long string multiple times. JF also managed to find a nice solution within the requirements (except for the fact that he uses initial guesses different from 0, which was also a requirement but that would be nitpicking) but as he uses a usercode loop within a loop it is much slower than using the assemblylanguage FNROOT and VAL applied to an expression parsed once into fast internal format. Anyway, congratulations to JF for his very clever way to achieving the stated goal. Just for fun and to demonstrate this nolimits capability even further, solving the following equation: Sqrt(x+1) + Sqrt(x+2) + Sqrt(x+3) + ... + Sqrt(x+98) + Sqrt(x+99) + Sqrt(x+200) = 2018 entails executing these command lines (118 character in all): >DESTROY ALL @ DIM T$[2800] @ FOR I=1 TO 200 @ T$=T$&"+SQR(FVAR+"&STR$(I)&")" @ NEXT I >VAL("FNROOT(0,0,"&T$[2]&"2018)") 10.4122270141 (correct 12digit value: 10.4122270160) and this time the expression which VAL evaluates is the 2708character string: FNROOT(0,0,SQR(FVAR+1)+SQR(FVAR+2)+SQR(FVAR+3)+SQR(FVAR+4)+SQR(FVAR+5)+SQR(F VAR+6)+SQR(FVAR+7)+SQR(FVAR+8)+SQR(FVAR+9)+SQR(FVAR+10)+SQR(FVAR+11)+SQR(FVAR +12)+SQR(FVAR+13)+SQR(FVAR+14)+SQR(FVAR+15)+SQR(FVAR+16)+SQR(FVAR+17)+SQR(FVA R+18)+SQR(FVAR+19)+SQR(FVAR+20)+SQR(FVAR+21)+SQR(FVAR+22)+SQR(FVAR+23)+SQR(FV AR+24)+SQR(FVAR+25)+SQR(FVAR+26)+SQR(FVAR+27)+SQR(FVAR+28)+SQR(FVAR+29)+SQR(F VAR+30)+SQR(FVAR+31)+SQR(FVAR+32)+SQR(FVAR+33)+SQR(FVAR+34)+SQR(FVAR+35)+SQR( FVAR+36)+SQR(FVAR+37)+SQR(FVAR+38)+SQR(FVAR+39)+SQR(FVAR+40)+SQR(FVAR+41)+SQR (FVAR+42)+SQR(FVAR+43)+SQR(FVAR+44)+SQR(FVAR+45)+SQR(FVAR+46)+SQR(FVAR+47)+SQ R(FVAR+48)+SQR(FVAR+49)+SQR(FVAR+50)+SQR(FVAR+51)+SQR(FVAR+52)+SQR(FVAR+53)+S QR(FVAR+54)+SQR(FVAR+55)+SQR(FVAR+56)+SQR(FVAR+57)+SQR(FVAR+58)+SQR(FVAR+59)+ SQR(FVAR+60)+SQR(FVAR+61)+SQR(FVAR+62)+SQR(FVAR+63)+SQR(FVAR+64)+SQR(FVAR+65) +SQR(FVAR+66)+SQR(FVAR+67)+SQR(FVAR+68)+SQR(FVAR+69)+SQR(FVAR+70)+SQR(FVAR+71 )+SQR(FVAR+72)+SQR(FVAR+73)+SQR(FVAR+74)+SQR(FVAR+75)+SQR(FVAR+76)+SQR(FVAR+7 7)+SQR(FVAR+78)+SQR(FVAR+79)+SQR(FVAR+80)+SQR(FVAR+81)+SQR(FVAR+82)+SQR(FVAR+ 83)+SQR(FVAR+84)+SQR(FVAR+85)+SQR(FVAR+86)+SQR(FVAR+87)+SQR(FVAR+88)+SQR(FVAR +89)+SQR(FVAR+90)+SQR(FVAR+91)+SQR(FVAR+92)+SQR(FVAR+93)+SQR(FVAR+94)+SQR(FVA R+95)+SQR(FVAR+96)+SQR(FVAR+97)+SQR(FVAR+98)+SQR(FVAR+99)+SQR(FVAR+100)+SQR(F VAR+101)+SQR(FVAR+102)+SQR(FVAR+103)+SQR(FVAR+104)+SQR(FVAR+105)+SQR(FVAR+106 )+SQR(FVAR+107)+SQR(FVAR+108)+SQR(FVAR+109)+SQR(FVAR+110)+SQR(FVAR+111)+SQR(F VAR+112)+SQR(FVAR+113)+SQR(FVAR+114)+SQR(FVAR+115)+SQR(FVAR+116)+SQR(FVAR+117 )+SQR(FVAR+118)+SQR(FVAR+119)+SQR(FVAR+120)+SQR(FVAR+121)+SQR(FVAR+122)+SQR(F VAR+123)+SQR(FVAR+124)+SQR(FVAR+125)+SQR(FVAR+126)+SQR(FVAR+127)+SQR(FVAR+128 )+SQR(FVAR+129)+SQR(FVAR+130)+SQR(FVAR+131)+SQR(FVAR+132)+SQR(FVAR+133)+SQR(F VAR+134)+SQR(FVAR+135)+SQR(FVAR+136)+SQR(FVAR+137)+SQR(FVAR+138)+SQR(FVAR+139 )+SQR(FVAR+140)+SQR(FVAR+141)+SQR(FVAR+142)+SQR(FVAR+143)+SQR(FVAR+144)+SQR(F VAR+145)+SQR(FVAR+146)+SQR(FVAR+147)+SQR(FVAR+148)+SQR(FVAR+149)+SQR(FVAR+150 )+SQR(FVAR+151)+SQR(FVAR+152)+SQR(FVAR+153)+SQR(FVAR+154)+SQR(FVAR+155)+SQR(F VAR+156)+SQR(FVAR+157)+SQR(FVAR+158)+SQR(FVAR+159)+SQR(FVAR+160)+SQR(FVAR+161 )+SQR(FVAR+162)+SQR(FVAR+163)+SQR(FVAR+164)+SQR(FVAR+165)+SQR(FVAR+166)+SQR(F VAR+167)+SQR(FVAR+168)+SQR(FVAR+169)+SQR(FVAR+170)+SQR(FVAR+171)+SQR(FVAR+172 )+SQR(FVAR+173)+SQR(FVAR+174)+SQR(FVAR+175)+SQR(FVAR+176)+SQR(FVAR+177)+SQR(F VAR+178)+SQR(FVAR+179)+SQR(FVAR+180)+SQR(FVAR+181)+SQR(FVAR+182)+SQR(FVAR+183 )+SQR(FVAR+184)+SQR(FVAR+185)+SQR(FVAR+186)+SQR(FVAR+187)+SQR(FVAR+188)+SQR(F VAR+189)+SQR(FVAR+190)+SQR(FVAR+191)+SQR(FVAR+192)+SQR(FVAR+193)+SQR(FVAR+194 )+SQR(FVAR+195)+SQR(FVAR+196)+SQR(FVAR+197)+SQR(FVAR+198)+SQR(FVAR+199)+SQR(F VAR+200)2018) which is quite a sight to behold. Lessons learnt:  That VAL and FNROOT (and INTEGRAL) can deal with expressions limited only by available RAM, not by the 96character limit of the command line. Step the Fourth: "Write a program which accepts a positive integer N from the user and outputs both the number and its square for every value from N down to 0, both included, one pair per line." As JF wrote in his nice solution, the task would be utterly trivial were it not for the novariables requirement. My original solution is this 2line (46 bytes) program: 1 DISP USING "#,^";(VAL(DISP$)+1)^2 2 DISP SQR(RES)1,RES^2 @ IF SQR(RES) THEN 2 Let's see: >15 [RUN] 15 225 14 196 13 169 ... 3 9 2 4 1 1 0 0 The trick to avoid using variables is first of all to accept a value from the user directly from the command line using DISP$, instead of inputting it to a variable, and then to store and handle it using RES, a system location which stores the value of the most recently evaluated *or displayed* numeric expression (whether real or complexvalued but not stringvalued). Thus, the first line simply puts in RES an adequate initial value for the loop in the second line by simply displaying it. Normally this would result in this spurious initial value being displayed too, as a side effect, but this is avoided by the USING image which supresses both the value and the return carriage. The second line then enters a simple loop where SQR(RES)1 retrieves and displays the next value to square and RES^2 squares it and displays the result as well. As soon as SQR(RES) reaches 0, the loop (and the program) ends. Notice that IF does *not* update the value of RES to the expression being evaluated and tested. By the way, there's another 1line version which is 49 bytes instead of 46: 1 DISP USING "#,^";(VAL(DISP$)+1)^2 @ 'A': DISP SQR(RES)1,RES^2 @ IF SQR(RES) THEN 'A' It simply uses a local label 'A' midline to implement the loop instead of a line number, thus avoiding the use of a second line. Lessons learnt:  that RES can be used to occasionally replace a variable  that USING a image we can store a value in RES without actually displaying it  that a local label midline allows looping within part of a single line Step the Fifth: "Write a program which accepts from the user a singledigit Id, then accepts from the user a text to scan for said Id and output the name associated with that Id. The format of the text to scan (up to 80 characters long, say) is as follows: (Id1):(Name1),(Id2):(Name2), ... , (IdN):(NameN) where (Id) is a single digit and (Name) is a string of up to 30 characters AZ & spaces. The Id aren't necessarily in numerical order in the text, but the Id sought for must appear somewhere within the text." This is similar in spirit to Step 4 above but with the added difficulty of having to handle two inputs (the Id to search for and the text where to search for it) without using variables. My original solution is a 2line program (74 bytes) but as no one posted any code or comment for this Step, it will be reserved for possible use at some future time. Step the Sixth: "We'll call "Selfie" to any positive Ndigit integer number which has the property that if you sum its N digits raised to the Nth power you get the original number backwards. For instance, the 7digit number 5271471 is a Selfie: 5271471 => 5^7 + 2^7 + 7^7 + 1^7 + 4^7 + 7^7 + 1^7 = 1741725, which is 5271471 backwards Write a program to find all Selfies from 1 to 9 digits long (for 10digit HP calcs, 29 in all) or from 1 to 11 digits long (for 12digit HP calcs, 37 in all). 0 is not a positive number so it's not a Selfie." Same here, no one posted any code or comments for this one either so I'll also save my original solution for a future article or something. As I said at the beginning of this post, it's a real pity as this Step was solvable (partially or in full) using most any HP calc model, and there are at least 3 ways to handle it, including brute force which will quickly become unfeasible as for 11digit numbers there would be some 90 billion numbers to try, so more sophisticated techniques are required to reach that far in reasonable times (a few minutes). By the way, I didn't ask for 12/10digit solutions because for some 12/10digit numbers the sum of their digits raised to the 12th/10th power exceeds the 12/10digit range. Also, there are no 12digit Selfies (but there's a unique 10digit one). That's all for now. Regards. V. All My Articles & other Materials here: Valentin Albillo's HP Collection 

« Next Oldest  Next Newest »

User(s) browsing this thread: