Project Euler Problem 11 on the HP 48GX? - Printable Version +- HP Forums (https://archived.hpcalc.org/museumforum) +-- Forum: HP Museum Forums (https://archived.hpcalc.org/museumforum/forum-1.html) +--- Forum: Old HP Forum Archives (https://archived.hpcalc.org/museumforum/forum-2.html) +--- Thread: Project Euler Problem 11 on the HP 48GX? (/thread-187292.html) |
Project Euler Problem 11 on the HP 48GX? - Peter Murphy (Livermore) - 07-06-2011 I have a 48GX, bought Not Working and revived by Randy Sloyer. I am using Project Euler to help me learn to use it, purely for fun; I have no practical application in mind. Project Euler Problem 11 seeks the largest product of four adjacent integers in a 20 x 20 matrix. I solved it by compiling a list of the maximum such products for each row, column, and diagonal and then using RNRM to extract the greatest of those.
Can anyone suggest smarter ways to solve the problem, and/or applicable commands more sophisticated than those required to extract rows, columns, and diagonals?
Re: Project Euler Problem 11 on the HP 48GX? - Gilles Carpentier - 07-07-2011 Hi, I solved it like this (with the 50G). My solution is quick & dirty and not very smart. I am not sure it's pefect but it gave the good answer. I remember now i was lucky to find the solution without testing others diagonals (just few lines to add). The first try was the good one so i stopped here. How do you do with RNRM ? EDIT : "I solved it by compiling a list of the maximum such products for each row, column, and diagonal and then using RNRM to extract the greatest of those." To find the greatest value (num, alpha ...) in a list , you can also do : << MAX >> STREAM
Edited: 7 July 2011, 4:13 a.m.
Re: Project Euler Problem 11 on the HP 48GX? - Peter Murphy (Livermore) - 07-07-2011 Hello Gilles, And thanks for the helpful reply. You say, "To find the greatest value (num, alpha ...) in a list , you can also do : << MAX >> STREAM" That's clearly the best way; thanks for pointing out the MAX/STREAM combination and for showing me the format that makes it work. They're both valuable lessons, and just what I hoped for when I posted this. To use RNRM I had to turn the list into an array with OBJ-> ->ARRY, a waste of time.
To extract the oppositely directed diagonals, I extracted all the columns, made them a list, used REVLIST to reverse them, and reconstituted the matrix. Then I could use ->DIAG as before. Is there a better way to do that? Would a loop to swap symmetrically located pairs of matrix columns be better, for example? Unfortunately, I am a very poor reader of RPL, so I can't appreciate any additional lessons contained in your code. All the best,
Peter
Re: Project Euler Problem 11 on the HP 48GX? - Oliver Unter Ecker - 07-07-2011 Nice code, Gilles! (As always...) I skipped this problem when I worked through the first PE problems because it just seemed tedious and unrewarding...
Peter's mention of \->DIAG instilled some curiosity and glimpse of a possible elegant solution. Here's the RPL+ result:
<< #11_data =m
The new command "diagonals" returns a matrix of the diagonals of a given matrix, and "flip" mirrors a matrix horizontally. The running max product is maintained on the stack, and I believe that should also be applicable to your solution, and maybe speed things up somewhat. (It does make the code smaller.) The solution thread to this problem reveals there were no clever solutions. Everyone brute-forced it and many guessed the right numbers. The solutions in "J" are concise but (to me) not exactly readable.
Oh, in RPL+, lists and vectors are unified. Hence no need for conversions back and fro. G - Gilles Carpentier - 07-07-2011 Hello ! You wrote : "I had to turn the list into an array with OBJ-> ->ARRY, a waste of time." AXL do the job and toggle list <-> matrice : { 1 2 3 } AXL -> [ 1 2 3 ] [ 1 2 3 ] AXL -> { 1 2 3 } It's very quick (but i've a doubt. perhaps it's a new 49/50 command) About ->DIAG, as I understand it returns only the larger diagonal... "Would a loop to swap symmetrically located pairs of matrix columns be better, for example?" Have you try the TRAN command ?
TRAN (not sure it works on a 48...) Generaly, you can avoid using loops for list processing with DOLIST and DOSUBS commands
Edited: 7 July 2011, 6:44 p.m.
Re: G - Oliver Unter Ecker - 07-07-2011 If TRAN doesn't exist, TRN will (this one's been around since the 28C), which does the same for real matrices.
DOSUBS is so worth learning... it's the swiss army knife of list processing.
Re: Project Euler Problem 11 on the HP 48GX? - Gilles Carpentier - 07-07-2011 Hi ! Oliver Unter Ecker wrote : "The running max product is maintained on the stack, and I believe that should also be applicable to your solution, and maybe speed things up somewhat. (It does make the code smaller.)"
Very fine ! It works ;) «
I don't like at all my diagonals solution ;)
Edited: 8 July 2011, 1:49 a.m.
Re: G - Peter Murphy (Livermore) - 07-08-2011 Bonjour Gilles, ->DIAG indeed returns a vector that contains the major diagonal elements of a matrix. But the input matrix does not have to be square. So if I lop off the leftmost column (or the topmost row) of a 20 x 20 matrix, ->DIAG will return a vector containing 19 elements; lop off another column (or another row) and get a vector containing 18 elements. etc. COL- or ROW- do the surgery. Thus I get all 33 diagonals of the principal orientation. I had hoped that taking the transpose of the matrix would allow me to get the oppositely oriented diagonals, but it does not; TRN swaps column 1 with row 1, column 2 with row 2, ..., column 20 with row 20, but it leaves those diagonals in the same orientation. Swapping columns 1 and 20, columns 2 and 19, ..., and columns10 and 11 does the trick, however. That's where I chose to extract the columns as a list, reverse the list, and reconstitute the matrix; a loop seemed to be the only other way to do the swapping. Thanks very much for suggesting DOLIST and DOSUBS as a better alternative. Add those to MAX and STREAM, you've enlarged my vocabulary by four comands. Now I must learn how to use them! All the best, Peter
Re: Project Euler Problem 11 on the HP 50G? - Gilles Carpentier - 07-10-2011 Here is new idea to tests the 2 diagonals: «
Edited: 10 July 2011, 3:01 p.m.
Re: Project Euler Problem 11 on the HP 28C/S ? - C.Ret - 07-11-2011 Hi,
In comparison, here is the way I resolve Euler11 on my HP 28S. First step is to enter the array of 20x20 datas. This is really a lot of typing (and double check), HP28C/S have no i/o facility.
[[ 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 ]
Thericaly, we have 8 directions to consider: left, right, up, down, up-left, up-right, down-right, down-left. The reduce set of scan we have to perform are only horizontal, vertical, direct diagonal (down-right '\') and indirect diagonal (up-right or '/') of the matrix. This is dividing the number of scans by two.
Now, considering the organization of the data matrix, one may notice a regular disposition of the element position (or indexes): [[ 1 2 3 ... 18 19 20 ] This mean that horizontal scanning can be performed by increasing indexes by one, vertical scanning by increasing index by 20, direct diagonal scanning by increasing index of 21 or 19 for inderct diagobal.
Horizontal indexing vertical indexing diagonal \ indexing diagonal / indexing
To minimize computation time, I paln to scan the entire data matrice only one time, from element 1 up to 400. At each step, the HP28S have to compute product of consecutive element in the four directions by playing with index increases from this INDEX table : [[ 0 1 2 3 ] @ horizontal Please note that we don’t have to scan the full matrix since the last 3 lines and the 3 last columns are already involved in previous steps of the run. This reduce again the among of computation, only 72.25% of the matrix positions have to be consider.
This lead to the ‘quite’ brute force scan algorithm : «This code is a bit “crude”. It uses no elaborated strategy or sophisticate instruction, since HP28C/S have few appropriate commands for matrix manipulations. By the less, any of you who have any idea or comment or any other strategy to optimize this problem on aged RPL is welcome. Re: Project Euler Problem 11 on the HP 28C/S ? - Gilles Carpentier - 07-11-2011 Bonjour C.Ret ! I like your sense of bytes economy and optimisation :D I like the idea of a index table.
But is there a problem here ? : it seems to me your algo don't test horizontal & vertical products for the lines 18 to 20 ? Edited: 11 July 2011, 7:01 a.m.
Re: Project Euler Problem 11 on the HP 28C/S ? - C.Ret - 07-11-2011 Bonjour Gilles
You are right! My code miss to check any horizontal products from line 18 to 20 as well as any vertical products from column 17 to 20 !
I have to correct my code by using a more ‘complex’ approach! As testing if line, row (l,c) element are in the correct interval is too much code and tests, I propose to short-cut all these tests by using the IFERR THEN END structure. Any attempt to get an element out of the matrix bound will be detected and trapped.
[[
Thank you for your attentive readings !
Re: Project Euler Problem 11 on the HP 28C/S ? - Gilles Carpentier - 07-11-2011 Hi,
another way would be to add 3 lines and columns fill with 0 and use your first version just changing the loop values
Re: Project Euler Problem 11 on the HP 28C/S ? - C.Ret - 07-12-2011 Yes, you are right again. Extending the matrix and padding the matrix with 0 makes it ! But, why padding with 0, why not with 1 ? Supposing we have en matrix full of low numbers (i.e. less than 20), and suppose that the greatest products appears to be at one borders with only 2 or 3 elements (supposing that only border's element are great numbers! Perhaps, I may change my last version by returning 1 instead of 0 ?
Another question is whenever or not is it needed to take this border effect into consideration? That's the problem with Euler, of few of us may get the expected answer by using an erroneous algorithm or a buggy code!
|