I'm new to Php and today I came across the rand()-function. I'd like to fill an array with numbers created with this function and then count the number of its duplicates. I already tried it a first time, but somehow I seem to be on the woodway.
<?php
$numbers = array();
for ($i=0; $i < 100; $i++) {
$numbers[$i] = rand(0, 100);
}
//$numbers = array(12,12,12,12);
echo "random numbers generated.<br>";
$arrLength = count($numbers);
$arrWithDoubles = array();
for ($i=0; $i < $arrLength; $i++) {
//echo "start looping for i: ".$i."! numbers['i'] has the content".$numbers[$i].".<br>";
for ($x=$i; $x < $arrLength; $x++) {
//echo "looped for x: ".$x."! numbers['x'] has the content".$numbers[$x].".<br>";
if($numbers[$i] == $numbers[$x]) {
if($i != $x) {
//echo "pushed to 'arrWithDoubles'.<br>";
array_push($arrWithDoubles, $numbers[$x]);
}
}
}
}
echo "numbers of doubles: ".count($arrWithDoubles)."<br>";
echo "list of numbers which were double:<br>";
for ($i=0; $i < count($arrWithDoubles); $i++) {
echo $arrWithDoubles[$i];
echo "<br>";
}
?>
The array_unique() function removes duplicates from an array, then just add a bit of math.
<?php
$numberOfDuplicates = count($orginalArray) - (count($orginalArray) - count(array_unique($originalArray)));
?>
$origin = array(2,4,5,4,6,2);
$count_origin = count($origin);
$unique = array_unique($origin);
$count_unique = count($unique);
$duplicates = $count_origin - $count_unique;
echo $duplicates;
$count = array();
foreach ($srcRandom as $sr) {
if (!array_key_exists ($sr, $count) ) {
$count[$sr] = 1;
continue;
}
$count[$sr]++;
}
var_dump ($count);
Thanks for all your input. With that I came to the following solution which fits my demand the best:
<?php
function countValueInArray($value, $array) {
$count = 0;
for ($i=0; $i < count($array); $i++) {
if($value == $array[$i]) {
$count++;
}
}
return $count;
}
$numbers = array();
for ($i=0; $i < 100; $i++) {
$numbers[$i] = rand(0, 100);
}
$duplicates = array();
for ($x=0; $x < count($numbers); $x++) {
$number = countValueInArray($numbers[$x], $numbers);
if ($number > 1) {
array_push($duplicates, $numbers[$x]);
}
}
$duplicatesList = array_values(array_unique($duplicates));
echo "number of duplicates: ".count($duplicatesList);
echo "<br>these are: <br>";
print_r($duplicatesList);
?>
Thanks a lot for your help!
Related
I'm trying to look for a number with maximum divisors in a range of 1 - 10000.
I succeeded, but then I wish to verify if there exist more than two max divisors and print them out. My array is really the problem. How can I clear an array and assign a new integer to it in an if else if statement?
Here is what I have tried:
function countDivisors(){
$input = 10000;
$maxNumOfDiv = -1;
$intWMaxDivs = -1;
$curNumOfDiv = 0;
$arr = array();
for($i=1; $i <= $input; $i++) {
$curNumOfDiv = 0;
for ($j = 1; $j < $i; $j++){
if ($i % $j == 0)
$curNumOfDiv++;
}
if($curNumOfDiv = $maxNumOfDiv){
$arr[] = $i;
$intWMaxDivs = $i;
$maxNumOfDiv = $curNumOfDiv;
} else if($curNumOfDiv > $maxNumOfDiv){
$arr = array();
$arr[] = $intWMaxDivs
$maxNumOfDiv = $curNumOfDiv;
}
}
for ($i; $i < count($arr); $i++){
echo $arr[$i]['intWMaxDivs'];
echo $arr[$i]['maxNumOfDiv'];
}
$div = [];
$maxDivKey = false;
$maxDiv = 0;
for($i = 1; $i <= 10000; $i++) {
for ($j = 1; $j < $i; $j++){
if ($i % $j == 0){
$div[$i][] = $i.'/'.$j.'='.$i/$j;
}
if($j == $i-1){
$count = count($div[$i]);
$div[$i]['count'] = $count;
if($maxDiv < $count){
$maxDiv = $count;
$maxDivKey = $i;
}
}
}
}
echo '<h1>Max divisors:</h1>';
print_r($div[$maxDivKey]);
//print_r($div);
I may be misunderstanding this question a little. If you are looking for a single number with maximum number of dividers, it should be something like this.
<?php
$max_num=10000;
$start_num=1;
$max_divs=-1;
$max_number=-1;
$numbers=array();
$max_divs_arr=array();
for($i=$start_num;$i<=$max_num;$i++)
{
$divs=0;
$div_array=array();
for($j=$start_num;$j<=$i;$j++)
{
if($i%$j==0)
{
$divs++;
$div_array[]=$j;
}
}
if($divs==$max_divs)
$max_divs_arr[$i]=$div_array;
if($divs>$max_divs)
{
$max_divs_arr=array();
$max_divs=$divs;
$max_divs_arr[$i]=$div_array;
}
}
foreach($max_divs_arr as $number=>$divisors)
echo "\nNumber with most divisors is $number\nIt has $max_divs divisors\nThose divisors are:".implode(',',$divisors);
I build a webpage to crack simple MD5 hash of a four digit pin for fun. The method I used was basically try all combination and check against the MD5 value the user has entered. Below is the PHP code I created to accomplish the goal.
Debug Output:
<?php
$answer = "PIN not found";
if (isset($_GET['md5'])) {
$txt = 'abcdefjhig';
$time_pre = microtime(TRUE);
$value = $_GET['md5'];
$show = 15;
for ($i = 0; $i <= 9; $i++) {
$first = $i;
for ($j = 0; $j <= 9; $j++) {
$second = $j;
for ($k = 0; $k <= 9; $k++) {
$third = $k;
for ($x = 0; $x <= 9; $x++) {
$fourth = $x;
$whole = $first . $second . $third . $fourth;
$check = hash('md5', $whole);
if ($check == $value) {
$answer = $whole;
echo "The pin is $answer";
}
if ($show > 0) {
print"$check $whole \n";
$show = $show - 1;
}
}
}
}
}
echo "\n";
$time_post = microtime(TRUE);
print "Elapsed time:";
print $time_post - $time_pre;
}
?>
Notice that in the middle there are four very similar for loops,I tried to simplify this by using functions, but it just returns one four digit number which is 9999 instead of all of them.
Below is the function I created:
function construct($input){
for($i=0; $i<=9, $i++){
$input=$i;
}
return $input
}
Then I tried to call this function for four times to form all of the four digit numbers but it just gives me 9999. Can anybody help? Thanks a lot.
Try this:
for ($i=0; $i<=9999 ; $i++) {
$whole = sprintf('%04d', $i);
$check=hash('md5', $whole);
if($check==$value){
$answer=$whole;
echo "The pin is $answer";
break; //remove this if you do not want to break the loop here
}
if ($show>0) {
print"$check $whole \n";
$show=$show-1;
}
}
You're using numbers from 0 to 9999, so why just loop through those numbers? You can add zero's by using str_pad() like so:
for ($i = 0; $i <= 9999; $i++) {
$whole = str_pad($i, 4, '0', STR_PAD_LEFT);
}
Also I'd like to mention that you really should think about better formatting of your code, especially indentation
$big_box = array(1,2,3,16,17,18,31,32,33,46,47,48,61,62,63,76,77,78,91,92,93,106,107,108,121,122,123,136,137,138............);
$small_box = array(4,19,34,49,64.............);
I want to generate dynamic numbers array like above example upto 10000.
For Array $big_box Try to something like this.
$j = 0;
for ($i=0; $i <= 1000; $i++) {
if ($i!=0) {
$big_box[] = $i;
$j++;
}
if ($j == 3) {
$j = 1;
$big_box[] = $i+13;
$i =$i+13;
}
}
echo "<pre>";
print_r($big_box);
And array $small_box
$small_box = array();
for($i=0; $i <= 1000; $i++) {
if ($i == 0) {
$small_box[$i] = 4;
}else{
$small_box[$i] = $small_box[$i-1]+15;
}
}
echo "<pre>";
print_r($small_box);
I wanted to have a way to get all combinations for all given numbers with given array length.
In my project the array size usually is 7. So I write a test code like this to see if I can get all needed combinations. The important part is every result array must be unique and maximum array size must be 7.
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7];
$arraysize = 7;
$subset = [];
$count = count($numbers);
for ($i = 0; $i < $count; $i++) {
$subset[] = $numbers[$i];
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
$subset[] = $numbers[$i] . $numbers[$j];
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k];
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l];
}
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
for ($m=$l; $m < $count; $m++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l] . $numbers[$m];
}
}
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
for ($m=$l; $m < $count; $m++) {
for ($n=$m; $n < $count; $n++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l] . $numbers[$m] . $numbers[$n];
}
}
}
}
}
}
for ($i=0; $i < $count; $i++) {
for ($j=$i; $j < $count; $j++) {
for ($k=$j; $k < $count; $k++) {
for ($l=$k; $l < $count; $l++) {
for ($m=$l; $m < $count; $m++) {
for ($n=$m; $n < $count; $n++) {
for ($o=$n; $o < $count; $o++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l] . $numbers[$m] . $numbers[$n] . $numbers[$o];
}
}
}
}
}
}
}
echo "<pre>";
print_r($subset);
echo "</pre>";
?>
When I run this code I get the combinations like I wanted (I make the combinations as string to see the results clearly but normally every result item in $subset array must be array)
With this code I can get all unique combinations.
But as you can see this code is ugly. I tried to make this a recursive function but I failed. Could anyone point me to right direction to get the exact same results like this? (every item in $subset array normally must be an array that contains digits)
You can simplify this logic (and make the code less ugly) without needing to go recursive by using:
for ($i = 0; $i < $count; $i++) {
$subset[] = $numbers[$i];
for ($j=$i; $j < $count; $j++) {
$subset[] = $numbers[$i] . $numbers[$j];
for ($k=$j; $k < $count; $k++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k];
for ($l=$k; $l < $count; $l++) {
$subset[] = $numbers[$i] . $numbers[$j] . $numbers[$k] . $numbers[$l];
}
}
}
}
the following will work in all cases even if you have duplicate numbers in your array
$array = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14);
sort($array); //in case it 's not sorted
$array = array_slice($array,-7);
$num = count($array );
$total = pow(2, $num);
$result= array();
$element='';
for ($i = 0; $i < $total; $i++)
{
for ($j = 0; $j < $num; $j++)
{
if (pow(2, $j) & $i)
{
$element=$element.$array [$j];
}
}
$result[]=$element;
$element='';
}
print_r($result);
This implementation returns all the combinations of all items (77 = 823542 combinations of 7 items):
function combine_all(array $numbers) {
$count = count($numbers);
$result = array_map('strval', $numbers);
for($i = 1; $i < $count; ++$i) {
$combinations = array_slice($result, pow($count, $i-1));
foreach($numbers as $number) {
foreach($combinations as $combination) {
$result[] = $number . ',' . $combination;
}
}
}
return $result;
}
When using print_r to output the data, it can perform very slowly:
$array = array_fill(0, pow(7,7), '');
$t = microtime(true);
echo '<pre>';
print_r($array);
echo '</pre>';
echo microtime(true) - $t;
// 0.75329303741455
$t = microtime(true);
echo '<pre>';
print_r( combine_all(array(1,2,3,4,5,6,7)) );
echo '</pre>';
echo microtime(true) - $t;
// 1.7037351131439
$t = microtime(true);
combine_all(array(1,2,3,4,5,6,7));
echo microtime(true) - $t;
//0.75869607925415
To restrict the items number, use the array_slice function:
combine_all(array_slice($numbers, 0, 7));
If you really want a recursive function, you could do something like this:
function combine_all(array $numbers, $cnt=null, $baseCombination=null) {
if( $baseCombination === null ) {
$cnt = count($numbers);
}
if( $cnt > 0 ) {
$result = array();
foreach($numbers as $number) {
$combination = $number . ',' . $baseCombination;
$result[] = $combination;
$result = array_merge($result, combine_all($numbers, $cnt-1, $combination));
}
return $result;
}
return array();
}
But it takes too much memory.
I finally found out a way to add recursive function to create unique combinations from given numbers:
$numbers = [1, 2, 3, 4, 5, 6, 7];
function subsetSumRecursive($numbers, $arraySize, $level = 1, $i = 0, $addThis = [])
{
// If this is the last layer, use a different method to pass the number.
if ($level == $arraySize) {
$result = [];
for (; $i < count($numbers); $i++) {
$result[] = array_merge($addThis, array($numbers[$i]));
}
return $result;
}
$result = [];
$nextLevel = $level + 1;
for (; $i < count($numbers); $i++) {
// Add the data given from upper level to current iterated number and pass
// the new data to a deeper level.
$newAdd = array_merge($addThis, array($numbers[$i]));
$temp = subsetSumRecursive($numbers, $arraySize, $nextLevel, $i, $newAdd);
$result = array_merge($result, $temp);
}
return $result;
}
echo "<pre>";
print_r(subsetSumRecursive($numbers, 7));
echo "</pre>";
How would I group 5 numbers in an array into each line? I've tried this code below but it results in something I'm not expecting it to be.
$arrayCount = count($result_data);
for ($x = 0; $x < $arrayCount; $x++)
{
for ($i=0; $i<5; $i++)
{
echo ($result_data[$i]);
}
echo ("\n");
}
Result:
239298246244268
239298246244268
239298246244268
239298246244268
This loop keep repeating the first 5 numbers in my array. How do I make it to loop for every 5 numbers instead in my whole array of numbers? Thank you!
$x should be your index for the echo. Try this instead:
<?php
$result_data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
for ($x = 0; $x < count($result_data); $x++)
{
echo ($result_data[$x]);
if(($x+1)%5==0)
{
echo ("\n");
}
}
use this $result_data[$x]
try this
$arrayCount = count($result_data);
for ($x = 0; $x < $arrayCount; $x++)
{
if($x%5==0)
{
echo ("\n");
}
echo ($result_data[$x]);
}
Don't know much about your $result_data Array, but probably it should go like this:
$arrayCount = count($result_data);
for ($x = 0; $x < $arrayCount; $x++)
{
for ($i=0; $i<5; $i++)
{
echo ($result_data[$x][$i]);
}
echo ("\n");
}
I think you want to do something like this
$i = 0;
foreach($result_data as $result) {
echo $result;
if($i < 5) {
echo ",";
} else {
echo "<br/>\n";
$i = 0;
}
$i++;
}
Something like this?
$chunks = array_chunk($result_data, 5);
foreach($chunks as $chunk) {
echo implode('', $chunk);
echo "\n";
}
See http://uk3.php.net/manual/en/function.array-chunk.php
Try this several line code:
$valuesDelimiter = ', ';
$lineDelimiter = "\n";
$input_array = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
$slited_array = array_chunk($input_array, 5);
array_walk($slited_array, function(&$arr) {$arr = implode($valuesDelimiter, $arr);});
$result = implode($lineDelimiter, $slited_array);