#!/usr/bin/perl

# pole_trojkata_heron( $dlugosc_pierwszego_boku,
#                      $dlugosc_drugiego_boku,
#                      $dlugosc_trzeciego_boku )
#   Mozliwe jest takze podanie szesciu argumentow, ktore beda trzema parami
#   wspolrzednych (x,y) rogow trojkata.
# Procedura zwraca pole trojkata.

sub pole_trojkata_heron {
    my ( $a, $b, $c );

    if ( @_ == 3 ) { ( $a, $b, $c ) = @_ }
    elsif ( @_ == 6 ) {
        ( $a, $b, $c ) = ( odleglosc( $_[0], $_[1], $_[2], $_[3] ),
                           odleglosc( $_[2], $_[3], $_[4], $_[5] ),
                           odleglosc( $_[4], $_[5], $_[0], $_[1] ) );
    }

    my $s = ( $a + $b + $c ) / 2;               # Parametr posredni.
    return sqrt( $s * ( $s - $a ) * ( $s - $b ) * ( $s - $c ) );
}

print pole_trojkata_heron(3, 4, 5), " ",
      pole_trojkata_heron( 0, 1,   1, 0,   2, 3 ), "\n";

# Procedura odleglosc( @p ) oblicza odleglosc euklidesowa pomiedzy dwoma
# punktami o d wymiarow, dla ktorych istnieje 2 * d wspolrzednych.  Dla przykladu,
# para punktow trojwymiarowych powinna byc przekazana do tej procedury
# jako ( $x0, $y0, $z0, $x1, $y1, $z1 ).

sub odleglosc {
    my @p = @_;                 # Wspolrzedne punktow.
    my $d = @p / 2;             # Liczba wymiarow.

    # Procedura zostala zoptymalizowana dla przypadku z dwoma wymiarami.
    return sqrt( ($_[0] - $_[2])**2 + ($_[1] - $_[3])**2 )
        if $d == 2;

    my $S = 0;                  # Suma kwadratow.
    my @p0 = splice @p, 0, $d;  # Uzyskanie punktu startowego.

    for ( my $i = 0; $i < $d; $i++ ) {
        my $di = $p0[ $i ] - $p[ $i ];  # Roznica...
        $S += $di * $di;                # ...podniesiona do kwadratu i zsumowana.
    }

    return sqrt( $S );
}


