On Mon, 25 Mar 2002 at 12:23:43 -0800, resi dencia wrote:
>
> Hmm.. very interesting.. each university has one team, each time has 3 people, total
>5 hours of programming. Languages C, C++, Java and Pascal are allowed to use.
> So, here is chance to prove either you are smarter than top college
> students, or Perl is a better programming language!:)
The latter...
> Give yourself 15 hours, solve more than 6 questions! (SJTU, MIT, UW,
> Tsinghua, Stanford solved 6 of 9 questions)
It's not as simple as that, of course - they only had one computer
between three people. Makes it a more subtle organisational problem. But
as an experiment, I solved the first problem. My solution produces the
right answer for the meagre and poorly-chosen test case (deliberately
poorly-chosen? hmm...) but I haven't checked in detail its solutions to
more complex setups.
The attached file (solution to problem A, "Balloons in a Box")
represents 72 minutes of effort on my part, starting from a familiar
environment. Not NT :-), but I did use exactly the version of text
editor that was available.
Students of perl style will find much to amuse them. I see that
some subs have prototypes, and some not. The code which wound up in
testball was inline to start with, until I thought about how to iterate
over all permutations. It became recursion, so we now have two instances
of @b. No time to fix it, of course. No time to fix anything.
I estimate I wasted about 10 minutes chasing stupid coding blunders,
mostly to do with indecisiveness about whether I was using arrays or
ref-arrays. I forgot to put "-w" on at the outset, which would have
saved about half of that time.
I had looked at the problems ahead of time, but didn't read the rules
closely or conciously think about the problem until I started. On
reading the others, some of them are noticably more difficult than the
balloons problem.
I now see that my script doesn't "Place a blank line after each test
case", so that's a 20 minute penalty :-(
Ian
#! /usr/local/bin/perl -w
# Subs
$pi = 2 * atan2(1,0);
sub min{
my $min = shift;
while(@_) { $min = $_[0] if $min > $_[0]; shift }
$min;
}
sub dist($$){
my($x1,$y1,$z1,$r1)=@{$_[0]};
my($x2,$y2,$z2,$r2)=@{$_[1]};
sqrt( ($x1-$x2)**2 + ($y1-$y2)**2 + ($z1-$z2)**2 ) - $r2;
}
sub towall {
my $b = $_[0];
min map{ (abs( $box1->[$_] - $b->[$_] ), abs( $box2->[$_] - $b->[$_] ) ) } 0..2;
}
sub testball
{
my @b = @_;
# Blow up balloons
for $ball (0..$#b) {
my $b = $b[$ball];
my $mindist = min towall($b[$ball]),
map { $ball==$_ ? () : dist( $b[$ball], $b[$_] ) } 0..$#b;
$b[$ball][3] = $mindist;
}
# Compute enclosure
my $enclosure = 0;
$enclosure += ($_->[3])**3*4*$pi/3 for @b;
#printf "%.1f ", $enclosure;
# Test for optimum ordering
$max_enclosed = $enclosure if $enclosure > $max_enclosed;
# We don't need the actual ordering, but remember it anyway:
# @best_order = @b;
# Deflate balloons
$_->[3]=0 for @b;
}
# Recursive random sort
sub recurse($$);
sub recurse($$) {
my( $pool, $filled ) = @_;
return testball(@$filled) if @$pool == 0;
for (0..$#$pool) {
my @p = @$pool;
my $f = splice @p,$_,1;
recurse( [@p], [@$filled,$f] );
}
}
# Parse
$testcase=1;
while( $count = <> )
{
last if $count == 0;
$box1=[ split' ', <> ];
$box2=[ split' ', <> ];
@b=();
push @b,[(split ' ',<>),0] while $count-- > 0;
$max_enclosed = 0;
# Iterate over every order of balloons
recurse(\@b, []);
# results
$boxvol = 1; $boxvol *= abs($box1->[$_]-$box2->[$_]) for 0..2;
$not_enc = int( 0.5 + $boxvol - $max_enclosed );
print "Box $testcase: $not_enc\n";
$testcase++;
}