diff options
| author | drbaggy <js5@sanger.ac.uk> | 2022-05-28 02:08:33 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2022-05-28 02:08:33 +0100 |
| commit | 771185091d026257be9401f0d8d50edc7bace2a3 (patch) | |
| tree | 935ff1e352f74d5f8a82264481325fe12b99ba7c | |
| parent | 366b5e801e4ded0a9a75c093b16ee6fcd0b614a2 (diff) | |
| download | perlweeklychallenge-club-771185091d026257be9401f0d8d50edc7bace2a3.tar.gz perlweeklychallenge-club-771185091d026257be9401f0d8d50edc7bace2a3.tar.bz2 perlweeklychallenge-club-771185091d026257be9401f0d8d50edc7bace2a3.zip | |
new code
| -rw-r--r-- | challenge-166/james-smith/perl/ch-2-ns.pl | 6 | ||||
| -rw-r--r-- | challenge-166/james-smith/perl/ch-2.pl | 193 |
2 files changed, 48 insertions, 151 deletions
diff --git a/challenge-166/james-smith/perl/ch-2-ns.pl b/challenge-166/james-smith/perl/ch-2-ns.pl index e06f9576c8..489643eb9f 100644 --- a/challenge-166/james-smith/perl/ch-2-ns.pl +++ b/challenge-166/james-smith/perl/ch-2-ns.pl @@ -1,3 +1,3 @@ -(@_=split'/'),push@{$d{$_[0]}},-d?"$_[1]/":$_[1]for<*/*>;$u{$_}++for map{@{$d{$_}}}my@p=sort keys%d;$l<length?$l=length:1for@p,@_=keys%u;print$H=join('-'x($l+2),('+')x@p,'+ -'),sprintf($T="| %-${l}s "x@p.'| -',@p),$H,map({$u{$F=$_}<@p?sprintf$T,map{$d{$_}[0]ne$F?'':shift@{$d{$_}}}@p:map{shift@{$d{$_}};()}@p}sort@_),$H
\ No newline at end of file +/\//,$u{$'.'/'x-d}{$d{$`}=$`}++for<*/*>;$l<length?$l=length:1for(@p=sort keys%d),@_=keys%u;print$a=join('-'x$l,('+--')x@p,'+ +'),sprintf($b="| %-${l}s "x@p.'| +',@p),$a,map({$l=$_;@p>keys%{$u{$l}}?sprintf$b,map{$u{$l}{$_}?$l:''}@p:()}sort@_),$a diff --git a/challenge-166/james-smith/perl/ch-2.pl b/challenge-166/james-smith/perl/ch-2.pl index 282205633b..90eae65eda 100644 --- a/challenge-166/james-smith/perl/ch-2.pl +++ b/challenge-166/james-smith/perl/ch-2.pl @@ -9,94 +9,17 @@ use Benchmark qw(cmpthese timethis); use Data::Dumper qw(Dumper); # 1 2 3 4 5 6 7 8 9 +say 'Super compact'; x(); say ''; +say 'Super compact'; z(); say ''; +say 'No comments'; z_diff_no_comments(); say ''; +exit; say 'Original - fake data'; k_diff( data() ); say ''; say 'Compact - fake data'; k_diff( fetch() ); say ''; say 'Original - dir. data'; k( data() ); say ''; say 'Compact - dir. data'; k( f() ); say ''; say 'Non compact'; z_diff(); say ''; -say 'No comments'; z_diff_no_comments(); say ''; -say 'Super compact'; z(); say ''; -say 'Super compact'; x(); say ''; - -## -## Data produces/fetches -## -## * data - function returns the data structure - simple test -## * fetch - readable fetch function -## * f - compact fetch function -## - -sub data { - return ( - 'dir_a' => [sort qw(Arial.ttf Backup/ Comic_Sans.ttf Consolas.otf Georgia.ttf Helvetica.ttf Impact.otf Old_Fonts/ Verdana.ttf Wingdings.ttf)], - 'dir_b' => [sort qw(Arial.ttf Backup/ Comic_Sans.ttf Consolas.otf Courier_New.ttf Helvetica.ttf Impact.otf Tahoma.ttf Verdana.ttf)], - 'dir_c' => [sort qw(Arial.ttf Backup/ Consolas.otf Courier_New.ttf Helvetica.ttf Impact.otf Monaco.ttf Verdana.ttf)], - 'dir_d' => [sort qw(Arial.ttf Backup/ Comic_Sans.ttf Consolas.otf Courier_New.ttf Helvetica.ttf Impact.otf Monaco.ttf Verdana.ttf Wingdings.ttf)], - ); -} - -sub fetch { - my(%data,$f,$sh), opendir( my $dh, '.' ); - opendir( $sh, $f=$_ ), $data{$f} = [ map { -d "$f/$_" ? "$_/" : $_ } grep { $_ ne '.' && $_ ne '..' } sort readdir $sh ] - for grep { -d $_ && $_ ne '.' && $_ ne '..' } readdir $dh; - %data; -} - -## Super compact version of fetch {80 bytes} -#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 -sub f{my%d;(@_=split/\//),push@{$d{$_[0]}},-d$_?"$_[1]/":$_[1]for glob'*/*';%d} - -## -## Diff functions - data structure from either data(), fetch(), f() passed in -## -## * k_diff - original diff coding -## * k - compact diff coding -## - -sub k_diff { - my ($len,%dir,$F,$T) = (0,@_); - - ## Get a sorted list of directory name & unique list of flies.... - my %unique_files = map { $_ => 1 } map { @{$dir{$_}} } (my @paths = sort keys %dir); - - ## Find the length of the longest directory/file name.... - (length $_ > $len ) && ( $len = length $_ ) for @paths, keys %unique_files; - - ## Create the template for printing a padded string & the line between header/body of table... - my $TEMPLATE = '|'." %-${len}s |" x @paths; - my $LINE = "+-@{[ join '-+-', map{ '-' x $len } @paths ]}-+"; - - ## Output results as a table with line - header - line - rows - line.... - say $LINE; - say sprintf $TEMPLATE, @paths; - say $LINE; - ## Nasty and the meat of the display challenge..... - ## first line - checks to see if we have the line we have to display - ## second line - displays the files which are present - ## third line - if all the same shift them off the front of the lists... - - $F = $_, ( grep { ($dir{$_}[0]//'') ne $F } @paths ) - ? ( say sprintf $TEMPLATE, map { ($dir{$_}[0]//'') eq $F ? shift @{$dir{$_}} : '' } @paths ) - : ( map { shift @{$dir{$_}} } @paths ) for sort keys %unique_files; - - ## Just finish of the table! - say $LINE; -} - -## Super compact version of parse { 338 byes } -#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 -sub k{my$l=0;my(%d,$F,@p,%u,$T,$H)=@_;(length$_>$l)&&($l=length$_)for -keys%{{%u=map{$_,1}map{@{$d{$_}}}@p=sort keys%d}},@p; -say for($H=join'-'x($l+2),('+')x(1+@p)),sprintf($T='|'." %-${l}s |"x@p,@p),$H, -map({$F=$_;(grep{($d{$_}[0]//'')ne$F}@p)?sprintf$T,map{($d{$_}[0]//'')eq$F? -shift@{$d{$_}}:''}@p:map{shift@{$d{$_}};()}@p}sort keys%u),$H} - - -## -## Combined functions - reads directory structure as well -## ## * z_diff - original combined coding with comments ## * z_diff_no_comments - original combined coding (easy to compare with z) ## * z - compact combined coding @@ -107,7 +30,7 @@ sub z_diff { ## Declare variables ## my($l,%d,$F,@p,%u,$T,$H)=0; - my( $length, %directories, %filename_counts )=0; + my( $length, %directories, %filenames =0; ## Read all sub-directories containing files and store ## in data structure as a hash of ordered arrays @@ -115,28 +38,18 @@ sub z_diff { ## (@_=split/\//),push@{$d{$_[0]}},-d$_?"$_[1]/":$_[1]for sort<*/*>; for( sort <*/*> ) { - my($dir,$file) = split m{/}; - push @{ $directories{$dir}}, -d $_ ? "$file/" : $file; - } - - ## Get out an ordered list of directories... - - ## $u{$_}++for map{@{$d{$_}}}@p=sort keys%d; - my @paths = sort keys %directories; - - ## Find the length of the longest directory name, and - ## keep a record of the number of times each filename - ## has been seen (also gives list of all unique filenames) - - for my $path ( @paths ) { - $filename_counts{ $_ }++ for @{$directories{$path}}; + my( $dir, $file ) = split m{/}, $_; + $directories{$dir}=1; + $file.='/' if -d $_; + $filenames{ $file }{ $dir } = 1; } ## Now find the length of the longest filename or directory name ## This gives us the column widths for the pretty display... ## (length$_>$l)&&($l=length$_)for@p,keys%u; - for ( @paths, keys %filename_counts ) { + my @paths = sort keys %directories; + for ( @paths, keys %filenames ) { $length = length $_ if length $_ > $length; } @@ -161,26 +74,16 @@ sub z_diff { ## map({$u{$F=$_}<@p?sprintf$T,map{($d{$_}[0]//'')ne$F?'': ## shift@{$d{$_}}}@p:map{shift@{$d{$_}};()}@p}sort keys%u) - for my $filename ( sort keys %filename_counts ) { - - ## If we have seen the file in all directories - we remove - ## it from all directory lists {and do nothing} - - if( $filename_counts{ $filename } == @paths ) { - shift @{$_} for values %directories; - next; - } + for my $filename ( sort keys %filenames ) { - ## If we haven't we loop through the rows if - ## the first entry is the file then we push it - ## on the list to print {and remove it from the directory list} - ## if not we just push an empty string to the - ## list + ## Foreach filename - we first see it is in all columns, + ## If it is we display the filename in the appropriate columnns. + next if @paths == keys %{$filenames{$filename}}; my @columns; for (@paths) { - if( @{$directories{$_}} && $directories{$_}[0] eq $filename ) { - push @columns, shift @{$directories{$_}}; + if( exists $filenames{$filename}{$_} ) { + push @columns, $filename; } else { push @columns, ''; } @@ -201,22 +104,19 @@ sub z_diff { sub z_diff_no_comments { ## my($l,%d,$F,@p,%u,$T,$H)=0; - my( $length, %directories, %filename_counts )=0; + my( $length, %directories, %filenames )=0; - ## (@_=split/\//),push@{$d{$_[0]}},-d$_?"$_[1]/":$_[1]for sort<*/*>; + ## /\//,$u{$'.'/'x-d}{$d{$`}=$`}++for<*/*>; for( sort <*/*> ) { - my($dir,$file) = split m{/}; - push @{ $directories{$dir}}, -d $_ ? "$file/" : $file; + my( $dir, $file ) = split m{/}, $_; + $directories{$dir}=1; + $file.='/' if -d $_; + $filenames{ $file }{ $dir } = 1; } - ## $u{$_}++for map{@{$d{$_}}}@p=sort keys%d; + ## (length$_>$l)&&($l=length$_)for(@p=sort keys%d),keys%u; my @paths = sort keys %directories; - for my $path ( @paths ) { - $filename_counts{ $_ }++ for @{$directories{$path}}; - } - - ## (length$_>$l)&&($l=length$_)for@p,keys%u; - for ( @paths, keys %filename_counts ) { + for ( @paths, keys %filenames ) { $length = length $_ if length $_ > $length; } @@ -228,17 +128,13 @@ sub z_diff_no_comments { say sprintf $TEMPLATE, @paths; say $HORIZONTAL_LINE; - ## map({$u{$F=$_}<@p?sprintf$T,map{($d{$_}[0]//'')ne$F?'': - ## shift@{$d{$_}}}@p:map{shift@{$d{$_}};()}@p}sort keys%u) - for my $filename ( sort keys %filename_counts ) { - if( $filename_counts{ $filename } == @paths ) { - shift @{$_} for values %directories; - next; - } + ## map({$l=$_;@p>keys%{$u{$l}}?sprintf$b,map{$u{$l}{$_}?$l:''}@p:()}sort@_) + for my $filename ( sort keys %filenames ) { + next if @paths == keys %{$filenames{$filename}}; my @columns; for (@paths) { - if( @{$directories{$_}} && $directories{$_}[0] eq $filename ) { - push @columns, shift @{$directories{$_}}; + if( exists $filenames{$filename}{$_} ) { + push @columns, $filename; } else { push @columns, ''; } @@ -250,19 +146,20 @@ sub z_diff_no_comments { say $HORIZONTAL_LINE; } -## Merging the fetch/parse into the a single function gives us just 357 bytes -## of perlly goodness {350 without the fn call overhead} +## Merging the fetch/parse into the a single function gives us just 272 bytes +## of perlly goodness {265 without the fn call overhead} + +#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789# +sub x{my($l,$F,%d,%u,@p)=0;/\//,$u{$'.'/'x-d}{$d{$`}=$`}++for<*/*>;$l<length?$l= +length:1for(@p=sort keys%d),@_=keys%u;print$a=join('-'x$l,('+--')x@p,"+\n"), +sprintf($b="| %-${l}s "x@p."|\n",@p),$a,map({$l=$_;@p>keys%{$u{$l}}?sprintf$b, +map{$u{$l}{$_}?$l:''}@p:()}sort@_),$a} + +## 270 bytes (263 without fn overhead) #23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789# -sub z{my($l,$F,%d,%u,$T,$H)=0;(@_=split'/'),push@{$d{$_[0]}},-d?"$_[1]/":$_[1] -for<*/*>;$u{$_}++for map{@{$d{$_}}}my@p=sort keys%d;$l<length?$l=length:1for@p, -@_=keys%u;say for$H=join('-'x($l+2),('+')x(1+@p)),sprintf($T="| %-${l}s "x@p.'|' -,@p),$H,map({$u{$F=$_}<@p?sprintf$T,map{($d{$_}[0]//'')ne$F?'':shift@{$d{$_}}}@p -:map{shift@{$d{$_}};()}@p}sort@_),$H} - -sub x{my($l,$F,%d,%u,$T,$H)=0;(@_=split'/'),push@{$d{$_[0]}},-d?"$_[1]/":$_[1] -for<*/*>;$u{$_}++for map{@{$d{$_}}}my@p=sort keys%d;$l<length?$l=length:1for@p, -@_=keys%u;say$H=join('-'x($l+2),('+')x@p,'+ -'),sprintf($T="| %-${l}s "x@p.'| -',@p),$H,map({$u{$F=$_}<@p?sprintf$T,map{($d{$_}[0]//'')ne$F?'':shift@{$d{$_}} -}@p:map{shift@{$d{$_}};()}@p}sort@_),$H} +sub z{my($l,$F,%d,%u,@p)=0;/\//,$u{$'.'/'x-d}{$d{$`}=$`}++for<*/*>;$l<length?$l= +length:1for(@p=sort keys%d),@_=keys%u;print$a=join('-'x$l,('+--')x@p,'+ +'),sprintf($b="| %-${l}s "x@p.'| +',@p),$a,map({$l=$_;@p>keys%{$u{$l}}?sprintf$b,map{$u{$l}{$_}?$l:''}@p:()}sort@_ +),$a} |
