in reply to How to transpose lines faster?

I would have used with_substr() (in the spoiler), but your chop-based is faster during my test. However, if the character '0' (ASCII 48) is in your possible alphabet, chop() won't give the right answer

update: chop will fail because you're testing the truthiness of the character it returns. '0', like 0, is false.

update 2: hmm, no, you should be testing the truthiness of the whole string. When I had '0' in my alphabet, it dropped one or more '0's from the last row of @$wch... Oh, right, if the last character in one of the strings in @original ends in one or more zeroes, then it will evaluate to false, rather than your expected true. So if '0' might be in your alphabet, you should probably test the if length($_) instead.

update 3: I meant while length $_...

Replies are listed 'Best First'.
Re^2: How to transpose lines faster?
by pryrt (Abbot) on Feb 01, 2018 at 22:23 UTC

    yeah, the while length $_ will do it; see modified code

    #!/usr/bin/env perl -l use warnings; use strict; use Benchmark qw/timethese cmpthese/; use Test::More; my @az = ('a'..'z', 'A'..'Z', '1'..'9'); # note: if '0' is in your +alphabet, chop() will fail my @golden_original; my $N = 2000; for( 1 .. $N ) { push @golden_original, join '', (map { $az[rand @az] } 1..$N-5), +'0'x5; } #print length($str), qq(\t"$str"); #print scalar @golden_original; #diag explain org => \@gold +en_original; my $wcf = [with_chop_fixed(@golden_original)]; #diag explain wcf => $w +cf; my $wch = [with_chop (@golden_original)]; #diag explain wch => $w +ch; my $wsp = [with_split (@golden_original)]; #diag explain wsp => $w +sp; my $wsu = [with_substr (@golden_original)]; #diag explain wsu => $w +su; is_deeply( $wch, $wsp, 'your chop vs split'); is_deeply( $wcf, $wsp, 'my chop vs split'); is_deeply( $wsu, $wsp, 'substr vs split'); sub with_split { my @original = @_; my @transposed; for( @original ) { my $i = 0; $transposed[$i++] .= $_ for split //; } return @transposed; } sub with_chop { my @original = @_; my @transposed; for( map $_ = reverse, @original ){ my $i = 0; $transposed[ $i ++ ] .= chop while $_; } return @transposed; } sub with_chop_fixed { my @original = @_; my @transposed; for( map $_ = reverse, @original ){ my $i = 0; $transposed[ $i ++ ] .= chop while length $_; } return @transposed; } sub with_substr { my @original = @_; my $w = scalar @original; my @transposed = ( ' 'x$w ) x $w; for my $i ( 0 .. $#original ) { for my $j ( 0 .. $i ) { substr($transposed[$i], $j, 1) = substr($original[$j], $i, + 1); substr($transposed[$j], $i, 1) = substr($original[$i], $j, + 1); } } return @transposed; } #my $r = timethese( -5, { # with_substr => sub { with_substr( @golden_original ); }, # with_split => sub { with_split ( @golden_original ); }, # with_chop => sub { with_chop ( @golden_original ); }, #}); #cmpthese $r; done_testing();
      Thank you, pryrt, for nice analysis, and thanks for finding a bug with '0'.