Jump to content

NUMBER FREQUENCY


Jayfromsandiego

Recommended Posts

Please see the attached file for what I am trying to accomplish. This PHP code is what I have so far ..

 

<?php
// display count to values

$arr = array('9','2','3','2','1','5');

$result = array_count_values($arr);

echo "DIGIT FREQUENCY RESULTS ..<br><br>
      0s: $result[0]<br>
      1s: $result[1]<br>
      2s: $result[2]<br>
      3s: $result[3]<br>
      4s: $result[4]<br>
      5s: $result[5]<br>
      6s: $result[6]<br>
      7s: $result[7]<br>
      8s: $result[8]<br>
      9s: $result[9]";

?>
<html>
<body>

<div>&nbsp;</div>
  <div>
* Need to find out how to count 3-digit number strings inside an array. It currently counts single digits only.
</div>

</body>
</html>

 

frequencyapp.png

Link to comment
Share on other sites

I'd store the input as arrays of 3 digits instead of 3-digit numbers.

$input = [];
for ($i=0; $i<5; $i++) {
    $input[] = str_split(sprintf('%03d',mt_rand(1,999)), 1); 
}

Giving...

$input Array
(
    [0] => Array
        (
            [0] => 8
            [1] => 5
            [2] => 2
        )

    [1] => Array
        (
            [0] => 3
            [1] => 6
            [2] => 3
        )

    [2] => Array
        (
            [0] => 4
            [1] => 1
            [2] => 1
        )

    [3] => Array
        (
            [0] => 1
            [1] => 5
            [2] => 6
        )

    [4] => Array
        (
            [0] => 7
            [1] => 8
            [2] => 2
        )

)

Then, if you want, you can get the individual positions for counting by using array_column()

$p1 = array_column($input, 0);
$p2 = array_column($input, 1);
$p3 = array_column($input, 2);

E.G...

$p1 Array
(
    [0] => 8
    [1] => 3
    [2] => 4
    [3] => 1
    [4] => 7
)

 

Edited by Barand
Link to comment
Share on other sites

Regarding your current code

It is going to throw warning notices when the dgits do not appear in the array eg

Notice: Undefined offset: 0 
Notice: Undefined offset: 4 
Notice: Undefined offset: 6 
Notice: Undefined offset: 7 
Notice: Undefined offset: 8

It is repetetive. The advantage of arrays is they can be used in loops, so your code can be replaced by

$arr = array('9','2','3','2','1','5');

$result = array_count_values($arr);

echo "DIGIT FREQUENCY RESULTS ..<br><br>";
for ($d=0; $d<10; $d++) {
    echo "{$d}s : " . ($result[$d] ?? 0) . '<br>';
}

 

Link to comment
Share on other sites

Hi Barand.

So like this .. but how do I get 3-digit numbers inside the array to work

<?php
// display count to values

$input = [];
for ($i=0; $i<5; $i++) {
    $input[] = str_split(sprintf('%03d',mt_rand(1,999)), 1);
}

$p1 = array_column($input, 0);
$p2 = array_column($input, 1);
$p3 = array_column($input, 2);

$arr = array(912,296,325,249,125,530);

$result = array_count_values($arr);

echo "DIGIT FREQUENCY RESULTS ..<br><br>";
for ($d=0; $d<10; $d++) {
    echo "{$d}s : " . ($result[$d] ?? 0) . '<br>';
}

?>
<html>
<body>

<div>&nbsp;</div>
  <div>
* Need to find out how to count 3-digit number strings inside an array. It currently counts single digits only.
</div>

</body>
</html>

 

Edited by Jayfromsandiego
Link to comment
Share on other sites

Like this...

//
//  Get the input string of comma-separated numbers
//  explode into an array and trim off any spaces
//    
    $input_str = "572, 545, 884, 123, 802, 337, 879, 307, 759, 227, 211, 002, 968, 532, 459, 895, 681, 967, 580, 399, 664, 077, 307, 227, 461, 594, 645, 859, 484, 827, 618, 675, 302, 246, 007, 842, 471, 006, 161, 171";
    $input_arr = array_map('trim', explode(',', $input_str));
//    
//  now split each number into a 3-element array
//  and store in $input
//
    foreach ($input_arr as $n) {
        $input[] = str_split($n, 1);
    }

Now you have a processable array. You now need an array ($freqs)  which contains, for each digit 0-9, an array the counts of that digits in P1, P2 and P3...

