Skip to content

Instantly share code, notes, and snippets.

@dihjital
Created May 15, 2023 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dihjital/6c5a7c062cf65d7e761fd09d8318e545 to your computer and use it in GitHub Desktop.
Save dihjital/6c5a7c062cf65d7e761fd09d8318e545 to your computer and use it in GitHub Desktop.
On the margin of a problem solution
<?php
use Ds\Set;
use stdClass;
class Zoli
{
protected array $range;
protected const RANGE_MIN = 0;
protected const RANGE_MAX = 5;
protected const RANGE_STEP = 0.5;
protected $a, $b, $c, $d = null;
protected $crossOp, $cellOp;
public function __construct(protected Set $set = new Set) {
$this->range = range(
self::RANGE_MIN,
self::RANGE_MAX,
self::RANGE_STEP
);
$this->crossOp = ($this->add(...));
$this->cellOp = ($this->multiply(...));
}
protected function resetVariables(): void {
$this->a =
$this->b =
$this->c =
$this->d = null;
}
protected function extractGuess(array $guess): array {
return [
$this->a ?? $guess[0],
$this->b ?? $guess[1],
$this->c ?? $guess[2],
$this->d ?? $guess[3],
];
}
protected function multiply(...$numbers): int|float {
return array_reduce($numbers,
fn($accumulator, $number) => $accumulator * $number
, 1);
}
protected function subtract(...$numbers): int|float {
return array_reduce($numbers,
fn($accumulator, $number) => $accumulator - $number
, 0);
}
protected function add(...$numbers): int|float {
return array_reduce($numbers,
fn($accumulator, $number) => $accumulator + $number
, 0);
}
protected function getSymbols(array $pairs): stdClass {
return array_reduce($pairs, function($obj, $sub_array) {
foreach ($sub_array as $sub_obj) {
foreach ($sub_obj as $key => $value) {
if (!property_exists($obj, $key)) {
$obj->{$key} = $value;
}
}
}
return $obj;
}, new stdClass());
}
protected function fixVariables(stdClass $symbols):void {
foreach($symbols as $symbol => $value) {
$this->{$symbol} = $value;
}
}
protected function eq(int $expectedResult, array $pairs): bool {
$result = ($this->crossOp)(...array_map(function($cell) {
return ($this->cellOp)(...array_map(fn($symbol) => array_values($symbol)[0], $cell));
}, $pairs));
if ($result == $expectedResult) {
$this->fixVariables($this->getSymbols($pairs));
return true;
}
return false;
}
protected function createPair(array $symbols, array $values): array {
return array_map(function ($symbol, $value) {
return [$symbol => $value];
}, $symbols, $values);
}
public function validateSolution(array $guess) {
list($a, $b, $c, $d) = $this->extractGuess($guess);
yield $this->eq(40, [
$this->createPair(['a', 'a'], [$a, $a]), $this->createPair(['c', 'c'], [$c, $c]),
$this->createPair(['c', 'c'], [$c, $c]), $this->createPair(['a', 'a'], [$a, $a])
]);
yield $this->eq(26, [
$this->createPair(['a', 'a'], [$a, $a]), $this->createPair(['a', 'a'], [$a, $a]),
$this->createPair(['d', 'd'], [$d, $d]), $this->createPair(['d', 'd'], [$d, $d])
]);
yield $this->eq(50, [
$this->createPair(['c', 'c'], [$c, $c]), $this->createPair(['c', 'c'], [$c, $c]),
$this->createPair(['d', 'd'], [$d, $d]), $this->createPair(['d', 'd'], [$d, $d])
]);
yield $this->eq(14, [
$this->createPair(['a', 'a'], [$a, $a]), $this->createPair(['b', 'c'], [$b, $c]),
$this->createPair(['a', 'a'], [$a, $a]), $this->createPair(['a', 'b'], [$a, $b])
]);
yield $this->eq(24, [
$this->createPair(['b', 'c'], [$b, $c]), $this->createPair(['d', 'b'], [$d, $b]),
$this->createPair(['c', 'c'], [$c, $c]), $this->createPair(['b', 'b'], [$b, $b])
]);
yield $this->eq(31, [
$this->createPair(['c', 'c'], [$c, $c]), $this->createPair(['d', 'b'], [$d, $b]),
$this->createPair(['a', 'a'], [$a, $a]), $this->createPair(['c', 'a'], [$c, $a])
]);
yield $this->eq(26, [
$this->createPair(['a', 'a'], [$a, $a]), $this->createPair(['b', 'b'], [$b, $b]),
$this->createPair(['d', 'd'], [$d, $d]), $this->createPair(['c', 'd'], [$c, $d])
]);
yield $this->eq(31, [
$this->createPair(['a', 'b'], [$a, $b]), $this->createPair(['c', 'a'], [$c, $a]),
$this->createPair(['d', 'd'], [$d, $d]), $this->createPair(['c', 'd'], [$c, $d])
]);
}
public function getRandomElement() {
return $this->range[array_rand($this->range)];
}
public function generateElements(): array {
return array_map(fn() => $this->getRandomElement(), range(1, 4));
}
public function checkIfGuessExists($guess): bool {
return $this->set->contains($guess);
}
public function generateGuess(): array {
$guess = $this->generateElements();
while ($this->checkIfGuessExists($guess) || count(array_unique($guess)) !== 4)
$guess = $this->generateElements();
return $guess;
}
public function evaluateSolution(array $guess): bool {
return array_reduce([...$this->validateSolution($guess)],
fn ($validGuess, $eq) => $validGuess && $eq
, true);
}
public function printSolution(array $solution): void {
echo sprintf("We have found a solution: a = %.1f, b = %.1f, c = %.1f, d = %.1f", ...$solution);
}
public function runSequence(int $length = 5000): bool {
$this->set->clear();
for ($j = 0; $j < $length; $j++) {
$guess = $this->generateGuess();
if ($this->evaluateSolution($guess)) {
$this->printSolution($this->extractGuess($guess));
return true;
} else {
$this->set->add($guess);
}
}
sleep(15);
$this->resetVariables();
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment