Last active
May 17, 2016 03:52
-
-
Save nitrix/cb0aac2563f08bdd6b4896fd15d2a0e1 to your computer and use it in GitHub Desktop.
Test genetic programming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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