(.*?)<\/code>/", str_replace(["\r", "\n"], '', $potentialCode), $results)
63 | ? collect($results[1])->map(function ($code) { return html_entity_decode($code); })
64 | : false
65 | )->filter();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/StackOverflowBuddyTest.php:
--------------------------------------------------------------------------------
1 | assertEquals([1, 2, 3, 4, 5], StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4]));
21 | }
22 |
23 | function test_it_caches_and_returns_good_code()
24 | {
25 | $this->assertEquals([1, 2, 3, 4, 5], StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4]));
26 | $this->assertEquals([1, 2, 3, 4, 5], StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4]));
27 | }
28 |
29 | function test_it_throws_away_non_function_code()
30 | {
31 | StackOverflowBuddy::$api = 'stackoverflow.dev/extracode/';
32 | $this->assertEquals(['atyp'], StackOverflowBuddy::getStringBetweenTwoStrings('pl', 'us', 'platypus'));
33 | }
34 |
35 | function test_it_provides_attribution()
36 | {
37 | StackOverflowBuddy::mergeSort([3, 5, 1, 2, 4]);
38 | $this->assertEquals([
39 | 'author' => 'Kartik',
40 | 'authorLink' => 'https://stackoverflow.com/users/325499/kartik',
41 | 'questionLink' => 'https://stackoverflow.com/a/9401135',
42 | ], StackOverflowBuddy::giveThanksFor('mergeSort'));
43 |
44 | }
45 |
46 | function test_it_doesnt_let_you_thank_no_one()
47 | {
48 | $this->expectException(UnnecessarilyGratefulException::class);
49 | StackOverflowBuddy::giveThanksFor('something');
50 | }
51 |
52 | function test_it_throws_exception_with_no_results()
53 | {
54 | StackOverflowBuddy::$api = 'stackoverflow.dev/empty/';
55 | $this->expectException(HaveToWriteYourOwnCodeException::class);
56 | StackOverflowBuddy::anything('x');
57 | }
58 |
59 | function test_it_throws_exception_with_bad_results()
60 | {
61 | StackOverflowBuddy::$api = 'stackoverflow.dev/bad/';
62 | $this->expectException(HaveToWriteYourOwnCodeException::class);
63 | StackOverflowBuddy::anything('x');
64 | }
65 |
66 | function test_it_handles_being_rate_limited_by_stack_overflow()
67 | {
68 | StackOverflowBuddy::$api = 'stackoverflow.dev/rate-limit/';
69 | $this->expectException(HaveToWriteYourOwnCodeException::class);
70 | StackOverflowBuddy::anything();
71 | }
72 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Stack Overflow Buddy
2 |
3 | Inspired by the revolutionary work done by @drathier and their [stack-overflow-import](https://github.com/drathier/stack-overflow-import), Stack Overflow Buddy is your own personal PHP based Stack Overflow assistant!
4 |
5 | Why spend your valuable time cutting and pasting from StackOverflow when Stack Overflow Buddy can do it for you? Who wouldn't trade all safety checks and only the basest of functionality checks for a bit of convenience?
6 | ### Installation
7 | ```
8 | composer require brandonshar/stack-overflow-buddy
9 | ```
10 | Because Stack Overflow Buddy uses untagged libraries, you may need to add the following lines to your composer root
11 | ```
12 | "minimum-stability": "dev",
13 | "prefer-stable": true
14 | ```
15 | ```php
16 | # and in your files you use it
17 | use brandonshar\StackOverflowBuddy;
18 | ```
19 | ---
20 | ### What's it do?
21 |
22 | Just give it a try!
23 |
24 | ```php
25 | StackOverflowBuddy::mergeSort([2,3,1,4]);
26 | // [1, 2, 3, 4]
27 | ```
28 |
29 | *Impressed?*
30 |
31 | How about
32 |
33 | ```php
34 | StackOverflowBuddy::substringBetweenTwoStrings('platypus', 'pl', 'us');
35 | // atyp
36 | ```
37 | ---
38 | ### Wow, how's it work?
39 | If you're impressed, you should probably stop reading here.
40 |
41 | 1. Split the camelCased function call into words
42 | 2. Grab the top scoring PHP tagged questions with those words in the title from StackOverflow's API
43 | 3. Grab the top scoring answers for those questions
44 | 4. Pull any and all code blocks from those answers
45 | 5. Find the first code block that:
46 | 1. Inteprets without error
47 | 2. Contains one or more functions
48 | 3. One of the functions has the same amount of arguments as were passed by the user
49 | 6. Then we throw caution to the wind, eval, and call the new method!
50 | ---
51 | ### Wow, this will change my workflow forever!
52 | It certainly will. But don't forget to use some of that time you're saving to thank the original author of the code you've now absorbed.
53 |
54 | ```php
55 | var_dump(StackOverflowBuddy::giveThanksFor('substringBetweenTwoStrings'));
56 | /*
57 | ["author"]=>
58 | string(18) "Alejandro Iglesias"
59 | ["authorLink"]=>
60 | string(57) "https://stackoverflow.com/users/425741/alejandro-iglesias"
61 | ["questionLink"]=>
62 | string(35) "https://stackoverflow.com/a/9826656"
63 | */
64 | ```
65 | ---
66 |
67 | ### What if StackOverflowBuddy can't find any good code for my method?
68 | In the incredibly unlikely (ok... maybe not *incredibly unlikely*) event that StackOverflowBuddy can't find any code that meets your request, it'll throw you a `HaveToWriteYourOwnCodeException` to keep you busy while hopefully someone else gives a better answer on Stack Overflow.
69 |
70 | ---
71 |
72 | ### Testimonials
73 | If you're still on the fence, don't take my word for it; here's what a satisifed reader of the code had to say:
74 | > "I love how this makes on the fly software updates really easy. If I ever need to tweak an algorithm or fix a bug, I just need to submit a really good answer to stack overflow with the updated code. Goodbye source control!"
75 |
76 | > \- [Pseudofailure](https://www.reddit.com/r/PHP/comments/6qzuzj/just_released_a_package_to_cut_out_the/dl1ejwg/)
77 | ---
78 |
79 | ### Warning-ware
80 | You're free to use this package, but if it makes it to your production environment you accept the responsibility of personally telling each of your users that they would be better off hiding their data under their mattress.
81 |
82 | ---
83 |
84 | ### Notes
85 | Keep in mind that every usage of this makes two requests to the StackOverflow API and they will rate-limit you after a certain number of requests per day. But that shouldn't really be an issue since no one sensible would ever use this for anything.
86 |
87 | ---
88 |
89 | ### Contributing
90 | Have a blast. There is currently only one end to end integration test that requires the index.php file to be reachable from a local server. I just used Laravel Valet. This code does not follow PSR-2 and deliberately uses no typehints or visiblity as I decided to do a similar style experiment to the required Zttp library. Even if you're the strictest PHP writer there is, not following a style guide is at best, like the 5th reason you should never use this code.
91 |
92 | ---
93 |
94 | ### License
95 | The Unlicense. If there's a less restrictive license with even less liability, let's go with that. Anyone who thinks that using this license is to the `detriment of my heirs` clearly didn't look at it very carefully.
96 |
--------------------------------------------------------------------------------
/tests/data/questions.json:
--------------------------------------------------------------------------------
1 | {"items":[{"tags":["php","sorting","mergesort"],"owner":{"reputation":15,"user_id":1216806,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/4897e27c476f7232c54f89ec2cb0d39f?s=128&d=identicon&r=PG","display_name":"jweb","link":"https://stackoverflow.com/users/1216806/jweb"},"is_answered":true,"view_count":9109,"accepted_answer_id":9401151,"answer_count":5,"score":2,"last_activity_date":1486053527,"creation_date":1329936343,"last_edit_date":1329936560,"question_id":9401019,"link":"https://stackoverflow.com/questions/9401019/writing-merge-sort-in-php","title":"Writing merge sort in PHP"},{"tags":["php","algorithm","sorting"],"owner":{"reputation":28,"user_id":220508,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/c3b68d4f630aae909f50a1405280a4a3?s=128&d=identicon&r=PG","display_name":"lordlinier","link":"https://stackoverflow.com/users/220508/lordlinier"},"is_answered":true,"view_count":1803,"answer_count":7,"score":1,"last_activity_date":1294635427,"creation_date":1262104370,"question_id":1975520,"link":"https://stackoverflow.com/questions/1975520/question-about-merge-sort-under-php","title":"question about merge sort under php"},{"tags":["php","multidimensional-array"],"owner":{"reputation":6,"user_id":397494,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/5b38b0afa683b2fc1f4b593a1ce6d0db?s=128&d=identicon&r=PG","display_name":"LeRoy Miller","link":"https://stackoverflow.com/users/397494/leroy-miller"},"is_answered":true,"view_count":1022,"answer_count":2,"score":1,"last_activity_date":1279687087,"creation_date":1279684570,"last_edit_date":1279684675,"question_id":3296203,"link":"https://stackoverflow.com/questions/3296203/php-need-to-merge-sort-a-multidimensional-array-based-on-one-key-in-the-dimensi","title":"PHP: Need to merge/sort a multidimensional array based on one key in the dimension"},{"tags":["php"],"owner":{"reputation":15346,"user_id":465546,"user_type":"registered","accept_rate":94,"profile_image":"https://www.gravatar.com/avatar/d67cc0a6798555fd468d2d5a00ae9927?s=128&d=identicon&r=PG","display_name":"qwertymk","link":"https://stackoverflow.com/users/465546/qwertymk"},"is_answered":true,"view_count":1007,"accepted_answer_id":11827593,"answer_count":1,"score":1,"last_activity_date":1344254792,"creation_date":1344252824,"question_id":11827451,"link":"https://stackoverflow.com/questions/11827451/merge-two-arrays-merge-sort-style","title":"merge two arrays, merge-sort style"},{"tags":["php","sorting"],"owner":{"reputation":12967,"user_id":392975,"user_type":"registered","accept_rate":63,"profile_image":"https://www.gravatar.com/avatar/a62bcec9b5b35a3cab7c25a44016e0d4?s=128&d=identicon&r=PG","display_name":"Eli","link":"https://stackoverflow.com/users/392975/eli"},"is_answered":true,"view_count":3541,"accepted_answer_id":17459600,"answer_count":2,"score":1,"last_activity_date":1372895143,"creation_date":1372892583,"last_edit_date":1372893515,"question_id":17459468,"link":"https://stackoverflow.com/questions/17459468/merge-sort-together-two-arrays-in-php","title":"Merge Sort Together Two Arrays in Php?"},{"tags":["php","mergesort"],"owner":{"reputation":3427,"user_id":237107,"user_type":"registered","accept_rate":71,"profile_image":"https://i.stack.imgur.com/poBfS.jpg?s=128&g=1","display_name":"noctilux","link":"https://stackoverflow.com/users/237107/noctilux"},"is_answered":true,"view_count":385,"accepted_answer_id":17510548,"answer_count":3,"score":0,"last_activity_date":1433225398,"creation_date":1373102674,"question_id":17501545,"link":"https://stackoverflow.com/questions/17501545/counting-inversions-using-merge-sort-unexpected-result","title":"Counting Inversions using merge sort - unexpected result"},{"tags":["php","c++","sorting"],"owner":{"reputation":15,"user_id":1973869,"user_type":"registered","accept_rate":100,"profile_image":"https://www.gravatar.com/avatar/643dded419ebe75ef9d21db21dfa6de5?s=128&d=identicon&r=PG","display_name":"FireForce","link":"https://stackoverflow.com/users/1973869/fireforce"},"is_answered":true,"view_count":468,"accepted_answer_id":17503488,"answer_count":1,"score":0,"last_activity_date":1373117707,"creation_date":1373116204,"last_edit_date":1373117521,"question_id":17503294,"link":"https://stackoverflow.com/questions/17503294/php-two-way-merge-sort","title":"PHP two-way merge sort"},{"tags":["php","arrays","sorting","object","merge"],"owner":{"reputation":788,"user_id":1861766,"user_type":"registered","accept_rate":44,"profile_image":"https://www.gravatar.com/avatar/1af2b33383d9d6f83cd6616a9ad99a9e?s=128&d=identicon&r=PG","display_name":"ChuckKelly","link":"https://stackoverflow.com/users/1861766/chuckkelly"},"is_answered":true,"view_count":280,"accepted_answer_id":18881112,"answer_count":1,"score":0,"last_activity_date":1379537656,"creation_date":1379533036,"last_edit_date":1379533878,"question_id":18880844,"link":"https://stackoverflow.com/questions/18880844/php-merge-sort-several-different-arrays-of-objects","title":"PHP Merge & Sort Several Different Arrays of Objects"},{"tags":["php","python","mergesort"],"owner":{"reputation":3,"user_id":7216164,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/09ea0737f51fddf465a07cbf79611f92?s=128&d=identicon&r=PG&f=1","display_name":"BeMu","link":"https://stackoverflow.com/users/7216164/bemu"},"is_answered":true,"view_count":25,"accepted_answer_id":43169171,"answer_count":1,"score":-1,"last_activity_date":1491141362,"creation_date":1491140390,"question_id":43169004,"link":"https://stackoverflow.com/questions/43169004/php-merge-sort-not-working","title":"PHP merge sort not working"}],"has_more":false,"quota_max":300,"quota_remaining":299}
--------------------------------------------------------------------------------
/tests/data/answers2.json:
--------------------------------------------------------------------------------
1 | {"items":[{"owner":{"reputation":23568,"user_id":219118,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a5a89ebe2152ed3c5de458a97542b0ed?s=128&d=identicon&r=PG","display_name":"sachleen","link":"https://stackoverflow.com/users/219118/sachleen"},"down_vote_count":0,"up_vote_count":20,"is_accepted":true,"score":20,"answer_id":14313097,"share_link":"https://stackoverflow.com/a/14313097","body":"You can just explode it:
\n\n<?php\n$string = 'reply-234-private';\n$display = explode('-', $string);\n\nvar_dump($display);\n// prints array(3) { [0]=> string(5) \"reply\" [1]=> string(3) \"234\" [2]=> string(7) \"private\" }\n\necho $display[1];\n// prints 234\n
\n\nOr, use preg_match
\n\n<?php\n$string = 'reply-234-private';\nif (preg_match('/reply-(.*?)-private/', $string, $display) === 1) {\n echo $display[1];\n}\n
\n"},{"owner":{"reputation":184,"user_id":1976345,"user_type":"registered","accept_rate":43,"profile_image":"https://www.gravatar.com/avatar/01ea0ca6ffe27dd2823c3b586445bcda?s=128&d=identicon&r=PG","display_name":"Chris Jackson","link":"https://stackoverflow.com/users/1976345/chris-jackson"},"down_vote_count":0,"up_vote_count":7,"is_accepted":false,"score":7,"answer_id":14313112,"share_link":"https://stackoverflow.com/a/14313112","body":"Have a look at explode() function
\n\nsomething like this:
\n\n$myString = 'reply-234-private';\n\n$myStringPartsArray = explode(\"-\", $myString);\n\n$answer = $myStringPartsArray[1];\n
\n"},{"owner":{"reputation":101,"user_id":3967957,"user_type":"registered","profile_image":"https://graph.facebook.com/100007955027846/picture?type=large","display_name":"Kuncara Kurniawan","link":"https://stackoverflow.com/users/3967957/kuncara-kurniawan"},"down_vote_count":0,"up_vote_count":5,"is_accepted":false,"score":5,"answer_id":27483387,"share_link":"https://stackoverflow.com/a/27483387","body":"This article show you, How to get of everything string between two tags or two strings.
\n\nhttp://okeschool.com/articles/312/string/how-to-get-of-everything-string-between-two-tag-or-two-strings
\n\n<?php\n // Create the Function to get the string\n function GetStringBetween ($string, $start, $finish) {\n $string = \" \".$string;\n $position = strpos($string, $start);\n if ($position == 0) return \"\";\n $position += strlen($start);\n $length = strpos($string, $finish, $position) - $position;\n return substr($string, $position, $length);\n}\n?>\n
\n\nin case your question, you can try this :
\n\n$string1='reply-234-private';\necho GetStringBetween ($string1, \"-\", \"-\")\n
\n\nor we can use any 'identifier string' for grab the string between the identifier string. for example:
\n\necho GetStringBetween ($string1, \"reply-\", \"-private\")\n
\n"},{"owner":{"reputation":171,"user_id":520896,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/799b0844613573b120c2dda72a69a0e8?s=128&d=identicon&r=PG","display_name":"Ravi Verma","link":"https://stackoverflow.com/users/520896/ravi-verma"},"down_vote_count":1,"up_vote_count":5,"is_accepted":false,"score":4,"answer_id":15093614,"share_link":"https://stackoverflow.com/a/15093614","body":"Use php's inbuilt regex support functions\npreg_match_all
\n\nthis would help, suppose you want the array of strings(keys) between @@ in following example, where '/' doesn't fall in-between, you can built new example with different start an end variable
\n\nfunction getInbetweenStrings($start, $end, $str){\n $matches = array();\n $regex = \"/$start([a-zA-Z0-9_]*)$end/\";\n preg_match_all($regex, $str, $matches);\n return $matches[1];\n}\n\n$str = \"C://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@\";\n$str_arr = getInbetweenStrings('@@', '@@', $str);\n\nprint_r($str_arr);\n
\n"},{"owner":{"reputation":84,"user_id":1847939,"user_type":"registered","accept_rate":12,"profile_image":"https://www.gravatar.com/avatar/2c2014d16dd1864c7e380fca91267755?s=128&d=identicon&r=PG","display_name":"szikael","link":"https://stackoverflow.com/users/1847939/szikael"},"down_vote_count":0,"up_vote_count":2,"is_accepted":false,"score":2,"answer_id":20826440,"share_link":"https://stackoverflow.com/a/20826440","body":"$myString = 'reply-234-private';\necho str_replace('-','',filter_var($myString,FILTER_SANITIZE_NUMBER_INT));\n
\n\nThat should do the job.
\n"},{"owner":{"reputation":51,"user_id":2951807,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/8acdc2b48025c8db7f09af79be7aedf6?s=128&d=identicon&r=PG&f=1","display_name":"user2951807","link":"https://stackoverflow.com/users/2951807/user2951807"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":29971866,"share_link":"https://stackoverflow.com/a/29971866","body":"If you want to do it in js, try this function -
\n\nfunction getStringBetween(str , fromStr , toStr){\n var fromStrIndex = str.indexOf(fromStr) == -1 ? 0 : str.indexOf(fromStr) + fromStr.length;\n var toStrIndex = str.slice(fromStrIndex).indexOf(toStr) == -1 ? str.length-1 : str.slice(fromStrIndex).indexOf(toStr) + fromStrIndex;\n var strBtween = str.substring(fromStrIndex,toStrIndex);\n return strBtween;\n}\n
\n"},{"owner":{"reputation":136,"user_id":5870505,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/ea52d19a3204b0e6841ec375dc68058e?s=128&d=identicon&r=PG&f=1","display_name":"Alexis Ochoa","link":"https://stackoverflow.com/users/5870505/alexis-ochoa"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":35834078,"share_link":"https://stackoverflow.com/a/35834078","body":"The function strpos implements a offset param.
\n\nTry this
\n\nfunction getdatabetween($string, $start, $end, $offset){\n $sp = strpos($string, $start, $offset)+strlen($start);\n $ep = strpos($string, $end, $offset)-strlen($start);\n $data = trim(substr($string, $sp, $ep));\n return trim($data);\n}\n
\n"}],"has_more":false,"quota_max":300,"quota_remaining":295}
--------------------------------------------------------------------------------
/tests/data/answers.json:
--------------------------------------------------------------------------------
1 | {"items":[{"owner":{"reputation":20223,"user_id":236047,"user_type":"registered","accept_rate":95,"profile_image":"https://www.gravatar.com/avatar/e083220ac33b47364d345eac8f017919?s=128&d=identicon&r=PG","display_name":"Victor Nicollet","link":"https://stackoverflow.com/users/236047/victor-nicollet"},"down_vote_count":0,"up_vote_count":8,"is_accepted":false,"score":8,"answer_id":1975609,"share_link":"https://stackoverflow.com/a/1975609","body":"To reach a nesting level of 100 on a merge sort, you would need to have an input array of size 2^100(about 1e30), which is impossible. I suspect your recursion is incorrect. For instance, you wrote $start + $end / 2 instead of ($start + $end) / 2.
\n"},{"owner":{"reputation":3304,"user_id":550,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a7d85c71a25c4d596f475a4858b5087c?s=128&d=identicon&r=PG","display_name":"Juan","link":"https://stackoverflow.com/users/550/juan"},"down_vote_count":0,"up_vote_count":7,"is_accepted":true,"score":7,"answer_id":9401151,"share_link":"https://stackoverflow.com/a/9401151","body":"In your merge function, you call count on right instead of $right. PHP assumes this is a string constant (at least in 5.3.9) and when casted into an array that always has one element. So count(right) is always one, and you never exit the first merge.
\n"},{"owner":{"reputation":3476,"user_id":325499,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/888e80528db858833b400d0a7a83dee4?s=128&d=identicon&r=PG","display_name":"Kartik","link":"https://stackoverflow.com/users/325499/kartik"},"down_vote_count":0,"up_vote_count":4,"is_accepted":false,"score":4,"answer_id":9401135,"share_link":"https://stackoverflow.com/a/9401135","body":"Try this approach. Instead of shifting it, slice.
\n\nAlso, for in while loop for the merge function, you need to do an and && comparison instead \nof ||
\n\nfunction mergeSort($array)\n{\n if(count($array) == 1 )\n {\n return $array;\n }\n\n $mid = count($array) / 2;\n $left = array_slice($array, 0, $mid);\n $right = array_slice($array, $mid);\n $left = mergeSort($left);\n $right = mergeSort($right);\n\n return merge($left, $right);\n}\n\n\nfunction merge($left, $right)\n{\n $res = array();\n\n while (count($left) > 0 && count($right) > 0)\n {\n if($left[0] > $right[0])\n {\n $res[] = $right[0];\n $right = array_slice($right , 1);\n }\n else\n {\n $res[] = $left[0];\n $left = array_slice($left, 1);\n }\n }\n\n while (count($left) > 0)\n {\n $res[] = $left[0];\n $left = array_slice($left, 1);\n }\n\n while (count($right) > 0)\n {\n $res[] = $right[0];\n $right = array_slice($right, 1);\n }\n\n return $res;\n}\n
\n"},{"owner":{"reputation":568,"user_id":1158019,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/d45488fe5137373e0ec63746cc840310?s=128&d=identicon&r=PG","display_name":"Avanche","link":"https://stackoverflow.com/users/1158019/avanche"},"down_vote_count":0,"up_vote_count":3,"is_accepted":false,"score":3,"answer_id":9401208,"share_link":"https://stackoverflow.com/a/9401208","body":"Have a look at this, the algorithm is already implemented, using array_push and array splice instead of just array_shift.
\n\nhttp://www.codecodex.com/wiki/Merge_sort#PHP\n
\n"},{"owner":{"reputation":46,"user_id":231648,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/91a1db323b404f866d5ffe9d1912892f?s=128&d=identicon&r=PG","display_name":"OlegK","link":"https://stackoverflow.com/users/231648/olegk"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":1975580,"share_link":"https://stackoverflow.com/a/1975580","body":"Set
\n\nxdebug.max_nesting_level=500 \n
\n\nin my php.ini
\n"},{"owner":{"reputation":96,"user_id":168255,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a95e70ac7b2964b6386b1034473fbe2a?s=128&d=identicon&r=PG","display_name":"Chris Martin","link":"https://stackoverflow.com/users/168255/chris-martin"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":4643794,"share_link":"https://stackoverflow.com/a/4643794","body":"Here's my working solution, feel free to compare...
\n\n/**\n * @param array $items array to sort\n * @param int $l left index (defaults to 0)\n * @param int $r right index (defaults to count($items)-1)\n */\nfunction mergeSort(&$items, $l = 0, $r = null)\n{\n if (!isset($r)) {\n $r = count($items) - 1;\n }\n\n if ($l < $r) {\n $m = floor(($r - $l) / 2) + $l;\n mergeSort($items, $l, $m);\n mergeSort($items, $m + 1, $r);\n merge($items, $l, $m, $r);\n }\n}\n\n/**\n * @param array $items array to merge\n * @param int $l left index\n * @param int $m middle index\n * @param int $r right index\n */\nfunction merge(&$items, $l, $m, $r)\n{\n $itemsA = array_slice($items, $l, $m + 1 - $l);\n $itemsB = array_slice($items, $m + 1, ($r + 1) - ($m + 1));\n\n $a = 0;\n $aCount = count($itemsA);\n $b = 0;\n $bCount = count($itemsB);\n\n for ($i = $l; $i <= $r; $i++) {\n if ($a < $aCount && ($b == $bCount || $itemsA[$a] <= $itemsB[$b])) {\n $items[$i] = $itemsA[$a++];\n } else {\n $items[$i] = $itemsB[$b++];\n }\n }\n}\n\n$items = array(5,3,6,1,2,3,9,10,7,2,4,8);\nmergeSort($items);\necho implode(',', $items) . \"\\n\";\n
\n\nOutputs:
\n\n1,2,2,3,3,4,5,6,7,8,9,10\n
\n"},{"owner":{"reputation":18090,"user_id":64193,"user_type":"registered","accept_rate":94,"profile_image":"https://www.gravatar.com/avatar/6d5d5488960dcb0cab2d02a031e51ba9?s=128&d=identicon&r=PG","display_name":"Scott Saunders","link":"https://stackoverflow.com/users/64193/scott-saunders"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975573,"share_link":"https://stackoverflow.com/a/1975573","body":"There is a maximum function nesting level of '100', and you have reached it. Your recursive function goes too deep.
\n"},{"owner":{"reputation":3758,"user_id":56225,"user_type":"registered","accept_rate":86,"profile_image":"https://i.stack.imgur.com/WpC9A.jpg?s=128&g=1","display_name":"bkildow","link":"https://stackoverflow.com/users/56225/bkildow"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975587,"share_link":"https://stackoverflow.com/a/1975587","body":"From http://www.xdebug.org/docs/all_settings:
\n\n\n xdebug.max_nesting_level\n Type: integer, Default value: 100\n Controls the protection mechanism for infinite recursion protection. The value of this setting is the maximum level of nested functions that are allowed before the script will be aborted.
\n
\n\nYou are going too deep in your recursive function triggering this xdebug error. Try raising this limit and see if that helps.
\n\nAlso, here is an interesting article about recursion and PHP: http://www.alternateinterior.com/2006/09/tail-recursion-in-php.html
\n"},{"owner":{"reputation":91152,"user_id":13508,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/c9e1d852b4d287027fe76f794e506878?s=128&d=identicon&r=PG","display_name":"Álvaro González","link":"https://stackoverflow.com/users/13508/%c3%81lvaro-gonz%c3%a1lez"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975599,"share_link":"https://stackoverflow.com/a/1975599","body":"PHP is not a good language for recursive algorithms. From the manual:
\n\n\n It is possible to call recursive\n functions in PHP. However avoid\n recursive function/method calls with\n over 100-200 recursion levels as it\n can smash the stack and cause a\n termination of the current script.
\n
\n\nIf you need to do it in PHP, you'll probably have to find an iterative version of the algorithm. You've hit a hard-coded limit in the language.
\n"},{"owner":{"reputation":1,"user_id":240972,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/795604ba66d65ddf64ee9c01185b4b3e?s=128&d=identicon&r=PG","display_name":"leo","link":"https://stackoverflow.com/users/240972/leo"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1980751,"share_link":"https://stackoverflow.com/a/1980751","body":"Cosi dovrebbe funzionare!!!! www.dslpg.it
\n\nfunction merge ( &$a, $left, $center, $right ) { //left = p right = r center = q\n $n1 = $center - $left + 1;\n $n2 = $right - $center;\n for ($i = 1; $i <= $n1; $i++) $L[$i] = $a[$left+$i-1];\n for ($i = 1; $i <= $n2; $i++) $R[$i] = $a[$center+$i];\n $L[$n1+1] = 99999;\n $R[$n2+1] = 99999; \n $i = 1;\n $j = 1;\n for ($k = $left; $k <= $right; $k++) {\n if ($L[$i] <= $R[$j] ) {\n $a[$k] = $L[$i];\n echo $a[$k];\n $i++;\n }\n else {\n $a[$k] = $R[$j];\n echo $a[$k];\n $j++;\n }\n }\n return $a;\n}\nfunction merge_sort ( &$a, $left, $right ) { //left = p right = r\n if ( $left < $right ) {\n $center = (int) floor(($left + $right) / 2 );\n\n merge_sort ($a, $left, $center);\n merge_sort ($a, $center+1, $right);\n merge ($a, $left, $center, $right);\n }\n}\nmerge_sort ( $a, 1, $n );\n
\n"},{"owner":{"reputation":19,"user_id":4577836,"user_type":"registered","profile_image":"https://graph.facebook.com/10152731435562825/picture?type=large","display_name":"Rana Kolta","link":"https://stackoverflow.com/users/4577836/rana-kolta"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":42007590,"share_link":"https://stackoverflow.com/a/42007590","body":"Your merge sort accepts a list by reference
\n\nfunction merge_sort(&$list)\n
\n\nSo you need to assign it the new merged and sorted list. So instead of
\n\nreturn merge($left, $right);\n
\n\ndo
\n\n$list = $this->merge($left, $right);\n
\n\nThat should do it, just remove the exit and fix the count variable
\n"},{"owner":{"reputation":71,"user_id":2304608,"user_type":"registered","profile_image":"https://i.stack.imgur.com/Nn1IO.jpg?s=128&g=1","display_name":"ayan sil","link":"https://stackoverflow.com/users/2304608/ayan-sil"},"down_vote_count":1,"up_vote_count":0,"is_accepted":false,"score":-1,"answer_id":16132508,"share_link":"https://stackoverflow.com/a/16132508","body":"<?php\n\n ###################\n #merge sort in php#\n ###################\n$ar=array(2,5,4,3);\nprint_r($ar);\necho \"<br/>\";\n$sar=ms($ar);\nprint_r($sar);\necho \"<br/>\";\nfunction ms($tar)\n{ \n$size=count($tar);\nif($size<=1)\n{\n print_r($tar);\n echo \"<br/>\";\n return $tar;\n} \nelse\n{\n $middle=(int)($size/2);\n for($i=0;$i<$middle;$i++)\n {\n $left[$i]=$tar[$i];\n }\n for($i=$middle,$j=0;$i<$size;$i++,$j++)\n {\n $right[$j]=$tar[$i];\n }\n $tl=ms($left);\n $tr=ms($right);\n $ma=merge($tl,$tr);\n\n return $ma;\n}\n}\nfunction merge($l,$r)\n{\n\n$sizel=count($l);\n$sizer=count($r);\n$j=0;\nwhile(($sizel>0)||($sizer>0))\n{ \n if(($sizel>0) && ($sizer>0))\n {\n if($l[0]<=$r[0])\n {\n $result[$j]=array_shift($l);\n $j++;\n }\n else\n {\n $result[$j]=array_shift($r);\n $j++;\n }\n\n }\n else if($sizel>0)\n {\n $result[$j]=array_shift($l); \n $j++; \n }\n else\n {\n $result[$j]=array_shift($r);\n $j++;\n }\n $sizel=count($l);\n $sizer=count($r);\n}\n return $result; \n}\n?>\n
\n"}],"has_more":false,"quota_max":300,"quota_remaining":273}
--------------------------------------------------------------------------------
/tests/data/badAnswers.json:
--------------------------------------------------------------------------------
1 | {"items":[{"owner":{"reputation":20223,"user_id":236047,"user_type":"registered","accept_rate":95,"profile_image":"https://www.gravatar.com/avatar/e083220ac33b47364d345eac8f017919?s=128&d=identicon&r=PG","display_name":"Victor Nicollet","link":"https://stackoverflow.com/users/236047/victor-nicollet"},"down_vote_count":0,"up_vote_count":8,"is_accepted":false,"score":8,"answer_id":1975609,"share_link":"https://stackoverflow.com/a/1975609","body":"To reach a nesting level of 100 on a merge sort, you would need to have an input array of size 2^100(about 1e30), which is impossible. I suspect your recursion is incorrect. For instance, you wrote $start + $end / 2 instead of ($start + $end) / 2.
\n"},{"owner":{"reputation":3304,"user_id":550,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a7d85c71a25c4d596f475a4858b5087c?s=128&d=identicon&r=PG","display_name":"Juan","link":"https://stackoverflow.com/users/550/juan"},"down_vote_count":0,"up_vote_count":7,"is_accepted":true,"score":7,"answer_id":9401151,"share_link":"https://stackoverflow.com/a/9401151","body":"In your merge function, you call count on right instead of $right. PHP assumes this is a string constant (at least in 5.3.9) and when casted into an array that always has one element. So count(right) is always one, and you never exit the first merge.
\n"},{"owner":{"reputation":3476,"user_id":325499,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/888e80528db858833b400d0a7a83dee4?s=128&d=identicon&r=PG","display_name":"Kartik","link":"https://stackoverflow.com/users/325499/kartik"},"down_vote_count":0,"up_vote_count":4,"is_accepted":false,"score":4,"answer_id":9401135,"share_link":"https://stackoverflow.com/a/9401135","body":"Try this approach. Instead of shifting it, slice.
\n\nAlso, for in while loop for the merge function, you need to do an and && comparison instead \nof ||
\n\nfunction mergeSort($array)\n{\n ifcount($array) == 1 )\n {\n return $array;\n }\n\n $mid = count($array) / 2;\n $left = array_slice($array, 0, $mid);\n $right = array_slice($array, $mid);\n $left = mergeSort($left);\n $right = mergeSort($right);\n\n return merge($left, $right);\n}\n\n\nfunction merge($left, $right)\n{\n $res = array();\n\n while (count($left) > 0 && count($right) > 0)\n {\n if($left[0] > $right[0])\n {\n $res[] = $right[0];\n $right = array_slice($right , 1);\n }\n else\n {\n $res[] = $left[0];\n $left = array_slice($left, 1);\n }\n }\n\n while (count($left) > 0)\n {\n $res[] = $left[0];\n $left = array_slice($left, 1);\n }\n\n while (count($right) > 0)\n {\n $res[] = $right[0];\n $right = array_slice($right, 1);\n }\n\n return $res;\n}\n
\n"},{"owner":{"reputation":568,"user_id":1158019,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/d45488fe5137373e0ec63746cc840310?s=128&d=identicon&r=PG","display_name":"Avanche","link":"https://stackoverflow.com/users/1158019/avanche"},"down_vote_count":0,"up_vote_count":3,"is_accepted":false,"score":3,"answer_id":9401208,"share_link":"https://stackoverflow.com/a/9401208","body":"Have a look at this, the algorithm is already implemented, using array_push and array splice instead of just array_shift.
\n\nhttp://www.codecodex.com/wiki/Merge_sort#PHP\n
\n"},{"owner":{"reputation":46,"user_id":231648,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/91a1db323b404f866d5ffe9d1912892f?s=128&d=identicon&r=PG","display_name":"OlegK","link":"https://stackoverflow.com/users/231648/olegk"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":1975580,"share_link":"https://stackoverflow.com/a/1975580","body":"Set
\n\nxdebug.max_nesting_level=500 \n
\n\nin my php.ini
\n"},{"owner":{"reputation":96,"user_id":168255,"user_type":"registered","profile_image":"https://www.gravatar.com/avatar/a95e70ac7b2964b6386b1034473fbe2a?s=128&d=identicon&r=PG","display_name":"Chris Martin","link":"https://stackoverflow.com/users/168255/chris-martin"},"down_vote_count":0,"up_vote_count":1,"is_accepted":false,"score":1,"answer_id":4643794,"share_link":"https://stackoverflow.com/a/4643794","body":"Here's my working solution, feel free to compare...
\n\n/**\n * @param array $items array to sort\n * @param int $l left index (defaults to 0)\n * @param int $r right index (defaults to count($items)-1)\n */\nfunction mergeSort(&$items, $l = 0, $r = null)\n{\n if (!isset($r)) {\n $r = count($items) - 1;\n }\n\n if ($l < $r) {\n $m = floor(($r - $l) / 2) + $l;\n mergeSort($items, $l, $m);\n mergeSort($items, $m + 1, $r);\n merge($items, $l, $m, $r);\n }\n}\n\n/**\n * @param array $items array to merge\n * @param int $l left index\n * @param int $m middle index\n * @param int $r right index\n */\nfunction merge(&$items, $l, $m, $r)\n{\n $itemsA = array_slice($items, $l, $m + 1 - $l);\n $itemsB = array_slice($items, $m + 1, ($r + 1) - ($m + 1));\n\n $a = 0;\n $aCount = count($itemsA);\n $b = 0;\n $bCount = count($itemsB);\n\n for ($i = $l; $i <= $r; $i++) {\n if ($a < $aCount && ($b == $bCount || $itemsA[$a] <= $itemsB[$b])) {\n $items[$i] = $itemsA[$a++];\n } else {\n $items[$i] = $itemsB[$b++];\n }\n }\n}\n\n$items = array(5,3,6,1,2,3,9,10,7,2,4,8);\nmergeSort($items);\necho implode(',', $items) . \"\\n\";\n
\n\nOutputs:
\n\n1,2,2,3,3,4,5,6,7,8,9,10\n
\n"},{"owner":{"reputation":18090,"user_id":64193,"user_type":"registered","accept_rate":94,"profile_image":"https://www.gravatar.com/avatar/6d5d5488960dcb0cab2d02a031e51ba9?s=128&d=identicon&r=PG","display_name":"Scott Saunders","link":"https://stackoverflow.com/users/64193/scott-saunders"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975573,"share_link":"https://stackoverflow.com/a/1975573","body":"There is a maximum function nesting level of '100', and you have reached it. Your recursive function goes too deep.
\n"},{"owner":{"reputation":3758,"user_id":56225,"user_type":"registered","accept_rate":86,"profile_image":"https://i.stack.imgur.com/WpC9A.jpg?s=128&g=1","display_name":"bkildow","link":"https://stackoverflow.com/users/56225/bkildow"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975587,"share_link":"https://stackoverflow.com/a/1975587","body":"From http://www.xdebug.org/docs/all_settings:
\n\n\n xdebug.max_nesting_level\n Type: integer, Default value: 100\n Controls the protection mechanism for infinite recursion protection. The value of this setting is the maximum level of nested functions that are allowed before the script will be aborted.
\n
\n\nYou are going too deep in your recursive function triggering this xdebug error. Try raising this limit and see if that helps.
\n\nAlso, here is an interesting article about recursion and PHP: http://www.alternateinterior.com/2006/09/tail-recursion-in-php.html
\n"},{"owner":{"reputation":91152,"user_id":13508,"user_type":"registered","accept_rate":88,"profile_image":"https://www.gravatar.com/avatar/c9e1d852b4d287027fe76f794e506878?s=128&d=identicon&r=PG","display_name":"Álvaro González","link":"https://stackoverflow.com/users/13508/%c3%81lvaro-gonz%c3%a1lez"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1975599,"share_link":"https://stackoverflow.com/a/1975599","body":"PHP is not a good language for recursive algorithms. From the manual:
\n\n\n It is possible to call recursive\n functions in PHP. However avoid\n recursive function/method calls with\n over 100-200 recursion levels as it\n can smash the stack and cause a\n termination of the current script.
\n
\n\nIf you need to do it in PHP, you'll probably have to find an iterative version of the algorithm. You've hit a hard-coded limit in the language.
\n"},{"owner":{"reputation":1,"user_id":240972,"user_type":"unregistered","profile_image":"https://www.gravatar.com/avatar/795604ba66d65ddf64ee9c01185b4b3e?s=128&d=identicon&r=PG","display_name":"leo","link":"https://stackoverflow.com/users/240972/leo"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":1980751,"share_link":"https://stackoverflow.com/a/1980751","body":"Cosi dovrebbe funzionare!!!! www.dslpg.it
\n\nfunction merge ( &$a, $left, $center, $right ) { //left = p right = r center = q\n $n1 = $center - $left + 1;\n $n2 = $right - $center;\n for ($i = 1; $i <= $n1; $i++) $L[$i] = $a[$left+$i-1];\n for ($i = 1; $i <= $n2; $i++) $R[$i] = $a[$center+$i];\n $L[$n1+1] = 99999;\n $R[$n2+1] = 99999; \n $i = 1;\n $j = 1;\n for ($k = $left; $k <= $right; $k++) {\n if ($L[$i] <= $R[$j] ) {\n $a[$k] = $L[$i];\n echo $a[$k];\n $i++;\n }\n else {\n $a[$k] = $R[$j];\n echo $a[$k];\n $j++;\n }\n }\n return $a;\n}\nfunction merge_sort ( &$a, $left, $right ) { //left = p right = r\n if ( $left < $right ) {\n $center = (int) floor(($left + $right) / 2 );\n\n merge_sort ($a, $left, $center);\n merge_sort ($a, $center+1, $right);\n merge ($a, $left, $center, $right);\n }\n}\nmerge_sort ( $a, 1, $n );\n
\n"},{"owner":{"reputation":19,"user_id":4577836,"user_type":"registered","profile_image":"https://graph.facebook.com/10152731435562825/picture?type=large","display_name":"Rana Kolta","link":"https://stackoverflow.com/users/4577836/rana-kolta"},"down_vote_count":0,"up_vote_count":0,"is_accepted":false,"score":0,"answer_id":42007590,"share_link":"https://stackoverflow.com/a/42007590","body":"Your merge sort accepts a list by reference
\n\nfunction merge_sort(&$list)\n
\n\nSo you need to assign it the new merged and sorted list. So instead of
\n\nreturn merge($left, $right);\n
\n\ndo
\n\n$list = $this->merge($left, $right);\n
\n\nThat should do it, just remove the exit and fix the count variable
\n"},{"owner":{"reputation":71,"user_id":2304608,"user_type":"registered","profile_image":"https://i.stack.imgur.com/Nn1IO.jpg?s=128&g=1","display_name":"ayan sil","link":"https://stackoverflow.com/users/2304608/ayan-sil"},"down_vote_count":1,"up_vote_count":0,"is_accepted":false,"score":-1,"answer_id":16132508,"share_link":"https://stackoverflow.com/a/16132508","body":"<?php\n\n ###################\n #merge sort in php#\n ###################\n$ar=array(2,5,4,3);\nprint_r($ar);\necho \"<br/>\";\n$sar=ms($ar);\nprint_r($sar);\necho \"<br/>\";\nfunction ms($tar)\n{ \n$size=count($tar);\nif($size<=1)\n{\n print_r($tar);\n echo \"<br/>\";\n return $tar;\n} \nelse\n{\n $middle=(int)($size/2);\n for($i=0;$i<$middle;$i++)\n {\n $left[$i]=$tar[$i];\n }\n for($i=$middle,$j=0;$i<$size;$i++,$j++)\n {\n $right[$j]=$tar[$i];\n }\n $tl=ms($left);\n $tr=ms($right);\n $ma=merge($tl,$tr);\n\n return $ma;\n}\n}\nfunction merge($l,$r)\n{\n\n$sizel=count($l);\n$sizer=count($r);\n$j=0;\nwhile(($sizel>0)||($sizer>0))\n{ \n if(($sizel>0) && ($sizer>0))\n {\n if($l[0]<=$r[0])\n {\n $result[$j]=array_shift($l);\n $j++;\n }\n else\n {\n $result[$j]=array_shift($r);\n $j++;\n }\n\n }\n else if($sizel>0)\n {\n $result[$j]=array_shift($l); \n $j++; \n }\n else\n {\n $result[$j]=array_shift($r);\n $j++;\n }\n $sizel=count($l);\n $sizer=count($r);\n}\n return $result; \n}\n?>\n
\n"}],"has_more":false,"quota_max":300,"quota_remaining":273}
--------------------------------------------------------------------------------