Problem mit Funktion in einer Schleife

Kalito

Erfahrenes Mitglied
Hallo,

ich habe ein folgendes Problem bei der Erstellung von Matheaufgaben. Ich möchte vorerst einfache Aufgaben erstellen, wo zwei Zahlen untereinander stehen und man dann das Ergebnis hinschreiben soll. Die Hürde hierbei ist, das ein Zahlenpaar nie größer 9 sein dürfen. Sprich 8 und 3 wären falsch, wohingegen 8 und 1 funktionieren darf. Bei zweistelligen Zahlen dürfen die untereinanderstehenden einer und Zehnerstellen auch jeweils nicht über 9 kommen. Also würde hier 21 und 18 gehen, aber 21 und 93 bzw 21 und 39 nicht gehen.
Der unten stehende Code funktioniert bei einer Abfrage. Wenn ich aber die Funktion untereinader in einer FOR-Schleife aufrufe, dann werden die Restrictionen nicht eingehalten und ergibt mir Zahlen aus, die es nicht soll. Woran kann das liegen?

Gruß, Kalito

PHP:
class math {
    private $anzahl = "2";
    private $check = false;
    private $pool = "1234567890"; 
    private $zahl1;
    private $zahl2;
    private $zahlarray1;
    private $zahlarray2;
    private $zeichen = "plus";    
    
    public function __construct(){}
    
    public function untereinander(){
        $this->generiereZahlarray();
     echo "<br/>Zahlarray1: "; 
     var_dump($this->zahlarray1);
     echo "<br/>Zahl1: ".$this->zahl1;
     echo "<br/>Zahlarray2: "; 
     var_dump($this->zahlarray2);
     echo "<br/>Zahl2: ".$this->zahl2;  
     echo"<br/>Summe: ".($this->zahl1 + $this->zahl2);                 
    }

    private function generiereZahlarray(){
        for($i=0;$i<$this->anzahl;$i++){
            do{
                $this->zahlarray1[$i] = $this->random();
                $this->zahlarray2[$i] = $this->random();           
                $this->check = $this->check();   
            }while(!$this->check);
        }
        $this->ArrayToString();
    }
    
    //Prüfung des Zeichen zur Auswahl der checkfunktion
    private function check(){
        switch ($this->zeichen){
            case "plus": return $this->checkAddition(); break;
        }    
    }
    
    private function checkAddition(){
        return ((end($this->zahlarray1) + end($this->zahlarray2)) <10) ? true : false;
    }
        
    private function ArrayToString(){
        $this->zahl1 = implode("", $this->zahlarray1);
        $this->zahl2 = implode("", $this->zahlarray2);
    }
    
    // Zufallsgenerierung einer Zahl
    private function random(){
        return $this->pool{rand(0, strlen($this->pool)-1)};    
    }

}
 
Dein Code verbessert und umgeschrieben:
PHP:
class Math{
  private  static $max;
  public static function generate($length){
    self::$max = pow(10, $length)-1;
    $min = pow(10, $length-1);
    $numbers = array( rand($min, self::$max), rand($min, self::$max));
    while( !self::isValid($numbers) ){
	  echo "Debug: {$numbers[0]} + {$numbers[1]} sind nicht zulässig.<br />";
      $numbers= array(rand($min, self::$max), rand($min, self::$max));
    }
    return $numbers;
  }
  private static function isValid($numbers){
    $sum = $numbers[0]+$numbers[1];
    return !($sum > self::$max || $sum%10 == 0);    
  }
}
echo '<pre>';
var_dump(Math::generate(1));
var_dump(Math::generate(1));
var_dump(Math::generate(2));
var_dump(Math::generate(2));
var_dump(Math::generate(3));
var_dump(Math::generate(3));
echo '</pre>';
Ausgabe:
Code:
Debug: 2 + 8 sind nicht zulässig.
array(2) {
  [0]=>
  int(4)
  [1]=>
  int(2)
}
Debug: 5 + 5 sind nicht zulässig.
Debug: 3 + 8 sind nicht zulässig.
Debug: 8 + 2 sind nicht zulässig.
Debug: 5 + 8 sind nicht zulässig.
array(2) {
  [0]=>
  int(3)
  [1]=>
  int(4)
}
Debug: 61 + 94 sind nicht zulässig.
array(2) {
  [0]=>
  int(30)
  [1]=>
  int(35)
}
array(2) {
  [0]=>
  int(40)
  [1]=>
  int(34)
}
Debug: 958 + 427 sind nicht zulässig.
Debug: 948 + 892 sind nicht zulässig.
array(2) {
  [0]=>
  int(253)
  [1]=>
  int(339)
}
array(2) {
  [0]=>
  int(328)
  [1]=>
  int(144)
}
?>
 
Zuletzt bearbeitet:
@timestamp
Ich habe verstanden, dass keine Ziffern Untereinader grösser als 9 sein darf. 12+19 währe demzufolge falsch, da 2+9 11 ergibt.

Mein generischer Lösungsansatz sieht so aus. Generisch, da es die Anzahl Ziffer sowie auch die Anzahl Zahlen als Parameter führt
PHP:
//Zahlen generieren und Prüfen
$math = new Math(2,2);
//Die generierten Zahlen anzeigen
echo implode('<br />', $math->numbers);
//Die Summe der Zahlen anzeigen
echo "<hr />{$math->sum}";

if($math->haveError){
    echo "<hr />Fehler: </b>{$math->error}";
}


class Math{   
    public $numbers = array();
    public $sum;
    public $error = NULL;
    public $haveError = false; 
    
    protected $numberOfData;
    protected $numberOfDigits;
    protected $data = array();
    
    
    /**
     * Generiert einen Array mit $numberOfData Zahlen welche jeweils $numberOfDigits Ziffern haben
     * @param  Integer            Anzahl Stellen der Zufallszahl
     * @param  Integer            Anzahl Zahlen
     * @return void
     */
    public function __construct($numberOfDigits, $numberOfData=2){
        $this->numberOfData = $numberOfData;
        $this->numberOfDigits = $numberOfDigits;
    
        $this->generateNumbers();
        $this->sum = array_sum($this->numbers);
        try {
            $this->check();
        } catch (Exception $e) {
            $this->haveError=true;
            $this->error = $e->getMessage();
        }
        
    }
    
    /**
     * Generiert die Nummern
     * @return void
     */
    protected function generateNumbers(){
        for($dataIndex = 0; $dataIndex<$this->numberOfData; $dataIndex++){
            $min = (Integer) str_pad('1', $this->numberOfDigits, '0');            
            $max = (Integer) str_pad('9', $this->numberOfDigits, '9');
            $number = mt_rand($min, $max);
            $this->numbers[$dataIndex] = $number;
            $this->data[$dataIndex] = str_split((String) $number);
        }
    }

    /**
     * Prüft die Ziffern
     * @throws Exception
     * @return void
     */
    protected function check(){
        for($digiPosition=0; $digiPosition<$this->numberOfDigits; $digiPosition++){
            //Die Ziffern aller Zahlen an der Position $digiPosition extrahieren
            $digits = array_extract_sub_item($this->data, $digiPosition);
            //Wenn die Ziffer-Summe grösser al 9 ist, einen Fehler werfen
            if(array_sum($digits) > 9){
                throw new Exception("Die Zahlen (" . implode(', ', $this->numbers) . ") sind nicht gültig");
            }
        }
    }
}


/**
 * Extrahieren ein Subitem aus einem mehrstufigen Array. Der Schlüssel wird beibehalten
 * http://wiki.yaslaw.info/wikka/PhpArrayExtractSubItem
 * @param   Array<Key => Array<Node>>   Ein mehrstufiger Array
 * @param   String                      Schlüssel des zu extrahierenden Item
 * @return  Array<Key => Node>
 */
function array_extract_sub_item($array, $key){
    foreach($array as $index => $item) $retArray[$index] = $item[$key];
    return $retArray;
}

Ausgaben
Code:
50
49
----
99



30
89
----
119
----
Fehler: Die Zahlen (30, 89) sind nicht gültig



23
38
----
61
----
Fehler: Die Zahlen (23, 38) sind nicht gültig


//Oder bei  der Einstellung $math = new Math(1,3);
2
3
3
----
8



2
9
----
617
----
Fehler: Die Zahlen (2, 9, 6) sind nicht gültig
 
Zurück