How to check matching array values in php? - php

Hi i have a repeating dates in array values i wan to count the number of repeating dates from the array value. I tried this but am not sure to do it correctly and am getting error Undefined offset: 0
<?php $array = array('2013-11-28','2013-11-28','2013-11-28','2013-11-29','2013-11-29','2013-11-30');
$len = sizeof($array);
$len = $len-1;
$day = array();
for($i=0; $i<=$len; $i++)
{
for($j=0; $j<=$len; $j++)
{
if($array[$i] == $array[$j])
{
if($day[0] == '')
{
$co = 1;
$day[] = $co;
}
else {
$day[$i] = $co++;
}
}
}
echo 'day'.$i.' '.$day[$i].' ';
}
?>
From the date values i should get 3 for 2013-11-28, 2 for 2013-11-29 and 1 for 2013-11-30 as you can see 2013-11-28 is presented 3 times , 2013-11-29 is presented 2 times and
2013-11-30 is presented one time.
I can understand that i am wrongly calculating because in the second loop i am again starting from first index so increasing the count.
I want to know the count of same dates. How to do this. Any other way to count this? Any help please?

Use array_count_values().
$dupesCount = array_count_values($array);
This will give you an array where the value is the key and the new value is the repetition count.

Related

Sorting and getting higest values codeigniter

I have a cloumn like token_number in table the values inserted in this row are like
token_number
1
2
3
15
4
5
6
14
7
8
18
10
11
9
etc..
I sort these values
1,2,3,4,5,6,7,8,9,10,11,14,15,18
I want to get the value 11 from this sorted array
ie the highest number with common difference 1
How to get 11 from this array?
Since the array is sorted, you can start from the bottom e loop it backwards:
$arr = // sorted array;
$max = null;
for( $i = count($arr) - 1 ; $i > 0 ; $i++ ){
if($arr[$i] - 1 == $arr[$i-1]){
$max = $arr[$i-1];
break;
}
}
if($max !== null){
echo "founded: " . $max;
}
You can find highest number with command difference as follow.
$arr= array(1,2,3,4,5,6,7,8,9,10,11,14,15,18);
$highestNo = null;
for($i=0 ;$i <= count($arr) - 1 ; $i++ ){
$diff = $arr[$i+1] - $arr[$i]; //check difference of current and next number
if($diff != 1){
$highestNo = $arr[$i];
break;
}
}
echo "Highest number with comman difference is: " . $highestNo;

Optimisation of O(n4) complexity to O(n) in PHP nested for loop

I am writing one logic to iterate numbers first and then additional logic to putting them into particular subset of array.
What does this code do :
Code accept first $n
its create array of $n number from 1 to $n
Then started converting to subset of $main_array to possible one like
['1'] [1,2] [1,2,3] [2] [2,3] [3] etc. same like this
After creating subset i am counting those some subset which satisfy condition
Condition is xyz[0] should not come in subset with abc[0] vice versa xyz[i] should not come in subset abc[i]. Example 2 and 3 is coming subset then dont count that subset, same 1 and 4 is coming then dont count
here is my nested for loop :
$n = 1299;
$main_array = range(1,$n);
$counter = 0;
$count = sizeof($abc); // $abc and $xyz size will same always.
$abc = [2,1];
$xyz = [3,4];
for ($i=0; $i <$n; $i++) {
for($j = $i;$j < $n; $j++){
$interval_array = array();
for ($k = $i; $k <= $j; $k++){
array_push($interval_array,$main_array[$k]);
}
$counter++;
for ($l=0; $l < $count ; $l++) {
//if block here to additional condition using in_array() php function. which do $counter--
if(in_array($abc[$l], $interval_array) &&
in_array($xyz[$l], $interval_array)){
$counter--;
break;
}
}
}
}
$main_array i have to create on the spot after receiving $n values.
Following is cases :
when running $n = 4 its run in 4s
when running $n = 1200 or 1299 or more than 1000 its run in 60s-123s
Expected execution timing is 9s. I reduce from 124s to 65s by removing function calling inside for loop but its not coming to point.
Expectation of code is if i have array like
$array = [1,2,3];
then
subset need to generate :
[1],[1,2],[1,2,3],[2],[2,3],[3]
Any help in this ?
It's difficult to test performance against your experience, but this solution removes one of the loops.
The way you repeatedly build $interval_array is not needed, what this code does is to just add the new value from the main array on each $j loop. This array is then reset only in the outer loop and so it just keeps the last values and adds 1 extra value each time...
for ($i=0; $i <$n; $i++) {
$interval_array = array();
for($j = $i;$j < $n; $j++){
array_push($interval_array,$main_array[$j]);
// Check output
echo implode(",", $interval_array)."\n";
$counter++;
for ($l=0; $l < $count ; $l++) {
if(in_array($abc[$l], $interval_array) &&
in_array($xyz[$l], $interval_array)){
$counter--;
break 2;
}
}
}
}
adding "\n" to better understanding for subset flow.
import datetime
N = list(range(1, int(input("N:")) + 1))
affected_list = list(map(int, input("affected_list").split()))
poisoned_list = list(map(int, input("poisoned_list").split()))
start_time = datetime.datetime.now()
exclude_list = list(map(list, list(zip(affected_list, poisoned_list))))
final_list = []
for i in range(0, len(N)):
for j in range(i + 1, len(N) + 1):
if N[i:j] not in exclude_list:
final_list.append(N[i:j])
print(final_list)
end_time = datetime.datetime.now()
print("Total Time: ", (end_time - start_time).seconds)

Can someone help me return a value?

I have created a loop which returns a random number between two values. Cool.
But now I want the script to return the following value too: The number of unique numbers between two similar numbers.
Example:
4
5
8
22
45
3
85
44
4
55
15
23
As you see there is a double which is the four and there are 7 numbers inbetween. So I would like the script to echo these numbers two so in this case it should echo 7 but if there are more doubles in the list it should echo all the numbers between certain doubles.
This is what I have:
for ($x = 0; $x <= 100; $x++) {
$min=0;
$max=50;
echo rand($min,$max);
echo "<br>";
}
Can someone help me or guide me? I'm learning :)
Thanks!
So You need to seperate script for three parts:
getting randoms and save them to array (name it 'result'),
analyze them,
print (echo) results
Simply - instead of printing every step of loop, save them to array(), exit loop, analyze every item with other, example:
take i element of list
check is i+j element is the same
if is it the same - save j-i to second array() (name it 'ranges')
And after this, print two arrays (named by me as 'result' and 'ranges')
UPDATE:
Here's solution, hope You enjoy:
$result = array(); #variable is set as array object
$ranges = array(); #same
# 1st part - collecting random numbers
for ($x = 0; $x < 20; $x++)
{
$min=0;
$max=50;
$result[] = rand($min,$max); #here's putting random number to array
}
$result_size = count($result); #variable which is containg size of $result array
# 2nd part - getting ranges between values
for ($i = 0; $i < $result_size; $i++)
{
for ($j = 0; $j < $result_size; $j++)
{
if($i == $j) continue; # we don't want to compare numbers with itself,so miss it and continue
else if($result[$i] == $result[$j])
{
$range = $i - $j; # get range beetwen numbers
if($range > 0 ) # this is for miss double results like 14 and -14 for same comparing
{
$ranges[$result[$i]] = $range;
}
}
}
}
#3rd part - priting results
echo("RANDOM NUMBERS:<br>");
foreach($result as $number)
{
echo ("$number ");
}
echo("<br><br>RANGES BETWEEN SAME VALUES:<br>");
foreach($ranges as $number => $range)
{
echo ("For numbers: $number range is: $range<br>");
}
Here's sample of echo ($x is set as 20):
RANDOM NUMBERS:
6 40 6 29 43 32 17 44 48 21 40 2 33 47 42 3 22 26 39 46
RANGES BETWEEN SAME VALUES:
For numbers: 6 range is: 2
For numbers: 40 range is: 9
Here is your fish:
Put the rand into an array $list = array(); and $list[] = rand($min,$max); then process the array with two for loops.
$min=0;
$max=50;
$list = array();
for ($x = 0; $x <= 100; ++$x) {
$list[] = rand($min,$max);
}
print "<pre>";print_r($list);print "</pre>";
$ranges = array();
$count = count($list);
for ($i = 0; $i < $count; ++$i) {
$a = $list[$i];
for ($j = $i+1; $j < $count; ++$j) {
$b = $list[$j];
if($a == $b) {
$ranges[] = $j-$i;
}
}
}
print "<pre>";print_r($ranges);print "</pre>";

Possible combinations of binary

