#!/usr/bin/perl

use 5.043.6;
use utf8;

my $DEBUG = 1;

# Gini 2 'rectangular'
# Este indicador puede ser útil no sólo para el uso normal
# sino para cualquier otra distribución (discreta) número, valor

# Coef. de desigualdad sobre la proporción 'lineal'
# versión 2 
# (c) Jesús Lozano Mosterín 2025

# Se trata de hallar el área de la diferencia entre
# una recta desde el punto (1,1) al punto (n,V)
# vulgo número, valor (de lo que sea)
# thus, a routine for finite sum is defined by n
# 1 to n, la la la, not a great deal
# (BTW Gijón is about a 275_000 thing)
# ...
# meantime, i give a lecture on how con la punta del
# ciruelo, ejem. 
# 
# BEGIN

unless (scalar(@ARGV) >= 2){
#   say "Usage: $0 <n> <V>";
    say "Usage: $0 <numeric list> <nl> <nl> .. <nl>";
    say "";
    say "Where nl are elements of numeric list";

#   say "Where n is the population, yes it is, a finite and";
#   say "computable thing.";
#   say "V, by the way, is the mother of all interest, and subject";
#   say "to expoliation by killing all the reproductive waay of";
#   say "the, say, family of Tuscany Valley";
#   say "(by no means should you think yor shit is the Tuscany Valley)";
#   say "";
#   say "Job is not to be saint Job";
#   say "";

    exit -1;
}

my $coefgini2;
my $lambda = 0;
my ($n0, $v0) = (1, 1);   # 8-)


goto planB;

# If you're here, means you have a pair

my $n = trim($ARGV[0]);
my $V = trim($ARGV[1]);

die "Error: $n is not a integer number" if ($n =~ /[\D|\.]/);
die "Error: $V is not a number" if ( 0+$V ne $V );




$coefgini2 = gini2b( 1 .. $V * $n );

planB:
  
$coefgini2 = gini2b( @ARGV );

say "El coeficiente Gini2 = $coefgini2" if $DEBUG;

exit 3;




sub gini2b {
    
    my @dats = @_;
    
    @dats = sort {$a <=> $b} @dats;
    
    @dats = snormal( @dats );    # normalizar de min a max hacia 1 .. max
    
    
    my $n = scalar(@dats);
    
    my $V = $dats[-1];             # (n y max de 'dats' son los datos fundamentales)
    
    # lo demás como antes, o casi. Ya no hace falta simular nada.
    
# if i'm here mean i am about to do something...
# [coffe break]

    my $j;    # valor teórico atribuido al grado de avance de $n0 a $n
          # pero puede suceder que interese que este valor sea mayor o menor 
          # [pausita]

    my @p;    # es el valor real del dato en el punto


# parámetro para simular las diferentes curvas los datos
#    my $lambda = $n/2 ;
# otro parámetro posible es mayor o menor divisivilidad de $n. De momento, no
    my $areadesigualdad = 0;
    my $areatotaldevalor = 0; 
    
    $areatotaldevalor = ($n - $n0) * ($V - $v0) /2; # es un triángulo rectángulo

    for my $i ($n0 .. $n){
	$j = $v0 + ($V - $v0) * $i / ($n-$n0);   # aquí presiento que entra lo complicado
	# pq la curva de datos se supone que está 
                                       # por debajo de esto
                                       # [repausa]

    # esto es una curva imaginada para que quede siempre por debajo de $V, pero
    # que sea graduable (hay un parámetro que falta y que lo voy a llamar, muy
    # originalmente $lambda  :-)
    
	my $algo = $j - $V * abs( ($i - $lambda - $n0) / ($n - $lambda - $n0) );    # esto es 0 en $n  
    # se supone que $n es grande y se puede tirar para abajo pero no para arriba
    # con esta baraja hemos de jugar
    
	$p[$i] = $j - $algo; 
    
	$areadesigualdad += abs($j - $p[$i]);    # didáctico = on

	say "step $i)   expected $j   dato_sim $p[$i]   area_ahorro ", $areadesigualdad/$areatotaldevalor if $DEBUG == 2; 
    }

    my $coefgini2 = int (100 * $areadesigualdad / $areatotaldevalor);

    return $coefgini2;

}

sub snormal {                  # normalizar, pero en vez de entre 0 y 1 entre 1 y max   
    my @dat = @_;
    
    my $min = $dat[0];
    my $max = $dat[-1];
    
    my @datos;
    
    $datos[$_] = 1 + abs ( ($dat[$_] - $min) /$max ) * $max for (0 .. scalar(@dat)-1);
    
    for my $i (0 .. scalar(@datos) -1){
	say "$i) $datos[$i]" if $DEBUG;	                       # debería estar entre 1 y $max
    }

    return @datos;
}

