<?php
/**
* descr: Löst lineare Gleichungssysteme
*/

if (!isset($_REQUEST['gl'])) {
echo <<<EOT
<div>lineare Gleichungen eingeben:</div>
<form method="post" action="">
<textarea name="gl" cols="100" rows="30">
A+N+G+S+T=35
G+A+R+S+T+I+G=50
G+E+I+S+T=19
G+E+S+P+E+N+S+T=37
K+A+L+T=24
K+R+O+E+T+E=29
S+A+R+G=35
S+P+I+N+N+E=36

</textarea><br />
<input type="submit" />
</form>
EOT;
exit;
}

$matrix = array();
$koeffizienten = array();
$variablen = array();
$b = array();
$t uniqid();

$gln explode("\n"$_REQUEST['gl']);
foreach (
$gln as $i=>$gl) {
    if (!
trim($gl)) continue;
    
$p strpos($gl'=');
    
$links trim(substr($gl0$p));
    
$links str_replace('-''+-''0+'.$links);
    
$rechts trim(substr($gl$p+1));
    
$rechts str_replace('+''+''0+'.$rechts);
    
$rechts str_replace('+-''-'$rechts);
    
$rechts str_replace('+'$t$rechts);
    
$rechts str_replace('-''+'$rechts);
    
$rechts str_replace($t'+-'$rechts);
    
$null str_replace('*'''$links.'+'.$rechts);
    
$null str_replace(' '''$null);
    
$null str_replace('++''+'$null);
    
$null str_replace('--''+'$null);
    
$terme explode('+'$null);
    
$koeffizienten[$i] = array();
    
$b[$i] = 0;
    foreach (
$terme as $term) {
        if (
preg_match('/^(?P<koeff>-?[\\.0-9]+(\\/[\\.0-9]+)?)?(?P<var>[a-zA-Z])$/'$term$matches)) {
            if (!isset(
$koeffizienten[$i][$matches['var']])) $koeffizienten[$i][$matches['var']] = 0;
            if (empty(
$matches['koeff'])) $matches['koeff'] = 1;
            else if (
$matches['koeff'] == '-'$matches['koeff'] = -1;
            
$koeffizienten[$i][$matches['var']] += $matches['koeff'];
        } else if (
preg_match('/^(?P<koeff>-?[\\.0-9]+(\\/[\\.0-9]+)?)$/'$term$matches)) {
            
$b[$i] -= $matches['koeff'];
        } else {
            die(
'Term ungueltig: '.$term' ('.$gl.')');
        }
    }
    
$variablen array_unique(array_merge($variablenarray_keys($koeffizienten[$i])));
}

sort($variablen);

foreach (
$koeffizienten as $i=>$koeff) {
    
$matrix[$i] = array();
    foreach (
$variablen as $k=>$v) {
        if (isset(
$koeff[$v])) {
            
$matrix[$i][$k] = $koeff[$v];
        } else {
            
$matrix[$i][$k] = 0;
        }
    }
}

ausgabe($variablen$matrix$b);
for (
$i 0$i count($matrix); ++$i) {
    
eliminiereSpalte($matrix$b$i);
    
ausgabe($variablen$matrix$b);
}

function 
zeileTauschen(&$matrix, &$b$zeile1$zeile2) {
    
$t $matrix[$zeile1];
    
$matrix[$zeile1] = $matrix[$zeile2];
    
$matrix[$zeile2] = $t;
    
$t $b[$zeile1];
    
$b[$zeile1] = $b[$zeile2];
    
$b[$zeile2] = $t;
}

function 
zeileTeilen(&$matrix, &$b$zeile$divisor) {
    for (
$i 0$i count($matrix[$zeile]); ++$i) {
        
$matrix[$zeile][$i] /= $divisor;
    }
    
$b[$zeile] /= $divisor;
}

function 
eliminiereSpalte(&$matrix, &$b$spalte) {
    global 
$variablen;
    
    
// pivotzeile suchen
    
for ($i $spalte$i count($matrix); ++$i) {
        if (
$matrix[$i][$spalte] != 0) {
            if (
$spalte == $i) break;
//             echo "Tausche Zeile $spalte mit Zeile $i<br>";
            
zeileTauschen($matrix$b$spalte$i);
            break;
        }
    }
    if (
$i == count($matrix)) return;//die("nicht loesbar");
    
if ($matrix[$spalte][$spalte] != 1) {
//         echo "Teile Zeile $spalte durch ", $matrix[$spalte][$spalte], "<br>";
        
zeileTeilen($matrix$b$spalte$matrix[$spalte][$spalte]);
    }
    for (
$i 0$i count($matrix); ++$i) {
        if (
$i == $spalte) continue;
        
$pivot $matrix[$i][$spalte];
//         echo "Ziehe das $pivot-fache von Zeile $spalte von Zeile $i ab<br>";
        
for ($j $spalte$j count($variablen); ++$j) {
            
$matrix[$i][$j] -= $matrix[$spalte][$j]*$pivot;
        }
        
$b[$i] -= $b[$spalte]*$pivot;
    }
}

function 
ausgabe($variablen$matrix$b) {
    echo 
"<table border><tr>";
    foreach (
$variablen as $v) {
        echo 
"<td>$v</td>";
    }
    echo 
"<td>=</td></tr>\n";
    foreach (
$matrix as $i=>$z) {
        echo 
"<tr>";
        foreach (
$z as $a) {
            
$a += 0;
            echo 
"<td>$a</td>";
        }
        echo 
"<td>"$b[$i]*1"</td></tr>\n";
    }
    echo 
"</table><br />";
}

?>