Formel: | " . STREICHHOLZBILDER($s_frm) . " |
\n";
$krumm = false;
for ($i = 0; $i < strlen($s_frm); $i++) {
if (strpos("0123456789+-/=",$s_frm[$i]) === false) $krumm = true;
}
if (($s_frm != $formel) || ($krumm == true)) {
print "(Kurzschreibweise: \"" . $s_frm . "\")
\n";
}
print "\n";
$ergebnis = BERECHNUNG($s_frm,$lazy);
$p = strpos($ergebnis,"gefunden:
");
if ($p > 0) {
$ergebnis = substr($ergebnis,0,$p+9) . STREICHHOLZBILDER(AUSRUF_WEG(substr($ergebnis,$p+9)));
}
print $ergebnis . "
\n";
######################################################################
### Funktion $s = STREICHHOLZBILDER($s)
######################################################################
function STREICHHOLZBILDER($s_frm) {
$s_print = ""; $s_frm = str_replace("
","#",$s_frm);
for ($i = 0; $i < strlen($s_frm); $i++) {
if ($s_frm[$i] == "+") {
$s_print .= "
";
} elseif ($s_frm[$i] == "-") {
$s_print .= "
";
} elseif ($s_frm[$i] == "x") {
$s_print .= "
";
} elseif ($s_frm[$i] == "/") {
$s_print .= "
";
} elseif ($s_frm[$i] == "=") {
$s_print .= "
";
} elseif (strpos("0123456789evsbnx",$s_frm[$i]) !== false) {
$s_print .= "
";
} else {
$s_print .= $s_frm[$i];
}
}
$s_print = str_replace("#","",$s_print);
return $s_print;
}
######################################################################
### Funktion $s_frm = AUSRUF_WEG($s_input)
### - wandelt 1! in e, 4! in v, 7! in s, 9! in n, 6! in b
### damit man bei der Eingabe spezielle Formen eingeben kann:
### - 6! bzw. b steht für eine 6 ohne oberen Querstrich
### - 1! bzw. e steht für eine 1 mit schrägem Anstrich
### - 4! bzw. v steht für eine 4, die aus einer 1! entstehen kann
### - 7! bzw. s steht für eine 7 mit senkrechtem Anstrich
### - 9! bzw. n steht für eine 9 ohne unteren Querstrich
######################################################################
function AUSRUF_WEG($s) {
for ($i = strlen($s)-1; $i > 0; $i--) {
if (substr($s,$i-1,2) == "1!") {
$s = substr($s,0,$i-1) . "e" . substr($s,$i+1);
} elseif (substr($s,$i-1,2) == "4!") {
$s = substr($s,0,$i-1) . "v" . substr($s,$i+1);
} elseif (substr($s,$i-1,2) == "7!") {
$s = substr($s,0,$i-1) . "s" . substr($s,$i+1);
} elseif (substr($s,$i-1,2) == "9!") {
$s = substr($s,0,$i-1) . "n" . substr($s,$i+1);
} elseif (substr($s,$i-1,2) == "6!") {
$s = substr($s,0,$i-1) . "b" . substr($s,$i+1);
} elseif (substr($s,$i-1,1) == "*") {
$s = substr($s,0,$i-1) . "x" . substr($s,$i);
}
}
return $s;
}
######################################################################
### Funktion $s_seg = FORMEL_TO_SEGMENTS($s_frm)
### - wandelt die Formel $s_frm in Segment-Schreibweise um
### - Jedes Zeichen der Formel wird in 10 Segmente verwandelt:
### 7 Segmente (Streichhölzer) für Zahlen
### 1 senkrechter Strich für das Plus
### 1 zweiter waagerechter Strich für das Gleichheitszeichen
### 1 schräger Strich für das Divisions-Zeichen
### - Beispiel: Die Formel "1=1" lautet in Segment-Schreibweise:
### "011000000000000010100110000000"
######################################################################
function FORMEL_TO_SEGMENTS($s_frm) {
$n_frm = strlen($s_frm); $s_seg = "";
for ($i_frm = 0; $i_frm < $n_frm; $i_frm++) {
$c = $s_frm[$i_frm];
if ($c == "0") $s_seg .= "111111000000";
elseif ($c == "1") $s_seg .= "011000000000";
elseif ($c == "e") $s_seg .= "011000000001";
elseif ($c == "2") $s_seg .= "110110100000";
elseif ($c == "3") $s_seg .= "111100100000";
elseif ($c == "4") $s_seg .= "011001100000";
elseif ($c == "v") $s_seg .= "011000100001";
elseif ($c == "5") $s_seg .= "101101100000";
elseif ($c == "6") $s_seg .= "101111100000";
elseif ($c == "b") $s_seg .= "001111100000";
elseif ($c == "7") $s_seg .= "111000000000";
elseif ($c == "s") $s_seg .= "111001000000";
elseif ($c == "8") $s_seg .= "111111100000";
elseif ($c == "9") $s_seg .= "111101100000";
elseif ($c == "n") $s_seg .= "111001100000";
elseif ($c == "-") $s_seg .= "000000100000";
elseif ($c == "+") $s_seg .= "000000110000";
elseif ($c == "=") $s_seg .= "000000101000";
elseif ($c == "/") $s_seg .= "000000000100";
elseif ($c == "x") $s_seg .= "000000000110";
}
return $s_seg;
}
######################################################################
### Funktion $s_frm = SEGMENTS_TO_FORMEL($s_seg,$lazy)
### - wandelt die Segment-Schreibweise $s_seg in eine Formel zurück
### - wenn $lazy true ist, werden auch abgewandelte Zahlen akzeptiert,
### z. B. 7 mit senkrechtem Anstrich
######################################################################
function SEGMENTS_TO_FORMEL($s_seg,$lazy,$ausruf) {
$s_frm = "";
while (strlen($s_seg) > 11) {
$segm = substr($s_seg,0,12);
if ($segm == "111111000000") $s_frm .= "0";
elseif ($segm == "011000000000") $s_frm .= "1";
elseif (($segm == "011000000001") && ($lazy == true)) $s_frm .= "1" . $ausruf;
elseif ($segm == "110110100000") $s_frm .= "2";
elseif ($segm == "111100100000") $s_frm .= "3";
elseif ($segm == "011001100000") $s_frm .= "4";
elseif (($segm == "011000100001") && ($lazy == true)) $s_frm .= "4" . $ausruf;
elseif ($segm == "101101100000") $s_frm .= "5";
elseif ($segm == "101111100000") $s_frm .= "6";
elseif (($segm == "001111100000") && ($lazy == true)) $s_frm .= "6" . $ausruf;
elseif ($segm == "111000000000") $s_frm .= "7";
elseif (($segm == "111001000000") && ($lazy == true)) $s_frm .= "7" . $ausruf;
elseif ($segm == "111111100000") $s_frm .= "8";
elseif ($segm == "111101100000") $s_frm .= "9";
elseif (($segm == "111001100000") && ($lazy == true)) $s_frm .= "9" . $ausruf;
elseif ($segm == "000000100000") $s_frm .= "-";
elseif ($segm == "000000110000") $s_frm .= "+";
elseif ($segm == "000000101000") $s_frm .= "=";
elseif ($segm == "000000000100") $s_frm .= "/";
elseif ($segm == "000000000110") $s_frm .= "x";
else $s_frm .= "?";
$s_seg = substr($s_seg,12);
}
return $s_frm;
}
######################################################################
### Funktion $stimmt = FORMEL_STIMMT($s_frm,$lazy,$err)
### - Testet, ob die Formel $s_frm stimmt.
### - Die detaillierte Fehlerbeschreibung $err wird nur für den ersten
### Test (ob die Ausgangsformel überhaupt zulässig ist) erzeugt.
######################################################################
function FORMEL_STIMMT($s_frm,$lazy,&$err) {
$err = "";
### Formale Prüfung: ##########################################################
if (strpos($s_frm,"?") !== false) $err = "Formel enthält Fragezeichen";
if ($err == "") {
$in_operand = false; $n_frm = strlen($s_frm);
for ($i_frm = 0; $i_frm < $n_frm; $i_frm++) {
if (strpos("+-x/=",$s_frm[$i_frm]) !== false) {
if ($i_frm == 0) $err = "Sorry, die Formel \"" . $s_frm . "\" muss mit einer Zahl beginnen.";
if ($i_frm == ($n_frm-1)) $err = "Sorry, die Formel \"" . $s_frm . "\" muss mit einer Zahl enden.";
if ($in_operand) $err = "Sorry, die Formel \"" . $s_frm . "\" hat an Position " . $i_frm . " und " . ($i_frm+1) . " zwei Operatoren hintereinander: \"" . $s_frm[$i_frm-1] . "\" und \"" . $s_frm[$i_frm] . "\".";
$in_operand = true;
} elseif (strpos("0123456789",$s_frm[$i_frm]) !== false) {
$in_operand = false;
} elseif ((strpos("evbsn",$s_frm[$i_frm]) !== false) && ($lazy == true)) {
$in_operand = false;
} else {
$err = "Sorry, die Formel \"" . $s_frm . "\" hat an Position " . ($i_frm+1) . " ein unerlaubtes Zeichen \"" . $s_frm[$i_frm] . "\". Es sind die Zeichen 0123456789+-x/= erlaubt.";
}
}
}
### Zerlegung an Gleichheitszeichen in Terme: #################################
if ($err == "") {
$a_term = array(); $n_term = 0; $in_term = false;
for ($i_frm = 0; $i_frm < $n_frm; $i_frm++) {
if (strpos("01e234v56b7s89n+-x/",$s_frm[$i_frm]) !== false) {
if ($in_term == false) {
$n_term++; $in_term = true; $a_term[$n_term] = $s_frm[$i_frm];
} else {
$a_term[$n_term] .= $s_frm[$i_frm];
}
} else {
$in_term = false;
}
}
if ($n_term < 2) $err = "Sorry, die Formel \"" . $s_frm . "\" muss mindestens ein Gleichheitszeichen enthalten.";
}
### Berechnen der Terme: #####################################################
if ($err == "") {
$a_wert = array(); $div0 = false;
for ($i_term = 1; $i_term <= $n_term; $i_term++) {
if ($div0 == false) {
$a_wert[$i_term] = TASCHENRECHNER($a_term[$i_term] . "=",$div0);
}
}
}
### Alle Terme müssen denselben Wert haben: ###################################
if ($err != "") {
$stimmt = false;
} elseif ($div0 == true) {
$stimmt = false;
} else {
$stimmt = true;
for ($i_term = 1; $i_term < $n_term; $i_term++) {
if ($a_wert[$i_term] != $a_wert[$i_term+1]) $stimmt = false;
}
}
return $stimmt;
}
######################################################################
### Funktion $s_ergeb = BERECHNUNG($s_frm,$lazy)
### - prüft, ob die Formel $s_frm überhaupt zulässig ist
### - prüft, ob die Formel bereits stimmt (unzulässig)
### - legt sämtliche möglichen Streichhölzer um
### - prüft außerdem die 4-11-Lösungen, bei denen aus der Einzel-
### ziffer 4 die zwei Ziffern 11 werden
######################################################################
function BERECHNUNG($s_frm,$lazy) {
$err = ""; $n_lsg = 0; $s_lsg = "";
### prüfen, ob die Formel unzulässig ist oder bereits stimmt: #################
if (FORMEL_STIMMT($s_frm,true,$err)) {
$err = "Sorry, die Formel \"" . $s_frm . "\" stimmt bereits.";
}
### BruteForce: ###############################################################
if ($err == "") {
$s_seg = FORMEL_TO_SEGMENTS($s_frm); $dum_err = "";
for ($p1 = 0; $p1 < (strlen($s_seg)-1); $p1++) {
for ($p2 = $p1+1; $p2 < strlen($s_seg); $p2++) {
if ($s_seg[$p1] != $s_seg[$p2]) {
$s_seg2 = $s_seg; $s_seg2[$p1] = $s_seg[$p2]; $s_seg2[$p2] = $s_seg[$p1];
if (FORMEL_STIMMT(SEGMENTS_TO_FORMEL($s_seg2,$lazy,""),$lazy,$dum_err)) {
$n_lsg++; $s_lsg .= SEGMENTS_TO_FORMEL($s_seg2,$lazy,"!") . "
\n";
}
}
}
}
}
### 4 durch 11 ersetzen: #####################################################
if ($err == "") {
for ($p = 0; $p < strlen($s_frm); $p++) {
if ($s_frm[$p] == "4") {
$s_frm2 = substr($s_frm,0,$p) . "11" . substr($s_frm,$p+1);
if (FORMEL_STIMMT($s_frm2,$lazy,$dum_err)) {
$n_lsg++; $s_lsg .= FORMEL_TO_SEGMENTS(SEGMENTS_TO_FORMEL($s_frm2,$lazy,"!")) . "
\n";
}
}
}
}
### 11 durch 4 ersetzen: #####################################################
if ($err == "") {
for ($p = 0; $p < (strlen($s_frm)-1); $p++) {
if (substr($s_frm,$p,2) == "11") {
$s_frm2 = substr($s_frm,0,$p) . "4" . substr($s_frm,$p+2);
if (FORMEL_STIMMT($s_frm2,$lazy,$dum_err)) {
$n_lsg++; $s_lsg .= FORMEL_TO_SEGMENTS(SEGMENTS_TO_FORMEL($s_frm2,$lazy,"!")) . "
\n";
}
}
}
}
### Ergebnis in Worte fassen: #################################################
if ($err != "") {
$s_ergeb = $err;
} else {
if ($n_lsg == 0) {
$s_ergeb = "Keine Lösung gefunden.";
} elseif ($n_lsg == 1) {
$s_ergeb = "Eine Lösung gefunden:
" . $s_lsg;
} else {
$s_ergeb = $n_lsg . " Lösungen gefunden:
" . $s_lsg;
}
}
return $s_ergeb;
}
######################################################################
### Funktion $x = TASCHENRECHNER($s_tipp,$div0)
### - tippt die Zeichenfolge $s_tipp in einen Taschenrechner.
### - liefert am Ende die Anzeige $x des Taschenrechners.
### - $s_tipp sollte auf = enden, sonst kommt nicht das Endergebnis.
### - Wenn Division durch 0 dabei war, wird $div0 auf TRUE gesetzt.
### - kennt Hierarchie, also 1+2*3= ergibt 7
######################################################################
function TASCHENRECHNER($s_tipp,&$div0) {
$x = 0; $y = 0; $z = 0; $op_yx = "="; $op_zy = "="; $n = strlen($s_tipp);
$in_zahl = true; $taste_old = "="; $div0 = false;
for ($i = 0; $i < $n; $i++) {
$taste = $s_tipp[$i]; if ($taste == "e") $taste = "1";
if ($taste == "v") $taste = "4"; if ($taste == "b") $taste = "6";
if ($taste == "s") $taste = "7"; if ($taste == "n") $taste = "9";
if (strpos("0123456789",$taste) !== false) {
if ($in_zahl) {
$x = $x*10+$taste;
} else {
$z = $y; $op_zy = $op_yx; $y = $x; $op_yx = $taste_old;
$x = 0+$taste; $in_zahl = true; $taste_old = "=";
}
} else {
for ($i2 = 1; $i2 <= 2; $i2++) {
if (($op_yx == "+") && ($taste != "x") && ($taste != "/")) {
$x = $y+$x; $op_yx = $op_zy; $y = $z; $op_zy = "="; $z = 0;
} elseif (($op_yx == "-") && ($taste != "x") && ($taste != "/")) {
$x = $y-$x; $op_yx = $op_zy; $y = $z; $op_zy = "="; $z = 0;
} elseif ($op_yx == "x") {
$x = $y*$x; $op_yx = $op_zy; $y = $z; $op_zy = "="; $z = 0;
} elseif ($op_yx == "/") {
if ($x != 0) $x = $y/$x; else $div0 = true;
$op_yx = $op_zy; $y = $z; $op_zy = "="; $z = 0;
}
}
$taste_old = $taste; $in_zahl = false;
}
}
return $x;
}
######################################################################
?>