//
//  get the counts in each position
//
    $freqs =  array_fill_keys(range(0,9), [0,0,0]);

    for ($pos=0; $pos<3; $pos++) {
        $digits = array_column($input, $pos);
        $occurs = array_count_values($digits);
        foreach ($occurs as $n => $tot) {
            $freqs[$n][$pos] += $tot;
        }
    }

You now have all the data that you want to output in your table in the $freqs array.

From that input data you should be able to end up with something like this...

image.png.ee3aad500134f34a4ae94971645262fa.png

Link to comment
Share on other sites

That looks nice.

I was only able to get the Input. I'm trying,

<?php

//  Get the input string of comma-separated numbers
//  explode into an array and trim off any spaces

    $input_str = "572, 545, 884, 123, 802, 337, 879, 307, 759, 227, 211, 002, 968, 532, 459, 895, 681, 967, 580, 399, 664, 077, 307, 227, 461, 594, 645, 859, 484, 827, 618, 675, 302, 246, 007, 842, 471, 006, 161, 171";
    $input_arr = array_map('trim', explode(',', $input_str));

//  now split each number into a 3-element array
//  and store in $input

    foreach ($input_arr as $n) {
        $input[] = str_split($n, 1);
    }

//  get the counts in each position

    $freqs =  array_fill_keys(range(0,9), [0,0,0]);

    for ($pos=0; $pos<3; $pos++) {
        $digits = array_column($input, $pos);
        $occurs = array_count_values($digits);
        foreach ($occurs as $n => $tot) {
            $freqs[$n][$pos] += $tot;
        }
    }

?>
<html>
<head>
<title>Digit Frequency Box</title>
</head>
<body>
  <!-- INPUT Table -->
 <table border="1" width="30%">
   <tr><p><b>Input</b></p>
     <td bgcolor="#F5F5DC"><span style="font-family: verdana,arial,helvetica; font-size: 14px; font-weight: color: #000000;"><?php echo "$input_str"; ?></span></td>
   </tr>
 </table>

<!-- Digit Frequencies Table -->
 <table border="1">
   <tr><p><b>Digit Frequencies</b></p>
   <tr><td bgcolor="#00994c"><span style="font-family: verdana,arial,helvetica; font-size: 14px; font-weight: bold; color: #ffffff;">DIGIT</span></td><td bgcolor="#00994c"><span style="font-family: verdana,arial,helvetica; font-size: 14px; font-weight: bold; color: #ffffff;">P1</span></td><td bgcolor="#00994c"><span style="font-family: verdana,arial,helvetica; font-size: 14px; font-weight: bold; color: #ffffff;">P2</span></td><td bgcolor="#00994c"><span style="font-family: verdana,arial,helvetica; font-size: 14px; font-weight: bold; color: #ffffff;">P3</span></td><td bgcolor="#00994c">&nbsp;</td><td bgcolor="#00994c"><span style="font-family: verdana,arial,helvetica; font-size: 14px; font-weight: bold; color: #ffffff;">DIGIT TOTALS</span></td></tr>
   <tr><td><b>0</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>1</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>2</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>3</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>4</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>5</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>6</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>7</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>8</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
   <tr><td><b>9</b></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;=</td><td>&nbsp;</td></tr>
 </table>

<div>&nbsp;</div>

<!-- FINAL DIGIT :: DISTRIBUTION LINE Table -->
 <table border="1">
   <tr><p><b>DISTRIBUTION LINE</b></p>
     <td bgcolor="#F5F5DC">&nbsp; <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> - <b>?</b> &nbsp;</td>
   </tr>
 </table>

</body>
</html>

 but I still have no idea how to grab and insert the individual digit data and put it inside PHP echo statements so they appear on the table columns.

mycurrent_output.png

Edited by Jayfromsandiego
Link to comment
Share on other sites

The $freqs array contains the counts for P1, P2 , P3 for each digit...

