#!/usr/bin/perl

print "Sucht die guenstigste Parallelschaltung zweier bzw. dreier Widerstaende\n";
print "aus den Normreihen E12 und E24 um einen Sollwiderstandswert zu erhalten.\n";

print "Beispieleingabe: 0.17 0R12,  4K6 1M01 oder 4608\n\n";

print "Gesuchter Widerstandswert (Parallelschaltung):";
$r=1;
$r=<STDIN>;
chop($r);
$r=lc $r;

$r=~s/r/\./;
if ($r=~/(\d+)k$/){
  $r=$1*1000;
}
if ($r=~/(\d+)m$/){
  $r=$1*1000000;
}

if ($r=~s/(\d+)k(\d+)$/$1\.$2)/){
  $r*=1000;
}
if ($r=~s/(\d+)m(\d+)$/$1\.$2)/){
  $r*=1000000;
}
if (0==$r){
  print "  Unzulaessige Eingabe (0 oder nicht erkannt).\n  Beispiele: 0.3 0R3 8K8  5M33 123456\n";
  exit;
}


@e12=qw(10 12 15 18 22 27 33 39 47 56 68 82);
@e24=qw(10 11 12 13 15 16 18 20 22 24 27 30 33 36 39 43 47 51 56 62 68 75 82 91);

sub ausgabe{
  my ($v)=@_;

  if ($v<1000){
      $v=~s/\./R/;
      unless ($v=~/R/){
        $v.="R";
      }
  }else{
    if ($v<1000000){
      $v/=1000;
      $v=~s/\./K/;
      unless ($v=~/K/){
        $v.="K";
      }
    }else{
      $v/=1000000;
      $v=~s/\./M/;
      unless ($v=~/M/){
        $v.="M";
      }
    }
  }
  return $v;
}
sub build{
  @r=();
  my $n=$#reihe + 1;

  my $dekade=sprintf("%d",log($r)/log(10)+0.5) -1; #floor
  #print "Dekade=$dekade  n=$n\n";
  #Suche über 3 Dekaden (genauer sind die Widerstände ja gar nicht)
    $dez0 = 10 ** $dekade;
    $dez1 = $dez2 * 10;
    $dez2 = $dez1 * 10;

  #Baue die Reihen
  #push(@r,0);
  for ($i=0; $i<$n; $i++){
    $x= $reihe[$i] * $dez0;
    push(@r,$x) if $x >= $r;
  }

  for ($i=0; $i<$n; $i++){
    $x= $reihe[$i] * $dez1;
    push(@r,$x) if $x >= $r;
  }

  for ($i=0; $i<$n; $i++){
    $x= $reihe[$i] * $dez2;
    push(@r,$x) if $x >= $r;
  }

 print "\n\nProbiert mit:";
 print join(' ',@r);
 print " :\n";
 
}
sub calc2{
  build();
  $n=$#r + 1;
  $best=9999999999;

  #Probier einfach alle durch... (sind maximal (24*3)**2=5184)
  #print "*** N=$n \n";
 @alt=();
  for ($i=0; $i<$n; $i++){
    for ($j=0; $j<$n; $j++){
      $x=1/((1/$r[$i]) + (1/$r[$j]));
      if (abs($x-$r) <= $best){
        $ist =substr($x,0,8);
        $r1=$r[$i];
        $r2=$r[$j];
        @alt=() if (abs($x-$r) < $best);
        $best=substr(abs($x-$r), 0, 8);
        $pcent=sprintf("%1.2f",(($ist-$r)/$r)*100);
        $r1=ausgabe($r1);
        $r2=ausgabe($r2);
        push(@alt, sprintf("-> $ist Ohm aus $r1 | $r2 \t($e) $best Ohm Abweichung ($pcent%) \n"));
      }
      #last if $x<$r;
    }
  }
  print @alt;
}

sub calc3{
  build();
  $n=$#r + 1;
  $best=9999999999;
 @alt=();
  #Probier einfach alle durch... (sind maximal (24*3+1)**3=389017)
  for ($i=0; $i<$n; $i++){
    for ($j=0; $j<$n; $j++){
      for ($k=0; $k<$n; $k++){
        $x= 1/((1/$r[$i]) + (1/$r[$j]) + 1/($r[$k]));
        if (abs($x-$r) <= $best){
          $ist =substr($x,0,8);
          $r1=$r[$i];
          $r2=$r[$j];
          $r3=$r[$k];
          @alt=() if (abs($x-$r) < $best);
          $best=substr(abs($x-$r), 0, 8);
          $pcent=sprintf("%1.2f",(($ist-$r)/$r)*100);
          $r1=ausgabe($r1);
          $r2=ausgabe($r2);
          $r3=ausgabe($r3);
          push(@alt, sprintf("=> $ist Ohm aus $r1 | $r2 | $r3 \t($e) $best Ohm Abweichung ($pcent%) \n"));
        }
        #last if $x<$r;
      }
    }
    $pcent=sprintf("%1.2f",(($ist-$r)/$r)*100);
  }
  print @alt;
}


print "\n----------- 2 Bauteile ------------------------\r\n";
#main
$e="E12";
@reihe=@e12;
calc2();

$e="E24";
@reihe=@e24;
calc2();

print "\n----------- 3 Bauteile ------------------------\r\n";

$e="E12";
@reihe=@e12;
calc3();

$e="E24";
@reihe=@e24;
calc3();

getc;
#EOF
