Last active
September 14, 2015 14:24
-
-
Save shengsheng/5d1a1809ec93908104d4 to your computer and use it in GitHub Desktop.
A million monkeys write Perl and Java.
This file contains hidden or 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 | |
| /** | |
| * 如果有一百万只猴子,每只给一个键盘,总有一天其中一只能敲出一份完整的可运行的 Java 代码。 | |
| * | |
| * 剩下的敲的都是 Perl 代码。 | |
| * | |
| * @author 胡生生BSA | |
| * @date: 2015-9-14 | |
| */ | |
| class Keyboard | |
| { | |
| /** | |
| * Keyboard name | |
| * | |
| * @var string | |
| */ | |
| private $name = 'Cherry'; | |
| /** | |
| * Keycap lifetime | |
| * | |
| * @var int | |
| */ | |
| private $lifetime = 9223372036854775807; | |
| /** | |
| * @var string | |
| */ | |
| private $chars = ''; | |
| /** | |
| * Accept a char | |
| * | |
| * @param string $char | |
| * @return bool | |
| */ | |
| public function input($char) | |
| { | |
| if ($this->lifetime <= 0) { | |
| return false; | |
| } | |
| $this->record($char); | |
| $this->lifetime--; | |
| return true; | |
| } | |
| /** | |
| * Record everything | |
| * | |
| * @param string $char | |
| */ | |
| private function record($char) | |
| { | |
| $this->chars .= $char; | |
| } | |
| /** | |
| * Get result | |
| * | |
| * @return string | |
| */ | |
| public function getResult() | |
| { | |
| return $this->chars; | |
| } | |
| } | |
| class Monkey | |
| { | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * Constructor | |
| * | |
| * @param string $name | |
| */ | |
| public function __construct($name) | |
| { | |
| $this->name = $name; | |
| } | |
| /** | |
| * I'm tying | |
| * | |
| * @param Keyboard $keyboard | |
| * @return bool | |
| */ | |
| public function typing(Keyboard $keyboard) | |
| { | |
| return $keyboard->input(chr(mt_rand(0, 255))); | |
| } | |
| /** | |
| * I have time and want tying | |
| * | |
| * @return bool | |
| */ | |
| public function canTyping() | |
| { | |
| return !($this->thinking() || $this->eating() || $this->sleeping()) && | |
| $this->wantTyping(); | |
| } | |
| /** | |
| * Thinking the monkeys' future | |
| * | |
| * @return bool | |
| */ | |
| private function thinking() | |
| { | |
| $tmp = mt_rand(1, 100); | |
| return $tmp >= 0 && $tmp <= 40; | |
| } | |
| /** | |
| * Banana! Banana! Banana! | |
| * | |
| * @return bool | |
| */ | |
| private function eating() | |
| { | |
| $tmp = mt_rand(1, 100); | |
| return $tmp >= 40 && $tmp <= 60; | |
| } | |
| /** | |
| * Dream | |
| * | |
| * @return bool | |
| */ | |
| private function sleeping() | |
| { | |
| $tmp = mt_rand(1, 100); | |
| return $tmp >= 60 && $tmp <= 90; | |
| } | |
| /** | |
| * I'm bored | |
| * | |
| * @return bool | |
| */ | |
| private function wantTyping() | |
| { | |
| $tmp = mt_rand(1, 100); | |
| return $tmp >= 90 && $tmp <= 100; | |
| } | |
| } | |
| class Epic | |
| { | |
| /** | |
| * @var Monkey | |
| */ | |
| private $monkey; | |
| /** | |
| * @var Keyboard | |
| */ | |
| private $keyboard; | |
| /** | |
| * Constructor | |
| * | |
| * @param Monkey $monkey | |
| * @param Keyboard $keyboard | |
| */ | |
| public function __construct($monkey, $keyboard) | |
| { | |
| $this->monkey = $monkey; | |
| $this->keyboard = $keyboard; | |
| } | |
| /** | |
| * Can you write something interesting stuff? | |
| * | |
| * @param string $stop_time | |
| */ | |
| public function write($stop_time = '2038-01-19 11:14:07') | |
| { | |
| $stop_time = strtotime($stop_time); | |
| while (true) { | |
| if (time() >= $stop_time) { | |
| break; | |
| } | |
| if ($this->monkey->canTyping()) { | |
| $result = $this->monkey->typing($this->keyboard); | |
| if (!$result) { | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| class EpicTest extends PHPUnit_Framework_TestCase | |
| { | |
| public function millionMonkeys() | |
| { | |
| return array_map(function($i) { return array($i); }, range(1, 1000000)); | |
| } | |
| /** | |
| * @dataProvider millionMonkeys | |
| * @param int $times | |
| */ | |
| public function testOneIsJavaAndRestOfThemArePerl($times) | |
| { | |
| $monkey = new Monkey('monkey_' . $times); | |
| $keyboard = new Keyboard(); | |
| $epic = new Epic($monkey, $keyboard); | |
| $epic->write(); | |
| $expect = 'Yes, PHP is the best programming language.'; | |
| $code = $keyboard->getResult(); | |
| if (isJava($code)) { | |
| $this->assertEquals($expect, runJava(new JavaCompile($code))); | |
| $this->assertGreaterThan(65535, strlen($code)); | |
| } else { | |
| $this->assertEquals($expect, runPerl($code)); | |
| } | |
| } | |
| } | |
| /* | |
| jianjuo@smartisan2015 (master)$ phpunit joke.php | |
| PHPUnit 4.6.6 by Sebastian Bergmann and contributors. | |
| ....................................... | |
| Time: 19320310320.71 seconds, Memory: 113.75Mb | |
| OK (1000000 tests, 1000001 assertions) | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment