#!/usr/bin/perl -w

use strict;

my $MAX = 4;
my ($n, $dir, $type) = @ARGV;
die unless defined $dir;

unless (defined $type) {
  foreach (1 .. $MAX) {
    system("time $0 $n $dir $_");
    print "\n"; 
  }
  exit 0;
}

my @files = <$dir/*>;
my @big = map { @files } 1 .. $n;
my @result;

if ($type == 1) {
  @result = sort { -s $a <=> -s $b } @big;
} elsif ($type == 2) {
  @result =
    map { $_->[0] }
    sort { $a->[1] <=> $b->[1] }
    map { [$_, -s] }
    @big;
} elsif ($type == 3) {
  my %h = ();
  @result = sort { eval { $h{$a} = -s $a unless defined $h{$a}; $h{$a}; }
                   <=>
                   eval { $h{$b} = -s $b unless defined $h{$b}; $h{$b}; } }
                 @big;
} elsif ($type == 4) {
  my $fref = memoize(sub { -s $_[0] });
  @result = sort { &$fref($a) <=> &$fref($b) } @big;
}

print ("Type $type:  ".(scalar @result)."\n");

sub memoize {   # only memoizes unary functions at the moment
  my $f = shift;
  my %h = ();
  return sub {
    my $x = shift;
    $h{$x} = &$f($x) unless defined $h{$x};
    return $h{$x};
  }
}
