Print triangular number patterns with loops and modulus calculation - php

I need to print a number pattern like this:
1
12
123
1234
2
23
234
2341
3
34
341
3412
4
41
412
4123
My code:
for($i=1; $i<=4; ++$i) {
for($j=1; $j<=$i; ++$j) {
echo $j;
}
echo ("<br/>");
}
for($i=2; $i<=4; ++$i) {
for($j=2; $j<=$i; ++$j) {
echo $j;
}
echo ("<br/>");
}
I don't know how to recycle to the first number after the max number is reached. Since my max number is 4, 1 should used instead of 5 (and 2 for 6 and 3 for 7).

You loop from 1 to 4, and subtract 4 if the value is bigger than 4.
This is for 2, 23, 234, 2341:
for ($i = 1; $i <= 4; $i++) {
for ($j = 1; $j <= $i; $j++) {
$value = $j + 1; // or +2, or +3
echo $value > 4 ? $value - 4 : $value;
}
echo "\n";
}
And this would generate all output within one big loop:
$max = 4;
for ($start = 0; $start < $max; $start++) {
for ($i = 1; $i <= $max; $i++) {
for ($j = 1; $j <= $i; $j++) {
$value = $j + $start;
echo $value > $max ? $value - $max : $value;
}
echo "\n";
}
}

Whenever you need circular array access, it is a good idea to implement a modulus calculation. To set this up, use a range between 0 and 3 instead of using 1 and 4. A modulus calculation can return a 0 result, so the formula must be prepared to handle this value. To adjust the value, just add 1 after the modulus calculation to generate numbers between 1 and 4.
Accumulate strings of numbers as desired and reset the string upon each start of the outer loop.
Below proves that you do not need three nested loops for this task.
Code: (Demo)
for ($i = 0; $i < 4; ++$i) {
for ($s = '', $j = 0; $j < 4; ++$j) {
$s .= ($i + $j) % 4 + 1;
echo $s . "\n";
}
}
Output:
1
12
123
1234
2
23
234
2341
3
34
341
3412
4
41
412
4123

Related

PHP: for loop $i value turns zero if the number is greater

I want to turn the $i variable value to start counting from 1 if the given value is greater than 10:
here is what i am trying to achieve
<?php
$givenValue = 15; //number of x value
for ($i = 1; $i < $givenValue; $i++) {
if ($givenValue > 10){
$i = 1;
}
echo $i."<br>";
}
?>
This is how i want my result to look like
output: 1
output: 2
output: 3
output: 4
output: 5
output: 6
output: 7
output: 8
output: 9
output: 10
output: 1
output: 2
output: 3
output: 4
output: 5
in for loop body
Any help is welcome
You can use modulo calculation to get the result you want.
I also changed your if from $givenvalue to $i as $givenvalue will "always" be 10+.
$givenValue = 15; //number of x value
for ($i = 1; $i <= $givenValue; $i++) {
if ($i > 10){
Echo $i%10 . "\n";
}else{
echo $i . "\n";
}
}
https://3v4l.org/5afc5
Another option, if that is possible for you, is to start at zero and only use modulo calculation and add one to it to get the same result.
This also means I need to stop the loop at <$givenvalue as your original code shows.
$givenValue = 15; //number of x value
for ($i = 0; $i < $givenValue; $i++) {
Echo $i%10+1 . "\n";
}
https://3v4l.org/r0sgA
A method that uses less looping is to add 10 to the loop on each iteration and create the values using range().
Then add them to the array with array_merge, and output with implode.
$givenValue = 47; //number of x value
$breakpoint = 10;
$arr=[];
For($i = $breakpoint; $i< $givenValue;){
// Add new values from 1-$breakpoint in array
$arr = array_merge($arr, range(1,$breakpoint));
$i +=$breakpoint;
}
// Loop will exit before all values been collected
// Add the rest of the values
$arr = array_merge($arr, range(1,$givenValue-($i-10)));
// Echo the values in array
Echo implode("\n", $arr);
https://3v4l.org/jGsO4
Your code can be written like this:
<?php
$givenValue = 15; //number of x value
for ($i = 1; $i <= $givenValue; $i++)
{
if ($i > 10)
{
$i = 1;
$givenValue-=10;
}
echo "output: $i\n";
}
?>
http://sandbox.onlinephpfunctions.com/code/ed34d8dcd12a9a5a866b73338ad1209f55298519
You are resenting the counter, I would expect the behaviour you have. To do what you want add another counter to the mix
$j=1;
$givenValue = 15; //number of x value
for ($i = 1; $i <= $givenValue; $i++) {
if ($j > 10){
$j = 1;
}
echo $j."\n";
++$j;
}
You also had several missing ;
Output:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
If you want to end on 5 you have to do 16 as the $givenValue or change it to <= less than or equal
See it here live
See what I have now, the $i variable counts to the $givenValue then the $j variable counts along side it, but with a range of 1-10 ( resets to 1 after 10 )

How to make this Number Pyramid Pattern

