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; } ###################################################################### ?>