Skip to content

Instantly share code, notes, and snippets.

@nitrix
Last active May 17, 2016 03:52
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 nitrix/cb0aac2563f08bdd6b4896fd15d2a0e1 to your computer and use it in GitHub Desktop.
Save nitrix/cb0aac2563f08bdd6b4896fd15d2a0e1 to your computer and use it in GitHub Desktop.
Test genetic programming
<?php
$instructions = ['0', '1', '+', '-', '*', '/', '>', '<', '=', '|', '&', '@', '!', '#', '(', ')', '%', '_'];
$instructionsLength = count($instructions) - 1;
while (true) {
$program = '';
for ($i = 0, $c = rand(0, 10); $i < $c; $i++) {
$program .= $instructions[rand(0, $instructionsLength)];
}
$resulta = vm([100], $program);
$resultb = vm([25], $program);
if ($resulta == [4] && $resultb == [4]) {
echo 'Winning program: '.$program."\n";
exit();
}
}
function vm($inputs, $instructions) {
$stack = $inputs;
$hold = [];
foreach (str_split($instructions) as $instruction) {
switch ($instruction) {
// Magic value
case '0':
array_unshift($stack, 0);
break;
// Magic value
case '1':
array_unshift($stack, 1);
break;
// Arithmetic addition
case '+':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a + $b);
break;
// Arithmetic substraction
case '-':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a - $b);
break;
// Arithmetic multiplication
case '*':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a * $b);
break;
// Arithmetic division
case '/':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
if ($b == 0) return;
array_unshift($stack, floor($a / $b));
break;
// Arithmetic exponent
case '^':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a ^ $b);
break;
// Greater than
case '>':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a > $b ? 1 : 0);
break;
// Lesser than
case '<':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a < $b ? 1 : 0);
break;
// Comparison
case '=':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a == $b ? 1 : 0);
break;
// Logical OR
case '|':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a || $b ? 1 : 0);
break;
// Logical AND
case '&':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a && $b ? 1 : 0);
break;
// Swap
case '@':
if (empty($stack)) return;
$a = array_shift($stack);
if (empty($stack)) return;
$b = array_shift($stack);
array_unshift($stack, $a);
array_unshift($stack, $b);
break;
// Dup
case '!':
if (empty($stack)) return;
$a = array_shift($stack);
array_unshift($stack, $a);
array_unshift($stack, $a);
break;
// Drop
case '#':
if (empty($stack)) return;
array_shift($stack);
break;
// Hold
case '(':
if (empty($stack)) return;
$a = array_shift($stack);
array_unshift($hold, $a);
break;
// Retrieve
case ')':
if (empty($hold)) return;
$a = array_shift($hold);
array_unshift($stack, $a);
break;
// Exchange
case '%':
$tmp = $hold;
$hold = $stack;
$stack = $tmp;
break;
// Noop
case '_':
break;
}
}
return $stack;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment