in reply to 'ls -C' column style

And here's mine, which again cycles to pick the max number of columns possible. Note that both width and spacer width can be specified.
use strict; my $width = 80; my $spacer = 2; my @files = sort(split(/\s+/, join('', <DATA>))); my ($pl, $c, $i, $j, $max, $total, @max, @sorted); while () { $pl = ($#files + 1) / ++$c; $pl = int $pl + 1 if $pl != int $pl; $total = 0; for ($i = 0; $i < $c; $i++) { $max = 0; for ($j = 0; $j < $pl; $j++) { $max = length($files[$i*$pl+$j]) if $max < length($files[$i*$pl+$j]); } $total += $max + $spacer; } last if ($width < $total - $spacer); } $pl = ($#files + 1) / --$c; $pl = int $pl + 1 if $pl != int $pl; for ($i = 0; $i < $c; $i++) { $max = 0; for ($j = 0; $j < $pl; $j++) { $sorted[$j][$i] = $files[$i*$pl+$j]; $max = length($files[$i*$pl+$j]) if $max < length($files[$i*$pl+$j]); } $max[$i] = $max + $spacer; } $max[$#max] -= $spacer; for (@sorted) { $c = 0; print sprintf('%-'.$max[$c++].'s', $_) for (@$_); print "\n"; } __DATA__ B Digest Filter MIME SDBM_File Time util ByteLoader DynaLoader GDBM_File NDBM_File Safe Unicode Cwd Encode I18N ODBM_File Socket XS DB_File Errno IO Opcode Storable attrs Data Fcntl IPC POSIX Sys re Devel File List PerlIO Thread threads

Replies are listed 'Best First'.
Re^2: 'ls -C' column style
by hv (Prior) on Nov 05, 2004 at 11:44 UTC

    Thanks for this; given the number of ways of doing:

    $pl = int $pl + 1 if $pl != int $pl;
    I'm looking forward (perhaps unwisely) to being able to define an infix ⌈...⌉ operator for ceiling().

    In general that line isn't a safe way of getting a ceiling, since it relies on equality testing of a floating point number; in this case though it would be dangerous only if the list of items were so large as to be impractical to display so it isn't really a problem. For generality I prefer the approach taken in some of the other examples above, effectively:

    sub ceildiv { my($num, $div) = @_; return int(($num + $div - 1) / $div); }
    .. and I suspect you avoided this only because you were using ++$c within the expression - I'd have preferred:
    ++$c; $pl = int((@files + $c - 1)/$c);

    Note that your approach of varying only the number of columns does miss some optimal solutions; for example, with $width = 20, $spacer = 2 you output the results in a single column even though the last 12 items could fit into a second column ('SDBM_File' being the last item that can't fit).

    Hugo