PHP Maths Logic - php
I am trying to set a variable based on some maths logic (to wrap specific html around elements).
I worked half the problem, to hit 0, 3, 6, 9, 12
if(($i % 3) == 0) { // blah }
Now I need to hit the following numbers, 2, 5, 8, 11, 14, etc
What possible maths operation could I do to hit this sequence?
if($i % 3 == 1)
if($i % 3 == 2)
Modulo returns the remainder, so when you match the 0, you get the 3rd, 6th, 9th, etc, because 0 is left in the division.
So just check for when 1 remains and 2 remains.
Along with Tor Valamo's answer you can notice the pattern of (3 * $i) - 1
(3*1)-1 = 2
(3*2)-1 = 5
(3*3)-1 = 8
...
if((($i-2) % 3) == 0) { // blah }
Related
Get the sum of all carried digits while performing addition on 2 or more integers
I've got this task, which I honestly don't understand what exactly to do. It my be because of my English level, or mathmatics level, but this is really something I can not make sense of. Could you help be at least to understand the task ? My php knowledge is very well, at least I thought so... The task is this : "Carry" is a term of an elementary arithmetic. It's a digit that you transfer to column with higher significant digits when adding numbers. This task is about getting the sum of all carried digits. You will receive an array of two numbers, like in the example. The function should return the sum of all carried digits. function carry($arr) { // ... } carry([123, 456]); // 0 carry([555, 555]); // 3 (carry 1 from ones column, carry 1 from tens column, carry 1 from hundreds column) carry([123, 594]); // 1 (carry 1 from tens column) Support of arbitrary number of operands will be a plus: carry([123, 123, 804]); // 2 (carry 1 from ones column, carry 1, carry 1 from hundreds column)
Background information on "carry": https://en.m.wikipedia.org/wiki/Carry_(arithmetic) For this task, we don't actually need the numbers written under the equals line, just the numbers which are carried. Importantly, the carried numbers need to be used when calculating subsequent columns. Before looping each column of integers, reverse the order of the columns so that looping from left-to-right also iterates the lowest unit column and progresses to higher unit columns (ones, then tens, then hundreds, etc). For flexibility, my snippet is designed to handle numbers of dynamic length. If processing potential float numbers, you could merely multiply all number by a power of 10 to convert all values to integers. My snippet is not designed to handled signed integers. Code: (Demo) function sumCarries(array $array) { $columns = ['carries' => []]; // prepare matrix of 1-digit integers in columns -- ones, tens, hundreds, etc foreach ($array as $integer) { $columns[] = str_split(strrev($integer)); } // sum column values in ascending order and populate carry values // subsequent column sums need to include carried value for ($i = 0, $len = strlen(max($array)); $i < $len; ++$i) { $columns['carries'][$i + 1] = (int)(array_sum(array_column($columns, $i)) / 10); } // sum all populated carry values return array_sum($columns['carries']); } $tests = [ [123, 456], // no carries in any column [555, 555], // 1 ones, 1 tens, 1 hundreds [123, 594], // 1 tens [123, 123, 804], // 1 ones, 1 hundreds [99, 9, 99, 99, 99], // 4 ones, 4 hundreds [9,9,9,9,9,9,9,9,9,9,9,9], // 10 ones ]; var_export(array_map('sumCarries', $tests)); Output: array ( 0 => 0, 1 => 3, 2 => 1, 3 => 2, 4 => 8, 5 => 10, )
Since it's homework, I'm not going to fully answer the question, but explain the pieces you seem confused about so that you can put them together. 1 11 111 111 <- these are the carry digits 555 555 555 555 555 + 555 -> + 555 -> + 555 -> + 555 -> + 555 ----- ----- ----- ----- ----- 0 10 110 1110 For a better example of two digits, let's use 6+6. To get the carry digit you can use the modulus operator where 12 % 10 == 2. So, (12 - (12 % 10)) / 10 == 1.
Thank you again. #Sammitch I got it to make it work. Actually the problem was my English Math Level. The term "Carry digits" had no meaning at all for me. I was completely focusing on something else. Here is my code : It may be far from perfect, but it does the job :) function carry($arr) { $sum_ones = 0; $sum_tens = 0; $sum_hunds = 0; $arrCount = count($arr); foreach($arr as $key){ $stri = (string)$key; $foo[] = array( "hunds" => $stri[0], "tens" => $stri[1], "ones" => $stri[2] ); } $fooCount = count($foo); for($i=0; $i<$fooCount; $i++) { $sum_ones+= $foo[$i]["ones"]; $sum_tens+= $foo[$i]["tens"]; $sum_hunds+= $foo[$i]["hunds"]; } $sum1 = ($sum_ones - ($sum_ones % 10)) / 10; $sum10 = ($sum_tens - ($sum_tens % 10)) / 10; $sum100 = ($sum_hunds - ($sum_hunds % 10)) / 10; return ($sum1 + $sum10 + $sum100); } $arr = array(555, 515, 111); echo carry($arr);
Validate A Game Board, And Fast
I am creating a multiplayer Battleship game using an Apache/PHP server (yes, I know Node would be much better for this, but I'll get around to learning it later). Anyways, I am at the point in which both players are uploading their game boards to start the game. While my client side JavaScript would obviously properly compile and validate boards before sending them off to the server, that is still vulnerable to cheating, so the server must also double check. However, on the server, speed and efficiency is everything. As of now, this is the process my server follows: Server receives the board as a JSON encoded multidimensional array via an AJAX request. $board = json_decode($_REQUEST["board"]); Server validates the structure of the passed input. $validate = array(gettype($board) == "array", count($board) == 10); for($i = 0; $i < count($board); $i++) { array_push($validate, count($board[$i]) == 10); for($ii = 0; $ii < count($board[$i]); $ii++) { array_push($validate, gettype($board[$i][$ii]) == "integer"); } } if(in_array(0, $validate)) throwError(); In the array, numbers zero through five represent blank, aircraft carrier, battleship, cruiser, submarine, and destroyer tiles respectively. I count the proper quantity of each. $valueCount = array_count_values(array_merge($board[0], $board[1], $board[2], $board[3], $board[4], $board[5], $board[6], $board[7], $board[8], $board[9])); $template = array("0"=>83,"1"=>5, "2"=>4, "3"=>3, "4"=>3, "5"=>2); if($template != $valueCount) throwError(); I need to ensure that ship tiles are only vertical or horizontal lines. $shipsValid = array(false, false, false, false, false); $transpose = array_map(null, $board[0], $board[1], $board[2], $board[3], $board[4], $board[5], $board[6], $board[7], $board[8], $board[9]); for($i = 0; $i < 9; $i++) { $temp1 = array_count_values($board[$i]); $temp2 = array_count_values($transpose[$i]); if($temp1["1"] == 5 || $temp2["1"] == 5) shipsValid[0] = true; if($temp1["2"] == 4 || $temp2["2"] == 4) shipsValid[1] = true; if($temp1["3"] == 3 || $temp2["3"] == 3) shipsValid[2] = true; if($temp1["4"] == 3 || $temp2["4"] == 3) shipsValid[3] = true; if($temp1["5"] == 2 || $temp2["5"] == 2) shipsValid[4] = true; } if(in_array(0, $shipsValid)) throwError(); I need to ensure ships are continuous with no gaps. ?????????????????????????? With enough work, I could have completed step five, but it would have been grossly inefficient, looping through everything repeatedly. So, in conclusion, how can I make what I have designed more efficient, and how I complete the final step (5) to validating the uploaded board? Example Board (Valid): "[[0,1,1,1,1,1,0,0,0,0], [0,0,0,0,0,0,0,2,0,0], [0,0,0,0,0,0,0,2,0,0], [0,0,0,0,0,0,0,2,0,0], [0,3,3,3,0,0,0,2,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,5,0,0,0,4,4,4,0], [0,0,5,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]]" Example Board (Invalid, for many reasons): "[[0,1,1,0,1,1,0,0,0,1], [0,0,0,0,0,0,0,2,0,0], [0,0,0,0,0,0,0,2,0,0], [0,0,0,0,0,0,0,2,0,0], [0,6,6,6,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,4,4,4,4,4], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0]]"
This solution is ugly and not clearly explained inline, but it does set the time record here with an average of 47.99473047 µs to validate a correct board on my server. I do apologize for the excessive use of inline logic structures; its kinda my coding style. function quit() { echo "invalid request"; exit(); } $board = json_decode($_REQUEST["board"]); if(gettype($board) != "array"|| count($board) != 10) quit(); foreach($board as $row) { if(gettype($row) != "array"|| count($row) != 10) quit(); foreach($row as $cell) if(gettype($cell) != "integer") quit(); } $strand = array_merge($board[0], $board[1], $board[2], $board[3], $board[4], $board[5], $board[6], $board[7], $board[8], $board[9]); $fleet = array(array_keys($strand, 0), array_keys($strand, 1), array_keys($strand, 2), array_keys($strand, 3), array_keys($strand, 4), array_keys($strand, 5)); if(count($fleet[0]) != 83 || count($fleet[1]) != 5 || count($fleet[2]) != 4 || count($fleet[3]) != 3 || count($fleet[4]) != 3 || count($fleet[5]) != 2 || count($fleet) != 6) quit(); foreach($fleet as $ship) if($ship != $fleet[0]) for($i = 0; $i < count($ship); $i++) if($ship[0] + 10 * $i != $ship[$i] && $ship[$i] - $ship[0] != $i) quit(); echo "success"; exit(); This process first checks that the array is properly structured (10 by 10 with integer values). It then combines all the arrays into one long array and fetches the keys of the values 0 through 5. I then check that the proper amount of each number (for each ship) occurs in the keys. Lastly, I check that keys for 1 through 5 occur sequentially or by tens, which would mean that they are horizontal or vertical. It feels kinda weird answering my own question, but I'm open to other ideas and optimizations on top of my own.
Version 2: Now with the highest priority on speed of validation.(no json_decode() call needed) The following are my two valid test $board strings. Between the two of them, all ships occur in both orientations. Test #1: [[0,1,1,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,2,0,0],[0,0,0,0,0,0,0,2,0,0],[0,0,0,0,0,0,0,2,0,0],[0,3,3,3,0,0,0,2,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,5,0,0,0,4,4,4,0],[0,0,5,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0]] Test #2: [[0,1,0,0,0,0,0,0,0,0],[0,1,0,0,2,2,2,2,0,0],[0,1,0,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0,0,0],[0,1,3,0,0,0,0,0,0,0],[0,0,3,0,0,0,0,0,0,0],[0,0,3,0,0,0,0,0,0,0],[0,0,5,5,0,0,4,0,0,0],[0,0,0,0,0,0,4,0,0,0],[0,0,0,0,0,0,4,0,0,0]] The method to follow is a simple preg_match() call in php. The technique uses lookaheads to validate each ship, followed by a fullstring match that validates the json structure. This technique is most commonly used when validating passwords, where a string must be generally validated for length and/or valid characters, but also checked for minimum occurrences of characters or ranges of characters (e.g. password must be a minimum of 8 characters and include a lowercase, uppercase, number, and a symbol). The brilliance in my method is not just that it is a single call, but that it can also be seamlessly called to validate the data in javascript as well. Now for the patterns (seatbelts on, please): Pattern #1: "Longer but Faster" (1590 characters) (Test#1: 371 steps; Test#2 446 steps) /(?=^[^1]*(?:1,1,1,1,1|1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1)[^1]*$)(?=^[^2]*(?:2,2,2,2|2\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+2\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+2\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+2)[^2]*$)(?=^[^3]*(?:3,3,3|3\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+3\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+3)[^3]*$)(?=^[^4]*(?:4,4,4|4\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+4\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+4)[^4]*$)(?=^[^5]*(?:5,5|5\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+5)[^5]*$)^\[\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\]\]$/ Pattern #2: "Shorter but Slower" (306 characters) (Test#1: 576 steps; Test#2 698 steps) /(?=^[^1]*(?:1,1,1,1,1|1(?:(?:\D+[^1]){9}\D+1){4})[^1]*$)(?=^[^2]*(?:2,2,2,2|2(?:(?:\D+[^2]){9}\D+2){3})[^2]*$)(?=^[^3]*(?:3,3,3|3(?:(?:\D+[^3]){9}\D+3){2})[^3]*$)(?=^[^4]*(?:4,4,4|4(?:(?:\D+[^4]){9}\D+4){2})[^4]*$)(?=^[^5]*(?:5,5|5(?:\D+[^5]){9}\D+5)[^5]*$)(?:(?:^\[|)\[[0-5](?:,[0-5]){9}\](?:,|\]$)){10}/ The 4 pillars of a good regex pattern... The reason the first pattern is faster is because I have removed all inessential non-capture groups. The cost, in terms of "Brevity", is drastic. "Readability" is extremely poor in both of patterns. Both patterns maintain the same "Accuracy", but the first pattern wins on "Efficiency" by some margin. As for the pattern components... All lookaheads have the same basic structure and obey the game rules/requirements: (?= #lookahead, but don't "consume" any characters in the process ^ #from the start of the string [^5]* #quickly, greedily match all characters that are not a 5 (?: #non-capture group to isolate the "alternatives" 5,5 #literally match a 2-peg row | # or 5\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+5 #match two 5 pegs that have nine non-5 pegs between them ) #end non-capture group [^5]* #quickly, greedily match all characters that are not a 5 (ensure there are no more 5's in the string) $ #all the way to the end of the string ) #end the lookahead The general board structure & pegs matching: ^ #from the start of the string \[ #match the opening outer bracket \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\], #match a row of 0, 1, 2, 3, 4, or 5's \[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\] #match a row of 0, 1, 2, 3, 4, or 5's \] #match the closing outer bracket $ #to the end of the string PHP Code: (Demo) $pattern='/(?=^[^1]*(?:1,1,1,1,1|1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+[^1]\D+1)[^1]*$)(?=^[^2]*(?:2,2,2,2|2\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+2\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+2\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+[^2]\D+2)[^2]*$)(?=^[^3]*(?:3,3,3|3\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+3\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+[^3]\D+3)[^3]*$)(?=^[^4]*(?:4,4,4|4\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+4\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+[^4]\D+4)[^4]*$)(?=^[^5]*(?:5,5|5\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+[^5]\D+5)[^5]*$)^\[\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\],\[[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5],[0-5]\]\]$/'; echo preg_match($pattern,$_REQUEST["board"]) ? 'success' : 'invalid';
Algorithm for a poker-style scoring system
What I need is to create five random integer (say rand(1,5)). Then, I generate a score based on these numbers. For instance, if I get a result of 1,2,3,4,5 then that would equal a zero score, but if I got 1,1,3,4,5 that would be 1 as we have a pair. Similar to a poker kind of scoring, so five of the same number would be a "full house" thus resulting in the highest score. How would I go about the scoring system, even if it is just the mathematical equation? More detail: 1-5 will hold separate images and then will be fought against "The House" which will have identical code to the user to determine the winner. Here's some example draws and the score they would receive: 1,2,3,4,5 = score 0 1,1,2,3,4 = score 1 (1 pair) 1,1,2,2,4 = score 2 (2 pair) 1,1,1,3,4 = score 3 (3 of a kind) 1,1,1,1,5 = score 4 (4 of a kind) 1,1,1,3,3 = score 5 (full house) 1,1,1,1,1 = score 6 (5 of a kind) The combination of numbers is irreverent if they score 6 and the house scores 6, it's a tie. if (isset($_POST['play'])) { $rand1 = rand(1, 5); $rand2 = rand(1, 5); $rand3 = rand(1, 5); $rand4 = rand(1, 5); $rand5 = rand(1, 5); if ($_POST['bet'] <= $user_data['coins']) { if ($_POST['bet'] < 999999999) { if ($_POST['bet'] > 0.99) { if ($user_data['coins'] >= 1) { $array = array($rand1,$rand2,$rand3,$rand4,$rand5); print_r(array_count_values($array)); echo $rand1.', '.$rand2.', '.$rand3.', '.$rand4.', '.$rand5; Array( // Here I don't understand 1 => 3,// 2 => 1,// 3 => 1 // ); } } } } } This outputs ; Array ( [5] => 2 [4] => 2 [1] => 1 ) 5, 5, 4, 4, 1
Use array_count_value function for this. $array = array(1,1,1,2,5); print_r(array_count_values($array)); Array( 1 => 3, 2 => 1, 3 => 1 );
Here's the approach I would consider, building on #Lele's answer. Warning: this is a bit confusing, so sit down with a cup of tea for this one. Build a set of five buckets, [1] to [5], and scan a player's numbers, so that the count for each number is stored in the corresponding bucket Then count the numbers you are left with into a new bucket system, with each position representing the number of counts you have for something. So, if your score is this: 1 1 2 2 4 Then your first buckets are: 2 2 0 1 0 That's because you have two ones, two twos, and one four. And your second buckets are: 1 2 0 0 0 That's because you have two two-counts, and one one-count. Here, you disregard the first position (since a one-count for something does not score anything) and score for the others. So, test for two twos, and score that two. If you score is this: 5 5 5 5 1 Then your first buckets are: 1 0 0 0 4 That's one one and four fives. So your second buckets are: 1 0 0 1 0 Your lookup table for this could be: x 1 0 0 0 -> one pair x 2 0 0 0 -> two pairs x 0 1 0 0 -> three of a kind x 1 1 0 0 -> full house x 0 0 1 0 -> four of a kind x 0 0 0 1 -> five of a kind The 'x' means that you don't match on this. So, your lookup table matches four numbers to a score. I was rather interested in this problem, so I have written some code to do the above. You'll still need to do the lookup table, but that is relatively trivial, and will be good practice for you. Here is a demo, with comments (run code here): <?php function counting(array $array) { // Input figures print_r($array); // Run the figures twice through the bucket-counter $firstBuckets = bucketCounter($array); $secondBuckets = bucketCounter($firstBuckets); // Ignore counts of 1 array_shift($secondBuckets); // Output, just need to do the lookup now echo ' converts to '; print_r($secondBuckets); echo "<br />"; } /** * Bucket counter */ function bucketCounter(array $array) { $result = array(0, 0, 0, 0, 0, ); foreach($array as $value) { if ($value > 0) { $result[$value - 1]++; } } return $result; } // Try some demos here! counting(array(1, 2, 3, 4, 5)); counting(array(1, 1, 2, 4, 2)); counting(array(1, 1, 1, 1, 1)); ?> The demos I've included seem to work, but do hunt for bugs!
If the range is quite small, you can use counting sort approach. For each number, provide a "bucket" to count how many times a number appear. Scan once to fill in the buckets. Then another scan, but this time against the bucket to get the highest value. That's your score.
How to determine if a digit divided by 8 is an integer?
How do I determine if a digit divided by 8 is an integer? for example: 32 % 8 = 4, it is an integer. 25 % 8 = 3.125, it is not an integer. I need a working code like: if ($str % 8 == integer){ // continue working }
the % operator, modulo, will ALWAYS return an integer - it's the remainder of the division. If you mean you want to check if a number is evenly divisible by 8, then do if ($str % 8 == 0) { ... evenly divisible by 8 ... }
you can go with if (val % 8 == 0) or with more tricky ways, like val & 0x0FFF == 0 by using bitwise operators. Somehow they work in the same way: first snippet checks if the remainder of the division by 8 is zero while second checks if number doesn't have any binary digit for 1, 2, or 4, which would make the number not divisible by 8.
I think this is what you need: if(is_int($integer)) { // do something with integer }
What does the percent sign mean in PHP?
What exactly does this mean? $number = ( 3 - 2 + 7 ) % 7;
It's the modulus operator, as mentioned, which returns the remainder of a division operation. Examples: 3%5 returns 3, as 3 divided by 5 is 0 with a remainder of 3. 5 % 10 returns 5, for the same reason, 10 goes into 5 zero times with a remainder of 5. 10 % 5 returns 0, as 10 divided by 5 goes exactly 2 times with no remainder. In the example you posted, (3 - 2 + 7) works out to 8, giving you 8 % 7, so $number will be 1, which is the remainder of 8/7.
It is the modulus operator: $a % $b = Remainder of $a divided by $b. It is often used to get "one element every N elements". For instance, to only get one element each three elements: for ($i=0 ; $i<10 ; $i++) { if ($i % 3 === 0) { echo $i . '<br />'; } } Which gets this output: 0 3 6 9 (Yeah, OK, $i+=3 would have done the trick; but this was just a demo.)
It is the modulus operator. In the statement $a % $b the result is the remainder when $a is divided by $b
Using this operator one can easily calculate odd or even days in month for example, if needed for schedule or something: <?php echo (date(j) % 2 == 0) ? 'Today is even date' : 'Today is odd date'; ?>
% means modulus. Modulus is the fancy name for "remainder after divide" in mathematics. (numerator) mod (denominator) = (remainder) In PHP <?php $n = 13; $d = 7 $r = "$n % $d"; echo "$r is ($n mod $d)."; ?> In this case, this script will echo 6 is (13 mod 7). Where $r is for the remainder (answer), $n for the numerator and $d for the denominator. The modulus operator is commonly used in public-key cryptography due to its special characteristic as a one-way function.
Since so many people say "modulus finds the remainder of the divisor", let's start by defining exactly what a remainder is. In mathematics, the remainder is the amount "left over" after performing some computation. In arithmetic, the remainder is the integer "left over" after dividing one integer by another to produce an integer quotient (integer division). See: http://en.wikipedia.org/wiki/Remainder So % (integer modulus) is a simple way of asking, "How much of the divisor is left over after dividing?" To use the OP's computation of (3 - 2 + 7) = 8 % 7 = 1: It can be broken down into: (3 - 2 + 7) = 8 8 / 7 = 1.143 #Rounded up .143 * 7 = 1.001 #Which results in an integer of 1 7 can go into 8 1 time with .14 of 7 leftover That's all there is to it. I hope this helps to simplify how exactly modulus works. Additional examples using different divisors with 21. Breakdown of 21 % 3 = 0: 21 / 3 = 7.0 3 * 0 = 0 (3 can go into 21 7 times with 0 of 3 leftover) Breakdown of 21 % 6 = 3: 21 / 6 = 3.5 .5 * 6 = 3 (6 can go into 21 3 times with .5 of 6 leftover) Breakdown of 21 % 8 = 5: 21 / 8 = 2.625 .625 * 8 = 5 (8 can go into 21 2 times with .625 of 8 leftover)