is it possible if I want an output like this?
5 4 3 2 1
4 3 2
3
with PHP, this is the code that I've been Try.
$n = 3;
for ($i = 3; $i > 0; $i--) {
for ($j = $n - $i; $j > 0; $j--)
echo "  ";
for ($j = 2 * $i - 1; $j > 0 ; $j--)
echo " ".$j;
echo "<br>";
}
and I got this , from that code
5 4 3 2 1
3 2 1
1
Wich part of my code that I do get wrong? can someone help me?
EDIT: Thanks people. most of the stackoverflow question that similar to my question is like my result that I have. the task was not that. 54321 432 3
most of them we're like 54321 4321 321 21 1. I'm sorry , I'm newbie. don't know that much as you people. once again , Thanks Alot!
You need to fix your last for loop's initial value and condition to match your criteria:
$n = 3;
for ($i = 3; $i > 0; $i--) {
for ($j = $n - $i; $j > 0; $j--)
echo " ";
for ($j = $n + $i - 1; $j > $n - $i ; $j--)
echo " ".$j;
echo "<br>";
}

How to produce the following sequence of numbers through a php for statement

I need to find out a way to output the following number sequence through a double php for statement:
0 - 1 <-- begin
0 - 2
0 - 3
0 - 4
1 - 1
1 - 2
1 - 3
1 - 4
2 - 2
2 - 3
2 - 4
3 - 3
3 - 4 <-- end
How can I make the second loop, lose its first number, after each loop so the sequence looks like the output above?
I've been trying things like:
for($z = 0; $z <= 3; $z++) {
for($y = 0; $y <= 3; $y++) {
echo $z . " - " . $y . "<br />";
}
}
But the second loop keeps starting with a number 1. But I can't even think of a way to do it at all.
for ($x = 0; $x <= 3; $x++) {
for ($y = 1; $y <= 4; $y++) {
if ($y >= $x) {
echo "$x - $y\n";
}
}
}
Use a nested loop and let the nested one start at the iteration of the outer one:
for ($i = 0; $i < $max; $i++)
for ($j = $i; $j < $max; $j++)
echo "$i - $j";

How to prepend a decremented number to a string in a loop?

I am trying to make a triangular-shaped set of lines of decreasing numbers like this :
5
45
345
2345
12345
I tried this :
for($i=1;$i<=5;$i++)
{
for($j=1;$j<=$i;$j++)
{
echo $j;
}
echo "<br>";
}
But it is printing the low number first and appending increasing numbers like this :
1
12
123
1234
12345
The inner loop needs to count down instead of up.
You can either subtract the outer loop's variable from the limit to get the starting point and count down:
for ($i = 0; $i < 5; $i++)
{
for ($j = 5 - $i; $j > 0; $j--)
{
echo $j;
}
echo "<br>";
}
or change the outer loop to count down from the limit as well.
for ($i = 5; $i >= 1; $i--)
{
for ($j = $i; $j >= 1; $j--)
{
echo $j;
}
echo "<br>";
}
This is pretty straightforward:
$max = 5;
echo "<pre>";
for($line=0; $line<$max; $line++) {
$min_this_line = $max-$line;
for($num = $min_this_line; $num <= $max; $num++) {
echo $num;
}
echo "\n";
}
echo "</pre>";
Output:
5
45
345
2345
12345
I think I would declare the $peak value, then use a for() loop to decrement the counter down to 1, and use implode() and range() to build the respective strings inside the loop.
This isn't going to outperform two for() loops, but for relatively small $peak values, no one is going to notice any performance hit.
Code: (Demo)
$peak = 5;
for ($i = $peak; $i; --$i) {
echo implode(range($i, $peak)) , "\n";
}
or with two loops: (Demo)
Decrement the outer loop and increment the inner loop.
$peak = 5;
for ($i = $peak; $i; --$i) {
for ($n = $i; $n <= $peak; ++$n) {
echo $n;
}
echo "\n";
}
Both output:
5
45
345
2345
12345

how to find the sum of all the multiples of 3 or 5 below 1000 in php, issue?

i have an small issue with the way this problem is resolved.
some would say: println((0 /: ((0 until 1000).filter(x => x % 3 == 0 || x % 5 == 0))) (_+_)) is the solution witch adds to 233168
my way was to do:
$maxnumber = 1000;
for ($i = 3; $i < $maxnumber; $i += 3)
{
$t += $i;
echo $i.',';
}
echo '<br>';
for ($j = 5; $j < $maxnumber; $j += 5)
{
$d += $j;
echo $j.',';
}
echo '<br>';
echo $t;
echo '<br>';
echo $d;
echo '<br>';
echo $t+$d;
this will give me :
3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,303,306,309,312,315,318,321,324,327,330,333,336,339,342,345,348,351,354,357,360,363,366,369,372,375,378,381,384,387,390,393,396,399,402,405,408,411,414,417,420,423,426,429,432,435,438,441,444,447,450,453,456,459,462,465,468,471,474,477,480,483,486,489,492,495,498,501,504,507,510,513,516,519,522,525,528,531,534,537,540,543,546,549,552,555,558,561,564,567,570,573,576,579,582,585,588,591,594,597,600,603,606,609,612,615,618,621,624,627,630,633,636,639,642,645,648,651,654,657,660,663,666,669,672,675,678,681,684,687,690,693,696,699,702,705,708,711,714,717,720,723,726,729,732,735,738,741,744,747,750,753,756,759,762,765,768,771,774,777,780,783,786,789,792,795,798,801,804,807,810,813,816,819,822,825,828,831,834,837,840,843,846,849,852,855,858,861,864,867,870,873,876,879,882,885,888,891,894,897,900,903,906,909,912,915,918,921,924,927,930,933,936,939,942,945,948,951,954,957,960,963,966,969,972,975,978,981,984,987,990,993,996,999
5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275,280,285,290,295,300,305,310,315,320,325,330,335,340,345,350,355,360,365,370,375,380,385,390,395,400,405,410,415,420,425,430,435,440,445,450,455,460,465,470,475,480,485,490,495,500,505,510,515,520,525,530,535,540,545,550,555,560,565,570,575,580,585,590,595,600,605,610,615,620,625,630,635,640,645,650,655,660,665,670,675,680,685,690,695,700,705,710,715,720,725,730,735,740,745,750,755,760,765,770,775,780,785,790,795,800,805,810,815,820,825,830,835,840,845,850,855,860,865,870,875,880,885,890,895,900,905,910,915,920,925,930,935,940,945,950,955,960,965,970,975,980,985,990,995
$t - 166833
$d - 99500
and total:
266333
why am i wrong?
Some numbers are multiples of both 3 and 5. (Your algorithm adds these numbers to the total twice.)
Because 6 * 5 == 30 and 10 * 3 == 30, you're adding the some numbers up twice.
$sum = 0;
$i = 0;
foreach(range(0, 999) as $i) {
if($i % 3 == 0 || $i % 5 == 0) $sum += $i;
}
Because you double-count numbers that are multiple of both 3 and 5, i.e. multiples of 15.
You can account for this naively by subtracting all multiples of 15.
for ($j = 15; $j < $maxnumber; $j += 15)
{
$e += $j;
echo $j.',';
}
$total = $total - $d;
In your case, if it is 15, you will add the number twice.
Try this:
$t = 0;
$d = 0;
for ($i = 0; $i <= $maxnumber; $i++){
if ($i % 3 == 0)
$t+= $i;
else if ($i % 5 == 0)
$d += $i;
}
echo $t.'<br>'.$d;
I think that in your code, if a number is a multiple of 3 and 5, it is added twice. Take 15 for example. It's in your list of multiples of 3 and in the list of multiples of 5. Is this the behaviour you want?
One of the best approach to this solution (to achieve optimum time complexity), run an Arithmetic Progression series and find the number of terms in all series by using AP formula: T=a+(n-1)d, then find sum by : S=n/2[2*a+(n-1)d]
where : a=first term ,n=no. of term , d=common deference, T=nth term
The code solution below has been implemented to suit the question above - so the values 3 and 5 are hard-coded. However, the function can modified such that values are passed in as variable parameters.
function solution($number){
$val1 = 3;
$val2 = 5;
$common_term = $val1 * $val2;
$sum_of_terms1 = calculateSumofMulitples($val1,$number);
$sum_of_terms2 = calculateSumofMulitples($val2,$number);
$sum_of_cterms = calculateSumofMulitples($common_term,$number);
$final_result = $sum_of_terms1 + $sum_of_terms2 - $sum_of_cterms;
return $final_result;
}
function calculateSumofMulitples($val, $number)
{
//first, we begin by running an aithmetic prograssion for $val up to $number say N to get the no of terms [using T=a +(n-1)d]
$no_of_terms = (int) ($number / $val);
if($number % $val == 0) $no_of_terms = (int) ( ($number-1)/$val ); //since we are computing for a no of terms below N and not up to/exactly/up to N. if N divides val with no remainder, use no of terms = (N-1)/val
//second, we compute the sum of terms [using Sn = n/2[2a + (n-1)d]
$sum_of_terms = ($no_of_terms * 0.5) * ( (2*$val) + ($no_of_terms - 1) * $val );
// sum of multiples
return $sum_of_terms;
}
You can run a single loop checking whether the number is multiple of 3 OR 5:
for ($i = 0; $i < $maxnumber; $i++)
{
if($i%3 || $i%5){
$t += $i;
echo $i.',';}
}
I think the original code is not including numbers which are multiples of both 3 and 5 in the total: if the test for multiple of 3 matches, it takes that and goes on.
If you total the multiples of 15 up to 1000, you get 33165, which is exactly the difference between your total, 266333, and the original total, 233168.
Here's my solution to the question:
<?php
$sum = 0;
$arr = [];
for($i = 1; $i < 1000; $i++){
if((int)$i % 3 === 0 || (int)$i % 5 === 0)
{
$sum += $i;
array_push($arr,$i);
}
}
echo $sum;
echo '<br>';
print_r($arr);//Displays the values meeting the criteria as an array of values

Categories