#!/usr/bin/perl

#Sucht die günstigste Reihenschaltung zweier Widerstände aus den Normreihen E12 und E24
#um einen Sollwiderstandswert zu erhalten.
print "Sucht die guenstigste Reihenschaltung zweier bzw. dreier Widerstaende\n";
print "aus den Normreihen E12 und E24 um einen Sollwiderstandswert zu erhalten.\n";

print "Beispieleingabe: 0.3 7R12  4K6  1M01 oder 73420\n\n";


$r=1234;

print "Gesuchter Widerstandswert:";
$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

  #Suche über 3 Dekaden (genauer sind die Widerstände ja gar nicht)
    $dez2 = 10 ** $dekade;
    $dez1 = $dez2 / 10;
    $dez0 = $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 "\nProbiert mit:";
 print join(' ',@r);
 print "\n";
 print "\n";

}
sub calc2{
  build();
  $n=$#r + 1;
  $best=9999999999;

  #Probier einfach alle durch... (sind maximal (24*3)**2=5184)
  for ($i=0; $i<$n; $i++){
    for ($j=0; $j<$n; $j++){
      $x=$r[$i] + $r[$j];
      if (abs($x-$r) < $best){
        $ist =$x;
        $best=abs($x-$r);
        $r1=$r[$i];
        $r2=$r[$j];
        #$result = "$r[$i]+$r[$j]";
      }
      last if $x>$r;
    }
  }
  $pcent=sprintf("%1.2f",(($ist-$r)/$r)*100);
#  print "\n\n";
  $r1=ausgabe($r1);
  $r2=ausgabe($r2);
  print "$ist Ohm aus $r1 + $r2 \t($e) $best Ohm Abweichung ($pcent%) \n";
}


sub calc3{
  build();
  $n=$#r + 1;
  $best=9999999999;

  #Probier einfach alle durch... (sind maximal (24*3+1)**3=389017)
  for ($i=0; $i<$n; $i++){
    for ($j=0; $j<$n; $j++){
      $xx=$r[$i] + $r[$j];
      for ($k=0; $k<$n; $k++){
        $x= $xx+ $r[$k];
        if (abs($x-$r) < $best){
          $ist =$x;
          $best=abs($x-$r);
          $r1=$r[$i];
          $r2=$r[$j];
          $r3=$r[$k];
        }
        last if $x>$r;
      }
      last if $xx>$r;
    }
    $pcent=sprintf("%1.2f",(($ist-$r)/$r)*100);
  }
  $r1=ausgabe($r1);
  $r2=ausgabe($r2);
  $r3=ausgabe($r3);
  print "$ist Ohm aus $r1 + $r2 + $r3 \t($e) $best Ohm Abweichung ($pcent%) \n";
}



#main
$e="E12";
@reihe=@e12;
calc2();

$e="E24";
@reihe=@e24;
calc2();

$e="E12";
@reihe=@e12;
calc3();

$e="E24";
@reihe=@e24;
calc3();

getc;
#EOF
