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/


Reply via email to