The problem statement is as following:
A particular kind of coding which we will refer to as "MysteryCode" is a binary system of encoding in which two successive values, differ at exactly one bit, i.e. the Hamming Distance between successive entities is 1. This kind of encoding is popularly used in Digital Communication systems for the purpose of error correction.
LetMysteryCodes(N)represent the MysteryCode list for N-bits.
MysteryCodes(1) = 0, 1 (list for 1-bitcodes,in this order)
MysteryCodes(2) = 00, 01, 11, 10 (list for 2-bitcodes,in this order)
MysteryCodes(3) =000, 001, 011, 010,110, 111, 101, 100 (list for 3-bitcodes,in this order)
There is a technique by which the list of (N+1) bitcodescan be generated from (N)-bitcodes.
Take the list of N bitcodesin the given order and call itList-N
Reverse the above list (List-N), and name the new reflected list: Reflected-List-N
Prefix each member of the original list (List-N) with 0 and call this new list 'A'
Prefix each member of the new list (Reflected-List-N) with 1 and call this new list 'B'
The list ofcodeswith N+1 bits is the concatenation of Lists A and B.
A Demonstration of the above steps: Generating the list of 3-bitMysteryCodesfrom 2-BitMysteryCodes
2-bit list ofcodes:00, 01, 11, 10
Reverse/Reflect the above list:10, 11, 01, 00
Prefix Old Entries with 0:000, 001, 011, 010
Prefix Reflected List with 1:110, 111, 101, 100
Concatenate the lists obtained in the last two steps:000, 001, 011, 010, 110, 111, 101, 100
Your Task
Your task is to display the last N "MysteryCodes" from the list of MysteryCodes for N-bits. If possible, try to identify a way in which this list can be generated in a more efficient way, than iterating through all the generation steps mentioned above.
More efficient or optimized solutions will receive higher credit.
Input Format
A single integer N.
Output Format
N lines, each of them with a binary number of N-bits. These are the last N elements in the list ofMysteryCodesfor N-bits.
Input Constraints 1 = N = 65
Sample Input 1
1
Sample Output 1
1
Explanation for Sample 1
Since N = 1, this is the (one) last element in the list ofMysteryCodesof 1-bit length.
Sample Input 2
2
Sample Output 2
11
10
Explanation for Sample 2 Since N = 2, these are the two last elements in the list ofMysteryCodesof 2-bit length.
Sample Input 3
3
Sample Output 3
111
101
100
$listN = 25;
$bits = array('0','1');
//check if input is valid or not
if(!is_int($listN))
{
echo "Input must be numeric!";
}
if($listN >= 1 && $listN <=65){
if($listN == 1){
echo '1'; exit;
}
ini_set('memory_limit', -1);
for($i=1; $i<=($listN - 1); $i++){
$reverseBits = array_reverse($bits);
$prefixBit = preg_filter('/^/', '0', $bits);
$prefixReverseBits = preg_filter('/^/', '1', $reverseBits);
$bits = array_merge($prefixBit, $prefixReverseBits);
unset($prefixBit, $prefixReverseBits, $reverseBits);
}
$finalBits = array_slice($bits, -$listN);
foreach($finalBits as $k=>$v){
echo $v."\n";
}
}
else{
echo "Invalid input!";
}
I have tried above solution, but didnt worked for input greater than 20.
for eg. If the input is 21, I got "Couldnt allocate memory" error.
It will be great if somebody figure out the optimized solutions...
The numbers follow a pattern which I transformed to below code.
Say given number is N
then create a N x N matrix and fill it's first column with 1's
and all other cells with 0's
Start from rightmost column uptil 2nd column.
For any column X start from bottom-most row and fill values like below:
Fill 2^(N - X + 1)/2 rows with 0's.
Fill 2^(N - X + 1) rows with 1's and then 0's alternatively.
Repeat step 2 till we reach topmost row.
Print the N x N matrix by joining the values in each row.
<?php
$listN = 3;
$output = [];
for ($i = 0; $i < $listN; $i++) {
$output[$i] = [];
for ($j = 0; $j < $listN; $j++) {
$output[$i][$j] = 0;
}
}
$output[$listN - 1][0] = 1;
for ($column = 1; $column < $listN; $column++) {
$zeroFlag = false;
for ($row = $listN - 1; $row >= 0;) {
$oneZero = 1;
if (!$zeroFlag) {
for ($k = 1; $k <= pow(2, $column) / 2 && $row >= 0; $k++) {
$output[$row][$listN - $column] = 0;
$row--;
$zeroFlag = true;
}
}
for ($k = 1; $k <= pow(2, $column) && $row >= 0; $k++) {
$output[$row][$listN - $column] = $oneZero;
$row--;
}
$oneZero = 0;
for ($k = 1; $k <= pow(2, $column) && $row >= 0; $k++) {
$output[$row][$listN - $column] = $oneZero;
$row--;
}
}
}
for ($i = 0; $i < $listN; $i++) {
$output[$i][0] = 1;
}
for ($i = 0; $i < $listN; $i++) {
print(join('', $output[$i]));
print("\n");
}

How can I sum groups of X elements together?

I need to get a valid timestamp from the following array:
$arrkeys = array(
"t" => [
1442238840,60,120,180,240,300,360,420,480,540,600,660,720,780,840,900,960,
1442239860,60,120,180,240,300,360,420,480,540,600,660,720,780,840,900,960,
1442240880,60,120,180,240,300,360,420,480,540,600,660,720,780,840,900,960
]
);
I need to sum the first valid timestamp 1442238840 with the following 17 numbers together, to get a correct timestamp, and then, the second timestamp 1442239860, etc...
Example:
1442238840 + 60;
1442238840 + 120;
1442238840 + 180;
etc...
I can't figure out how I could do this,
some things I've tried:
Attempt No. 1
//Pseudo-code
foreach($arrkeys["t"] as $t){
if(strlen($t) < 10){
//Search for the first valid timestamp and sum?
}
}
Attempt No. 2
//Not working.
$array_size = 17;
/* I know that every 17 (counting from 0) have a valid timestamp.
so that 0 = 1st valid timestamp, 20 = 2nd valid timestamp. */
for ($i = 0; $i < $array_size; $i++) {
do {
echo $i;
} while ($i > 0);
I don't know if I'm going the right way to solve this, I don't know how to do this efficiently, or at least do it.
Any suggestions?
I love that you tried different things. That's good!
You tried to solve the problem yourself and array_chunk() will help you a lot here, since you can chunk your array into groups of 17 elements and then use array_sum() to sum each group of 17 elements together, e.g.
$result = array_chunk($arrkeys["t"], 17);
$result = array_map("array_sum", $result);

Categories