Discipulus has asked for the wisdom of the Perl Monks concerning the following question:
I want to add a 17th fun experiment to my project: infact there is a properties I have still not shown: the number in a specific tile is also the number of different shortest path from the top tile (no backwards move nor lateral ones).
I want to show (colorizing them) all distinct paths in sequence and to do it I need a serie of coordinates: given the following structure
0-0 1-0 1-1 2-0 2-1 2-2 3-0 3-1 3-2 3-3 4-0 4-1 4-2 4-3 4-4 5-0 5-1 5-2 5-3 5-4 5-5
if the user click the node 3-1 i need to have back:
0-0 1-0 2-0 3-1 0-0 1-0 2-1 3-1 0-0 1-1 2-1 3-1
I have asked in the chatterbox some days ago and oiskuu, Eily and Lanx were so kind to suggest various approach, but franckly i was not able to implement a simple way: infact not all combinations are valid: 0-0 1-0 1-1 2-1 3-1 contains the illigal lateral move 1-0 1-1
Well I can produce all combinations and then throw away solutions with too much moves.. but for sure exists a simpler perlish way.
Squeezing my brain I only ended with naive method to highlight the area of such valid tiles:
sub enum_area{ my ($x,$y) = split '-', $_[0]; my $minus = $x - $y; print "$_ " for grep { my ($cx,$cy) = split '-',$_; $cy > $cx ? 0 : ( $cx-$cy < $minus + 1 ? 1 : 0) } glob '{'.(join ',',0..$x).'}-'. '{'.(join ',',0..$y).'}'; }
thanks in advance
L*
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one) (2 updates)
by LanX (Saint) on Mar 22, 2018 at 12:23 UTC | |
You see in your system:
This algorithm is fixing it by recalculating the remaining left-down moves
updatein hindsight it's probably better implemented in the new coordinate system and only the results are transformed back. The code is much easier then.
Cheers Rolf
| [reply] [d/l] [select] |
by LanX (Saint) on Mar 22, 2018 at 15:12 UTC | |
> The code is much easier then. Yep!
Cheers Rolf
| [reply] [d/l] [select] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by vr (Curate) on Mar 22, 2018 at 12:55 UTC | |
Started this before LanX' answer (trying to implement whatever I understood reading the HOP):
Update. Slightly refactored version, eliminating "left agenda", i.e. pushing and immediately popping. Still, it's ugly because from initial point we can descend left and right, but from any partial solution from agenda - right only, left direction already exhausted. Hence, the "init" flag. Read more... (1346 Bytes) | [reply] [d/l] [select] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by VinsWorldcom (Prior) on Mar 22, 2018 at 11:24 UTC | |
I've recently been playing with Graph and it seems this may be a shortest path (specifically, All-Pairs Shortest Paths (APSP)) problem? The module uses the Floyd Warshall algorithm to calculate. The following creates the graph object and then calculates shortest path and prints it. Note, it only shows 1 path - have a look at the Graph perldoc on how to get all paths. (Note: I also used Graph::Convert and Graph::Easy to get the visual; it's not required to make this work.) UPDATE: Updated code to be more efficient
OUTPUT: +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ | 0-0 | --> | 1-0 | --> | 2-0 | --> | 3-0 | --> | 4-0 | --> | 5-0 | +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ | | | | | | | | | | v v v v v +-----+ +-----+ +-----+ +-----+ +-----+ | 1-1 | --> | 2-1 | --> | 3-1 | --> | 4-1 | --> | 5-1 | +-----+ +-----+ +-----+ +-----+ +-----+ | | | | | | | | v v v v +-----+ +-----+ +-----+ +-----+ | 2-2 | --> | 3-2 | --> | 4-2 | --> | 5-2 | +-----+ +-----+ +-----+ +-----+ | | | | | | v v v +-----+ +-----+ +-----+ | 3-3 | --> | 4-3 | --> | 5-3 | +-----+ +-----+ +-----+ | | | | v v +-----+ +-----+ | 4-4 | --> | 5-4 | +-----+ +-----+ | | v +-----+ | 5-5 | +-----+ 0-0 1-0 2-0 3-1 | [reply] [d/l] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by LanX (Saint) on Mar 22, 2018 at 09:39 UTC | |
Like 3-1 has You could easily do a recursion which checks and decrements $l and $r.
Cheers Rolf
*) see Re: compute paths in Pascal's triangle (aka Tartaglia's one) (2 updates) for explanation | [reply] |
by LanX (Saint) on Mar 22, 2018 at 10:43 UTC | |
I don't like that there are still wrong moves possible*, probably because I din't follow my own concept...
Cheers Rolf
*) i.e. the else branch with the warning should never be reached.
updatesolution here | [reply] [d/l] [select] |
by hdb (Monsignor) on Mar 22, 2018 at 11:48 UTC | |
Well, for any given target node you build a string of the correct number of left and right moves (or zeroes and ones) and then any permutation is one of the admissible solutions (and all of them). UPDATE: Just as illustration, using a module, and having to filter out duplicates in the permutations, it could work like this:
| [reply] [d/l] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by tybalt89 (Monsignor) on Mar 22, 2018 at 15:47 UTC | |
| [reply] [d/l] |
by LanX (Saint) on Mar 22, 2018 at 16:29 UTC | |
Cheers Rolf
| [reply] |
by tybalt89 (Monsignor) on Mar 23, 2018 at 19:48 UTC | |
Here's the functional version Re: compute paths in Pascal's triangle (aka Tartaglia's one) modified to allow a top other than 0-0.
| [reply] [d/l] |
by LanX (Saint) on Mar 25, 2018 at 23:49 UTC | |
by tybalt89 (Monsignor) on Mar 22, 2018 at 17:33 UTC | |
That would be an entirely different problem altogether </Airplane joke> | [reply] |
by LanX (Saint) on Mar 22, 2018 at 18:00 UTC | |
by tybalt89 (Monsignor) on Mar 23, 2018 at 19:52 UTC | |
| |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by roboticus (Chancellor) on Mar 22, 2018 at 17:16 UTC | |
Looks like there are already a bunch of good solutions to your problem. But I did it anyway for a bit of diversion, so rather than throwing it away, I'll add it to the list:
Update: Rather than building the paths from the root to the specified node, I took advantage of the fact that there are only 1 or 2 moves upwards from any node. Then I recursively gathered the paths upwards. I then reversed the path before printing so it looks like a path from the root to the node, instead of the node to the root. ...roboticus When your only tool is a hammer, all problems look like your thumb. | [reply] [d/l] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by oiskuu (Hermit) on Mar 22, 2018 at 20:23 UTC | |
My suggestion was to modify the recursive formula (function) to return not the sum value, but the paths themselves. Perhaps the more practical alternative is to construct an iterator. I've included both in the code below. Note that the @path have only column numbers. If you need Row-Column coordinates, zip/pairwise them with [0 .. $n] as appropriate.
The recursive formula is rather simple, and can be trivially adjusted for Row-Col pairs as well:
| [reply] [d/l] [select] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by hdb (Monsignor) on Mar 22, 2018 at 13:58 UTC | |
The property you mention is simple to prove: "the number in a specific tile is also the number of different shortest path from the top tile". In any path to a tile n-k, you have (n-k) (n minus k) moves left, and k moves right. Only the order of these moves determine the specific path. The number of possible permutations of (n-k) and k identical elements each is n! / k! / (n-k)! which is the number in the tile. | [reply] [d/l] [select] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by tybalt89 (Monsignor) on Mar 23, 2018 at 19:19 UTC | |
I was playing with this a bit, since it's such a fun little problem. Here's a version that returns the answer as the value of the function.
It's only a two statement function (of course one statement is very long :) | [reply] [d/l] |
by Discipulus (Canon) on Mar 25, 2018 at 20:48 UTC | |
I got back many interesting replies. For sure I was not there when recursive thinking was ditributed: infact I had a lot of trouble understanding your solutions, oh wise monks. LanX: thanks! you was the first giving a working solution and also some variations around it. They are also almost easy to understand as, you said, you proceded by baby steps. Anyway, if I'm permitted, I find your approach convoluted: your sub needed the top tile to passed in and goal's coordinates are external global variables. I tried to use your solution in my program but, I must admit, I discarded it soon. You are a genial problem solver but I do not want to be the man who has to debug your code ;=) hdb: I never had a doubt about you. Your is a scientific approach, where the use of Algorithm::Permute gives an idea of your stence to the problem, is clean and effective. I will not use your function just for the mere (somehow idiotic) motivation that I do not want to add a dependency to my program. I'd like to see your code explained by you. The only remark I can do to your code is that the plural form of path is paths and not pathes.. paté? ;=) I plan to use your spoken prove of the property in the help text of my project. VinsWorldcom what to say? Intelligence is using his own schemas to understand the reality. You are using nowadays the Graph module and you immediately perceived a possibility to use it to solve my question. TIMTOWTDI vr: thanks to you too; an iterative solution! I forgot to mention that I was not there also when iterative intelligence was distributed.. You were there, obviously. roboticus: you built not only the answer but the entire frame where the problem lies: a package with six methods draw the whole context. Your code is easy to read and to expand. Thanks! oiskuu you was the first to address me to a correct solution in the CB: your scientific approach using Algorithm::Combinatorics is what I suspected for the first moment it had to exists. Unfurtunately I have not a mind to imagine nor implement it tybalt89 you are born in a golf field? your solutions are sharpened as a razor: clean and straight to the goal. As Eily anticipated in the chatter box, one good option is to recurse upward. You get involved in this fun little problem as you said and you produced this:
Apart for the cleverness of the overall structure, you recurse if $row * $col > 0 and if $row > $col can you explain why? I suppose you are checking you are still within the boudaries of the triangle. Right? Anyway I tried to analize your code, just as a medieval jewish doctor dissecting a corpse watching what passed, and I arrived to:
and if I run this sub calling using Data::Dump method dd as in dd up(3-1) it produces:
I hope the above shows well what is happening and the recursion level. What I can say? genial! Now I plan (but see update below..) to use a modified version that uses AoA as input and output and not the stringy form 3-1 and, even if it is uglier to see it respect more my original intention:
The above modified version is uglier because it must to be called as up_modified ([[(3,1)]]); that is nothing good to see.. but it works returning AoA ie an array of coordinates pairs that is what I need in my project to colorize them. It produces, in this verbose version, the following output:
final words thanks you all wise monks to have contributed to this thread: I'm speachless seeing how many different approaches were proposed, each one valid and intresting on it's own. L* update March 26 it was to late.. this is simpler in construct and in what receives/returns:
There are no rules, there are no thumbs.. Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS. | [reply] [d/l] [select] |
by tybalt89 (Monsignor) on Mar 26, 2018 at 02:21 UTC | |
AoA with a less ugly call
Outputs:
And yes, the row and col checks are to stay within the triangle.
| [reply] [d/l] [select] |
by LanX (Saint) on Mar 25, 2018 at 22:08 UTC | |
Easy... ;-)
Please note, any recursion can be written as iteration. If speed matters this might be worth it. tybalt is using the same algorithm, just starting from the end (so he doesn't need to reverse the path) and more golfy.
Cheers Rolf
| [reply] [d/l] [select] |
by LanX (Saint) on Mar 26, 2018 at 08:52 UTC | |
by LanX (Saint) on Mar 25, 2018 at 21:13 UTC | |
> you proceded by baby steps. I call this maintainable. > I find your approach convoluted: your sub needed the top tile to passed in I call this flexible, it allows differing starting points > and goal's coordinates are external global variables. no I used lexicals, > I do not want to be the man who has to debug your code My fault, I expected the use of closures to be elementary. xD Put a block around it or an extra sub ... > You are a genial problem solver I'm ... running out of arguments. ;-)
Cheers Rolf
| [reply] |
|
Re: compute paths in Pascal's triangle (aka Tartaglia's one)
by tybalt89 (Monsignor) on Mar 27, 2018 at 16:19 UTC | |
Fun little regex exercise :)
| [reply] [d/l] |