Hi lee, I decided to try to give you another chance to be educated, despite Uri's conclusion in the other thread. Hopefully you won't let me down.
On Thu, 25 May 2017 16:48:13 +0100 lee <l...@yagibdah.de> wrote: > Shlomi Fish <shlo...@shlomifish.org> writes: > > > [...] > >> >> while ( my $numbline = <DATA> ) { > >> >> chomp $numbline; > >> >> my @numbline = split //, $numbline; > >> > > >> > You're processing the input number line-by-line, but it's one whole > >> > number and the products may span across more than one line. You need to > >> > slurp it and prepare an array of digits. > >> > >> Isn't it more efficient to put all the digits into a string rather than > >> into an array and use substr()? > >> > > > > I believe it should be more space efficient, but perl shouldn't have a > > problem managing an array of a 1,000 digits on most machines. > > Yes, I'm just wondering. > > It doesn't even depend on how many digits there are because it's > possible to consider only the relevant portion of the digits in each > step. > Thinking about it one may wish to use the https://en.wikipedia.org/wiki/Stream_(computing) pattern (if one calls it that) and just keep a https://en.wikipedia.org/wiki/Circular_buffer of the last 13 or so elements. > > See https://duckduckgo.com/?q=premature+optimization+evil+quote&ia=web > > - we should worry about optimising when we need to - not before. > > I don't agree that all optimization is evil to begin with. I can not > write a line of code without optimizing first because otherwise, I > wouldn't know what to write. Can you? > > Knowing what is more efficient helps me before the first line of a > program is written and with every single line of it. I couldn't do any > overall design without knowing. > > Even syntax highlighting, reasonable formatting and reasonable use of > comments is an optimization. > > The point is to do the right amount of optimization which allows you to > make appropriate progress towards a working version. Once you have that, > you can optimize more or leave it as is. > > Programming is a creative process of optimization. > First of all note that I strongly believe the quote referred to speed / runtime optimisation - not to https://en.wikipedia.org/wiki/Code_refactoring , cleanups , bug fixes , code design and other unrelated activities. Secondly, it talked about *premature* optimisation, where you spend a lot of time optimising before there is a proven and genuine need for it. There is such a thing as "Time to market" and also needlessly changing the code always risks introducing bugs, so one should try to avoid it. > > Since we're looking at a mathematical excersise here, we might use it to > learn something about programming :) > > > Using arrays allows us to use convenient operators and functions that > > are less native to strings. > > Ok, let me be a smartass: > > substr() is only so native to strings as perl does not do implicit > typecasting. What is "typecasting" in this context? > > The operator in question is multiplication. Are there different > multiplication operators in perl which are more or less convenient? > There is https://metacpan.org/pod/List::Util#product and I also refer to array slicing (e.g @array[@indices]), map, grep, and lots of other stuff. > Did I use inconvenient operators? > > > Also note that using http://perldoc.perl.org/functions/vec.html should > > allow to store a digit within 4 bits in a binary buffer, which is even > > better than using a string. > > Hm, I don't understand this documentation. This function seems to be > designed to mess up things by confusing strings with bytes and could be > considered as a symptom of perl not having variables of fixed types. > vec uses a binary buffer as input, which is usable as a non-unicode string. > Maybe I'd understand from a safe and evident use case for it. > Let's say you want to have a https://en.wikipedia.org/wiki/Bit_array that maps non-negative integers to a false/true value. You can initialise it as all-Falses using «my $bit_vec = '';» and then set or lookup «vec($bit_vec, $idx, 1)». This is useful for https://en.wikipedia.org/wiki/Generating_primes#Prime_sieves - prime sieving. > > Some comments about your code: > > > > > [...] > >> > >> my $data = " > >> 73167176531330624919225119674426574742355349194934 > >> 96983520312774506326239578318016984801869478851843 > > [...] > >> "; > >> > > > > Please use here-documents for multi-line strings - see > > http://perl-begin.org/tutorials/bad-elements/#string-notation . > > Yes, I know. Only I always can't remember how to write those, Then look it up. > and I > don't see much of an advantage. > > This isn't supposed to be a multi-line string. If a string is one, it > can be written nicely enough, and if it isn't, it's a either a long line > or something that needs to be converted from multiple lines into one. > > Is there a way to make sure that a single-line string written in > multiple lines is converted at compile time? > don't know. > >> $data =~ s/\n//g; > >> > > > > Nice! Perhaps use \s or [^0-9] instead though. > > That would have been better. I guess I was too tired to think of it. > > >> my $adjacency = 13; > >> my $maxprod = 0; > >> > >> my $start = 0; > >> my $end = length($data) - $adjacency; > >> > >> while($start < $end) { > > > > This should be a «for my $idx ($start .. $end-1)» loop. > > Why? > > I would think using '$end - 1' is particularly bad because it needs to > be computed for each run of the loop unless the optimizer does a good > job, which I don't know. The contents of the parentheses in such a foreach loop are evaluated only once - at loop initialisation. So it's safe to rely on that. > Since I don't know and since I know that it > can't be optimized out in all cases, I always prefer to use loop > boundaries that do not need to be recalculated for each loop. --- This > is not specific to perl, and while the perl optimizer may do a good job, > optimizers for other languages might not, so generally don't use loop > boundaries that may be calculated for each loop unless it can't be > avoided. Perl is not other languages. You should write idiomatic Perl code (or idiomatic code in other languages). > > I am --- perhaps overly --- fond of using while() for loops rather than > for(). I'm finding while() loops easier to read because they are more > explicit and easier to use than for() because the notation of for() > loops in different languages varies while the notation of while() loops > does not. You also can easily turn them around by using 'do { ... } > while();' when needed, which you can't do with for() loops. > do { ... } while has bad behaviour in Perl. A better idea is to either use a closure and execute it once before the while() loop or use a $run_once variable. > So what advantage would a for() loop have, in general and particularly > in this case? I would not use '$end - 1', so the for() would require > another variable or some other kind of further ado. > > The adornments of for() loops make them intricate; while() loops are > unadorned, hence remain plain and simple, and it is good to write stuff > explicitly as long as it serves to make clear what you mean. A for() > loop doesn't help me making clear what I mean because it is intricate by > its nature. > for and foreach loops work well and are easy to understand. > >> my $adjunct = 1; > >> my $prod = substr($data, $start, 1); > >> print "$prod"; > >> while($adjunct < $adjacency) { > > > > Again. > > no :) > > >> my $ad = substr($data, $start + $adjunct, 1); > >> print " * $ad"; > >> $prod *= $ad; > >> $adjunct++; > >> } > >> print " = $prod\n"; > >> $maxprod = $prod if($maxprod < $prod); > >> > >> $start++; > >> } > >> > >> print "The largest product of $adjacency adjacent numbers is $maxprod.\n"; > >> > >> exit 0; > >> > > > > No need for the exit statement here. > > Write stuff explicitly and tidy. The program ends here, even defining a > return code. You can easily see that right away. > > Otherwise, I would need to enable the scroll bars and look at them, or > move point to the end of the buffer, or do something else to be sure. > > It's not needed but clear. I do like adornments when they're helpful. > well, it is redundant. > >> > >> Is this supposed to be a programming exercise? It's a purely > >> mathematical one to me. > >> > > > > See https://en.wikipedia.org/wiki/Project_Euler for the Project Euler > > mission and motivation. > > Why is it that everyone interested in programming is assumed to be > interested in mathematics? > P.E. is intended for such people, but it does not force itself upon you. The original poster asked about a problem they ran into with it, and I replied. There are other sites with programming challenges: * https://github.com/vhf/free-programming-books/blob/master/problem-sets-competitive-programming.md * https://github.com/shlomif/Freenode-programming-channel-FAQ/blob/master/FAQ.mdwn#i-feel-like-programming-something-but-i-dont-know-what-can-you-suggest-some-good-ideas-for-programs > I can't do mathematics at all because I understand things by removing > abstractions. Remove all abstractions from mathematics and nothing > remains. I can only use it, to some limited extend, like a computer > executes a program. That isn't very interesting, and I have computers > to do that for me so I don't need to. First of all I should note that many of the "abstractions" of maths manifest itself in nature in all kinds of places and are useful in many sciences. For example the https://en.wikipedia.org/wiki/Binary_search_algorithm run time is logarithmic. Moreover, many abstractions are independent of maths. You don't need to know how a tool works (including a computer) to use it, so this tool is an abstraction. There are many abstractions in English as well. Regards, Shlomi -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/