$freqs = Array
(
    [0] => Array                          # digit "0"
        (
            [0] => 4                      # P1
            [1] => 7                      # P2
            [2] => 1                      # P3
        )

    [1] => Array
        (
            [0] => 3
            [1] => 2
            [2] => 6
        )

    [2] => Array
        (
            [0] => 4
            [1] => 4
            [2] => 6
        )

which, coincidentally, is the same structure as the output table. You now loop through the array and for each digit (row) loop through its array (positions columns) and build the table.

//
//  create frequncy table and calc digit totals
//
    $totals =  array_fill_keys(range(0,9), []);
    $tdata = '';
    foreach ($freqs as $n => $occs) {
        $tdata .= "<tr><td><b>$n</b></td>";
        foreach ($occs as $o) {
            $tdata .= "<td>$o</td>";
        }
        $total = array_sum($occs);
        $totals[$n] = [$n,$total];
        
        $tdata .= "<td>=</td><td><b>$total</b></td></tr>\n";
    }

My complete solution...

<?php

//
//  Get the input string of comma-separated numbers
//  explode into an array and trim off any spaces
//    
    $input_str = "572, 545, 884, 123, 802, 337, 879, 307, 759, 227, 211, 002, 968, 532, 459, 895, 681, 967, 580, 399, 664, 077, 307, 227, 461, 594, 645, 859, 484, 827, 618, 675, 302, 246, 007, 842, 471, 006, 161, 171";
    $input_arr = array_map('trim', explode(',', $input_str));
//    
//  now split each number into a 3-element array
//  and store in $input
//
    foreach ($input_arr as $n) {
        $input[] = str_split($n, 1);
    }

//
//  create output table to display the input numbers
//  in rows of 10 numbers 
//
    $inputdata = '';
    $chunks = array_chunk($input_arr, 10);
    foreach ($chunks as $nums) {
        $inputdata .= "<tr>";
        foreach ($nums as $num) {
            $inputdata .= "<td>$num</td>";
        }
        $inputdata .= "</tr>\n";
    }

//
//  get the counts in each position
//
    $freqs =  array_fill_keys(range(0,9), [0,0,0]);

    for ($pos=0; $pos<3; $pos++) {
        $digits = array_column($input, $pos);
        $occurs = array_count_values($digits);
        foreach ($occurs as $n => $tot) {
            $freqs[$n][$pos] += $tot;
        }
    }
    
//
//  create frequncy table and calc digit totals
//
    $totals =  array_fill_keys(range(0,9), []);
    $tdata = '';
    foreach ($freqs as $n => $occs) {
        $tdata .= "<tr><td><b>$n</b></td>";
        foreach ($occs as $o) {
            $tdata .= "<td>$o</td>";
        }
        $total = array_sum($occs);
        $totals[$n] = [$n,$total];
        
        $tdata .= "<td>=</td><td><b>$total</b></td><td>" . bar($total, 30) . "</td></tr>\n";
    }

//
//  put digits in frequncy order (highest to lowest)
//
    uasort ($totals, function($a, $b) {
                        $x = $b[1] <=> $a[1];
                        if ($x == 0) 
                            return $a[0] <=> $b[0];
                        return $x;
                    });
    $freqorder = '<b>' . join('</b> &ndash; <b>', array_keys($totals)) . "</b>" ;

/**
* draw bar representing number of occurences
* 
* @param int $val
* @param int $max
*/
    function bar($val, $max)
    {
        $wid = 200;
        $ht  = 15;
        $svg = "<svg width='$wid' height='$ht'>
                <rect x='0' y='0' width='$wid' height='$ht' stroke='#CCC' fill='none'/>
                ";
        $pix = $wid/$max;
        $w = $val * $pix;
        $svg .= "<rect x='0' y='0' width='$w' height='$ht' fill='#396' stroke='#CCC' />\n";
        $svg .= "</svg>\n";
        return $svg;
    }

?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-language" content="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="PhpED 18.0 (Build 18044, 64bit)">
<title>Number frequencies</title>
<meta name="creation-date" content="09/29/2019">
<style type="text/css">
    table { border-collapse: collapse; font-family: verdana, sans-serif; font-size: 10pt; }
    th    { background-color: #396; color: #FFF; padding: 8px; font-variant: small-caps;}
    td    { text-align: center; padding: 4px 8px; }
    #league, #inputs { padding: 16px; background-color: #FCF8E8; font-size: 12pt; border: 1px solid gray; display: inline-block; }
</style>
</head>
<body>
    <h3>Input</h3>
    <div id="inputs">
        <table>
            <?=$inputdata?>
        </table>
    </div>
    <h3>Digit Frequencies</h3>
    <table border="1">
        <tr><th>Digit</th><th>P1</th><th>P2</th><th>P3</th><th>&nbsp;</th><th>Digit<br>Totals</th></tr>
        <?=$tdata?>
    </table>
    <br>
    <h3>Digit Frequency League</h3>
    <div id="league">
        <?=$freqorder?>
    </div>
</body>
</html>

  • Like 1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.