Loops/Increment loop index within loop body
You are encouraged to solve this task according to the task description, using any language you may know.
Sometimes, one may need (or want) a loop which
its iterator (the index
variable) is modified within the
loop body in addition to the normal incrementation by the (do) loop structure index.
- Goal
Demonstrate the best way to accomplish this.
- Task
Write a loop which:
- starts the index (variable) at 42
- (at iteration time) increments the index by unity
- if the index is prime:
- displays the index and the prime (to the terminal)
- increments the index such that the new index is now that prime
- terminates the loop when 42 primes are shown
Extra credit: because of the primes get rather large, use commas
within the displayed primes to ease comprehension.
Show all output here.
- Note
Not all programming languages allow the modification of a loop's index. If that is the case, then use whatever method that is appropriate or idiomatic for that language. Please add a note if the loop's index isn't modifiable.
- Related tasks
- Loop over multiple arrays simultaneously
- Loops/Break
- Loops/Continue
- Loops/Do-while
- Loops/Downward for
- Loops/For
- Loops/For with a specified step
- Loops/Foreach
- Loops/Infinite
- Loops/N plus one half
- Loops/Nested
- Loops/While
360 Assembly
Assembler 360 provides 3 instructions to create loops: BCT, BXH and BXLE, the register which contains the loop index can be modified at any time. Nothing exceptional for an assembly, banning to modify the loop index begins with high level languages.
This task is a good example of the use of ED instruction to format a number.
For macro use (IF,DO,...), see Structured Macros.
<lang 360asm>* Loops/Increment loop index within loop body - 16/07/2018
LOOPILWB PROLOG
SR R6,R6 i=0 ZAP N,=P'42' n=42 DO WHILE=(C,R6,LT,IMAX) do while(i<imax) BAL R14,ISPRIME call isprime(n) IF C,R0,EQ,=F'1' THEN if n is prime then LA R6,1(R6) i=i+1 XDECO R6,XDEC edit i MVC PG+2(2),XDEC+10 output i MVC ZN,EM load edit mask ED ZN,N edit n MVC PG+7(L'ZN),ZN output n XPRNT PG,L'PG print buffer ZAP WP,N n AP WP,N +n SP WP,=P'1' +1 ZAP N,WP n=n+n-1 ENDIF , endif ZAP WP,N n AP WP,=P'1' +1 ZAP N,WP n=n+1 ENDDO , enddo EPILOG
ISPRIME EQU * isprime(n) -----------------------
CP N,=P'2' if n=2 BE RETURN1 then return(1) CP N,=P'3' if n=3 BE RETURN1 then return(1) ZAP WDP,N n DP WDP,=PL8'2' /2 CP WDP+8(8),=P'0' if mod(n,2)=0 BE RETURN0 then return(0) ZAP WDP,N n DP WDP,=PL8'3' /3 CP WDP+8(8),=P'0' if mod(n,3)=0 BE RETURN0 then return(0) ZAP J,=P'5' j=5
LWHILE ZAP WP,J j
MP WP,J *j CP WP,N while(j*j<=n) BH EWHILE ~ ZAP WDP,N n DP WDP,J /j CP WDP+8(8),=P'0' if mod(n,j)=0 BE RETURN0 then return(0) ZAP WP,J j AP WP,=P'2' +2 ZAP WDP,N n DP WDP,WP n/(j+2) CP WDP+8(8),=P'0' if mod(n,j+2)=0 BE RETURN0 then return(0) ZAP WP,J j AP WP,=P'6' +6 ZAP J,WP j=j+6 B LWHILE loopwhile
EWHILE B RETURN1 return(1) RETURN0 LA R0,0 rc=0
B RETURNX
RETURN1 LA R0,1 rc=1 RETURNX BR R14 return to caller ----------------- IMAX DC F'42' limit EM DC XL20'402020206B2020206B2020206B2020206B202120' mask N DS PL8 n J DS PL8 j PG DC CL80'i=00 : 000,000,000,000,000' buffer XDEC DS CL12 temp for XDECO WP DS PL8 temp for AP,SP,MP WDP DS PL16 temp for DP CW DS CL16 temp for UNPK ZN DS CL20
REGEQU END LOOPILWB</lang>
- Output:
i= 1 : 43 i= 2 : 89 i= 3 : 179 i= 4 : 359 i= 5 : 719 i= 6 : 1,439 i= 7 : 2,879 i= 8 : 5,779 i= 9 : 11,579 i=10 : 23,159 i=11 : 46,327 i=12 : 92,657 i=13 : 185,323 i=14 : 370,661 i=15 : 741,337 i=16 : 1,482,707 i=17 : 2,965,421 i=18 : 5,930,887 i=19 : 11,861,791 i=20 : 23,723,597 i=21 : 47,447,201 i=22 : 94,894,427 i=23 : 189,788,857 i=24 : 379,577,741 i=25 : 759,155,483 i=26 : 1,518,310,967 i=27 : 3,036,621,941 i=28 : 6,073,243,889 i=29 : 12,146,487,779 i=30 : 24,292,975,649 i=31 : 48,585,951,311 i=32 : 97,171,902,629 i=33 : 194,343,805,267 i=34 : 388,687,610,539 i=35 : 777,375,221,081 i=36 : 1,554,750,442,183 i=37 : 3,109,500,884,389 i=38 : 6,219,001,768,781 i=39 : 12,438,003,537,571 i=40 : 24,876,007,075,181 i=41 : 49,752,014,150,467 i=42 : 99,504,028,301,131
ALGOL 68
In Algol 68, the FOR loop counter cannot be modified in the loop. This uses a WHILE loop testing at the top but is otherwise largely a translation of the Kotlin entry. <lang algol68>BEGIN
# returns TRUE if n is prime, FALSE otherwise # PROC is prime = ( LONG INT n )BOOL: IF n MOD 2 = 0 THEN n = 2 ELIF n MOD 3 = 0 THEN n = 3 ELSE LONG INT d := 5; BOOL result := TRUE; WHILE IF d * d > n THEN FALSE ELIF n MOD d = 0 THEN result := FALSE ELIF d +:= 2; n MOD d = 0 THEN result := FALSE ELSE d +:= 4; TRUE FI DO SKIP OD; result FI # is prime # ;
LONG INT i := 42; LONG INT n := 0; WHILE n < 42 DO IF is prime( i ) THEN n +:= 1; print( ( "n = " , whole( n, -2 ) , " " , whole( i, -19 ) , newline ) ); i +:= i - 1 FI; i +:= 1 OD
END</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1439 n = 7 2879 n = 8 5779 n = 9 11579 n = 10 23159 n = 11 46327 n = 12 92657 n = 13 185323 n = 14 370661 n = 15 741337 n = 16 1482707 n = 17 2965421 n = 18 5930887 n = 19 11861791 n = 20 23723597 n = 21 47447201 n = 22 94894427 n = 23 189788857 n = 24 379577741 n = 25 759155483 n = 26 1518310967 n = 27 3036621941 n = 28 6073243889 n = 29 12146487779 n = 30 24292975649 n = 31 48585951311 n = 32 97171902629 n = 33 194343805267 n = 34 388687610539 n = 35 777375221081 n = 36 1554750442183 n = 37 3109500884389 n = 38 6219001768781 n = 39 12438003537571 n = 40 24876007075181 n = 41 49752014150467 n = 42 99504028301131
C
The following uses a 'for' rather than a 'do/while' loop but otherwise is similar to the Kotlin entry.
The 'thousands separator' aspect (using the ' flag in printf and setting the locale appropriately) works fine when compiled with gcc on Ubuntu 14.04 but may not work on some other systems as this is not a standard flag. <lang c>#include <stdio.h>
- include <locale.h>
- define LIMIT 42
int is_prime(long long n) {
if (n % 2 == 0) return n == 2; if (n % 3 == 0) return n == 3; long long d = 5; while (d * d <= n) { if (n % d == 0) return 0; d += 2; if (n % d == 0) return 0; d += 4; } return 1;
}
int main() {
long long i; int n; setlocale(LC_NUMERIC, ""); for (i = LIMIT, n = 0; n < LIMIT; i++) if (is_prime(i)) { n++; printf("n = %-2d %'19lld\n", n, i); i += i - 1; } return 0;
}</lang>
- Output:
Same as Kotlin entry
C++
<lang cpp>
- include "stdafx.h"
- include <iostream>
- include <math.h>
using namespace std;
bool isPrime(double number) {
for (double i = number - 1; i >= 2; i--) { if (fmod(number, i) == 0)
return false;
} return true;
} int main() {
double i = 42; int n = 0; while (n < 42) { if (isPrime(i)) { n++;
cout.width(1); cout << left << "n = " << n;
//Only for Text Alignment if (n < 10)
{ cout.width(40); cout << right << i << endl; } else { cout.width(39); cout << right << i << endl; }
i += i - 1;
} i++;
} return 0;
}</lang>
C#
<lang csharp> using System; using System.Globalization;
namespace PrimeNumberLoopcs {
class Program { static bool isPrime(double number) { for(double i = number - 1; i > 1; i--) { if (number % i == 0) return false; } return true; } static void Main(string[] args) { NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat; nfi.NumberDecimalDigits = 0; double i = 42; int n = 0; while (n < 42) { if (isPrime(i)) { n++; Console.WriteLine("n = {0,-20} {1,20}", n, i.ToString("N", nfi)); i += i - 1; } i++; } } }
}</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131
Factor
Explicit loop indices are non-idiomatic, but Factor is certainly capable of using them. Factor has a for loop near-equivalent, <range> [ ] each
, but since it doesn't mesh well with mutation, a while loop is used.
Using two numbers on the data stack
<lang factor>USING: formatting kernel math math.primes tools.memory.private ; IN: rosetta-code.loops-inc-body
42 0 [ dup 42 < ] [
over prime? [ 1 + 2dup swap commas "n = %-2d %19s\n" printf [ dup + 1 - ] dip ] when [ 1 + ] dip
] while 2drop</lang>
Using lexical variables
Factor provides lexical variables for situations where they improve readability. <lang factor>USING: formatting kernel math math.primes tools.memory.private ; IN: rosetta-code.loops-inc-body
[let
42 :> i! 0 :> n! [ n 42 < ] [ i prime? [ n 1 + n! n i commas "n = %-2d %19s\n" printf i i + 1 - i! ] when i 1 + i! ] while
]</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131
Fortran
Fortran does not allow to modify the index inside the loop. <lang fortran>do i=1,10
write(*,*) i i=i+1
end do</lang>
Error - I is currently being used as a DO or implied DO control variable Compilation failed.
Fortran 95
<lang fortran>! Loops Increment loop index within loop body - 17/07/2018
integer*8 n imax=42 i=0; n=42 Do While(i<imax) If (isprime(n)==1) Then i=i+1 Write (*,'(I2,1X,I20)') i,n n=n+n-1 EndIf n=n+1 EndDo End
Function isprime(n) integer*8 n,i If (n==2 .OR. n==3) Then isprime=1 return ElseIf (Mod(n,2)==0 .OR. Mod(n,3)==0) Then isprime=0 return Else i=5 Do While(i*i<=n) If (Mod(n,i)==0 .OR. Mod(n,i+2)==0) Then isprime=0 return EndIf i=i+6 EndDo isprime=1 return EndIf EndFunction</lang>
- Output:
1 43 2 89 3 179 4 359 5 719 6 1439 7 2879 8 5779 9 11579 10 23159 11 46327 12 92657 13 185323 14 370661 15 741337 16 1482707 17 2965421 18 5930887 19 11861791 20 23723597 21 47447201 22 94894427 23 189788857 24 379577741 25 759155483 26 1518310967 27 3036621941 28 6073243889 29 12146487779 30 24292975649 31 48585951311 32 97171902629 33 194343805267 34 388687610539 35 777375221081 36 1554750442183 37 3109500884389 38 6219001768781 39 12438003537571 40 24876007075181 41 49752014150467 42 99504028301131
Fortran IV
The limit is set to 25 due to the size of integer in Fortran IV. <lang fortran>C LOOPS INCREMENT LOOP INDEX WITHIN LOOP BODY - 17/07/2018
IMAX=25 I=0 N=42 10 IF(I.GE.IMAX)GOTO 30 IF(ISPRIME(N).NE.1)GOTO 20 I=I+1 WRITE(*,301) I,N 301 FORMAT(I2,1X,I10) N=N+N-1 20 N=N+1 GOTO 10 30 CONTINUE END
FUNCTION ISPRIME(M) IF(M.NE.2 .AND. M.NE.3)GOTO 10 ISPRIME=1 RETURN 10 IF(MOD(M,2).NE.0 .AND. MOD(M,3).NE.0)GOTO 20 ISPRIME=0 RETURN 20 I=5 30 IF(I*I.GT.M)GOTO 50 IF(MOD(M,I).NE.0 .AND. MOD(M,I+2).NE.0)GOTO 40 ISPRIME=0 RETURN 40 I=I+6 GOTO 30 50 ISPRIME=1 RETURN END</lang>
- Output:
1 43 2 89 3 179 4 359 5 719 6 1439 7 2879 8 5779 9 11579 10 23159 11 46327 12 92657 13 185323 14 370661 15 741337 16 1482707 17 2965421 18 5930887 19 11861791 20 23723597 21 47447201 22 94894427 23 189788857 24 379577741 25 759155483
Go
This uses Go's 'for' loop but is otherwise similar to the Kotlin entry.
The 'thousands separator' aspect is dealt with by a couple of external packages (in the 'import' declarations) which can be installed using 'go get'. <lang go>package main
import(
"golang.org/x/text/language" "golang.org/x/text/message"
)
func isPrime(n uint64) bool {
if n % 2 == 0 { return n == 2 } if n % 3 == 0 { return n == 3 } d := uint64(5) for d * d <= n { if n % d == 0 { return false } d += 2 if n % d == 0 { return false } d += 4 } return true
}
const limit = 42
func main() {
p := message.NewPrinter(language.English) for i, n := uint64(limit), 0; n < limit; i++ { if isPrime(i) { n++ p.Printf("n = %-2d %19d\n", n, i) i += i - 1 } }
}</lang>
- Output:
Same as Kotlin entry
J
Java
The following uses a 'for' rather than a 'do/while' loop but otherwise is similar to the Kotlin entry. <lang java>public class LoopIncrementWithinBody {
static final int LIMIT = 42;
static boolean isPrime(long n) { if (n % 2 == 0) return n == 2; if (n % 3 == 0) return n == 3; long d = 5; while (d * d <= n) { if (n % d == 0) return false; d += 2; if (n % d == 0) return false; d += 4; } return true; }
public static void main(String[] args) { long i; int n; for (i = LIMIT, n = 0; n < LIMIT; i++) if (isPrime(i)) { n++; System.out.printf("n = %-2d %,19d\n", n, i); i += i - 1; } }
}</lang>
- Output:
Same as Kotlin entry
Kotlin
Unlike many other C-family languages (notably Java), Kotlin's 'for' statement doesn't allow either the iteration variable or the step to be modified within the loop body.
So instead we use a do/while loop here which has no such restrictions. <lang scala>// version 1.2.60
fun isPrime(n: Long): Boolean {
if (n % 2L == 0L) return n == 2L if (n % 3L == 0L) return n == 3L var d = 5L while (d * d <= n) { if (n % d == 0L) return false d += 2L if (n % d == 0L) return false d += 4L } return true
}
fun main(args: Array<String>) {
var i = 42L var n = 0 do { if (isPrime(i)) { n++ System.out.printf("n = %-2d %,19d\n", n, i) i += i - 1 } i++ } while (n < 42)
}</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131
Although Kotlin is predominantly an object-oriented/procedural language, it does have some features which enable one to program in a functional style. These features include 'tail recursion' which, of course, is commonly used in place of loops in purely functional languages.
In such cases, the Kotlin compiler optimizes out the recursion, leaving behind a fast and efficient loop based version instead.
The following version uses a tail recursive function rather than a while loop to achieve the same effect:
<lang scala>// version 1.2.60
fun isPrime(n: Long): Boolean {
if (n % 2L == 0L) return n == 2L if (n % 3L == 0L) return n == 3L var d = 5L while (d * d <= n) { if (n % d == 0L) return false d += 2L if (n % d == 0L) return false d += 4L } return true
}
tailrec fun loop(index: Long, numPrimes: Int) {
if (numPrimes == 42) return var i = index var n = numPrimes if (isPrime(i)) { n++ System.out.printf("n = %-2d %,19d\n", n, i) loop(2 * i - 1, n) } else loop(++i, n)
}
fun main(args: Array<String>) {
loop(42, 0)
}</lang>
- Output:
Same as 'while' loop version.
M2000 Interpreter
<lang M2000 Interpreter> Module CheckIt {
Function IsPrime (x) { if x<=5 OR frac(x) then { if x == 2 OR x == 3 OR x == 5 then =true Break } if frac(x/2 ) else exit if frac(x/3) else exit x1=sqrt(x): d=5 {if frac(x/d ) else exit d += 2: if d>x1 then =true : exit if frac(x/d) else exit d += 4: if d<= x1 else =true: exit loop } } \\ For Next loops or For {} loops can't change iterator variable (variable has a copy of real iterator) \\ In those loops we have to use Continue to skip lines and repeat the loop. \\ so we have to use Block iterator, using Loop which set a flag current block to repeat itself once. def long Limit=42, n def currency i i=Limit { if n<limit Else exit if isPrime(i) then n++ : Print format$("n={0::2}: {1:-20}", n, str$(i,"#,###")) : i+=i-1 i++ loop }
} CheckIt </lang>
- Output:
Same as Kotlin entry
Maple
A translation of Kotlin entry <lang Maple>i := 42: count := 0: while(count < 42) do i := i+1: if type(i,prime) then count := count + 1: printf("n=%-2d %19d\n", count,i): i := 2*i -1: end if: end do:</lang>
- Output:
n=1 43 n=2 89 n=3 179 n=4 359 n=5 719 n=6 1439 n=7 2879 n=8 5779 n=9 11579 n=10 23159 n=11 46327 n=12 92657 n=13 185323 n=14 370661 n=15 741337 n=16 1482707 n=17 2965421 n=18 5930887 n=19 11861791 n=20 23723597 n=21 47447201 n=22 94894427 n=23 189788857 n=24 379577741 n=25 759155483 n=26 1518310967 n=27 3036621941 n=28 6073243889 n=29 12146487779 n=30 24292975649 n=31 48585951311 n=32 97171902629 n=33 194343805267 n=34 388687610539 n=35 777375221081 n=36 1554750442183 n=37 3109500884389 n=38 6219001768781 n=39 12438003537571 n=40 24876007075181 n=41 49752014150467 n=42 99504028301131
Microsoft Small Basic
Small Basic allows to modify the index inside the loop. <lang smallbasic>'Loops Increment loop index within loop body - 16/07/2018 imax=42 i=0 n=42 While i<imax
isprime_n() If ret_isprime_n Then i=i+1 format_i() format_n() TextWindow.WriteLine("i="+ret_format_i+" : "+ret_format_n) n=n+n-1 EndIf n=n+1
EndWhile
Sub isprime_n
If n=2 Or n=3 Then ret_isprime_n="True" ElseIf Math.Remainder(n,2)=0 Or Math.Remainder(n,3)=0 Then ret_isprime_n="False" Else j=5 While j*j<=n If Math.Remainder(n,j)=0 Or Math.Remainder(n,j+2)=0 Then ret_isprime_n="False" Goto exitsub EndIf j=j+6 EndWhile ret_isprime_n="True" EndIf
exitsub: EndSub 'isprime_n
Sub format_i
ret_format_i=Text.GetSubText(" ",1,3-Text.GetLength(i))+i
EndSub 'format_i
Sub format_n
nn="" l=-1 For k=Text.GetLength(n) To 1 Step -1 l=l+1 cc=Text.GetSubText(n,k,1) If l=3 Then cv="," l=0 Else cv="" EndIf nn=Text.Append(cc,Text.Append(cv,nn)) EndFor space=" " nn=Text.GetSubText(space,1,Text.GetLength(space)-Text.GetLength(nn))+nn ret_format_n=nn
EndSub 'format_n</lang>
- Output:
i= 1 : 43 i= 2 : 89 i= 3 : 179 i= 4 : 359 i= 5 : 719 i= 6 : 1,439 i= 7 : 2,879 i= 8 : 5,779 i= 9 : 11,579 i=10 : 23,159 i=11 : 46,327 i=12 : 92,657 i=13 : 185,323 i=14 : 370,661 i=15 : 741,337 i=16 : 1,482,707 i=17 : 2,965,421 i=18 : 5,930,887 i=19 : 11,861,791 i=20 : 23,723,597 i=21 : 47,447,201 i=22 : 94,894,427 i=23 : 189,788,857 i=24 : 379,577,741 i=25 : 759,155,483 i=26 : 1,518,310,967 i=27 : 3,036,621,941 i=28 : 6,073,243,889 i=29 : 12,146,487,779 i=30 : 24,292,975,649 i=31 : 48,585,951,311 i=32 : 97,171,902,629 i=33 : 194,343,805,267 i=34 : 388,687,610,539 i=35 : 777,375,221,081 i=36 : 1,554,750,442,183 i=37 : 3,109,500,884,389 i=38 : 6,219,001,768,781 i=39 : 12,438,003,537,571 i=40 : 24,876,007,075,181 i=41 : 49,752,014,150,467 i=42 : 99,504,028,301,131
NewLISP
<lang newlisp>
- ! /usr/local/bin/newlisp
(define (prime? n)
(and (set 'lst (factor n)) (= (length lst) 1)))
(define (thousands_separator i)
(setq i (string i)) (setq len (length i)) (setq i (reverse (explode i))) (setq o "") (setq count3 0) (dolist (x i) (setq o (string o x)) (inc count3) (if (and (= 3 count3) (< (+ $idx 1) len)) (begin (setq o (string o "_")) (setq count3 0)))) (reverse o))
- - - - Main begins here
(setq i 42) (setq n 0) (while (< n 42)
(if (prime? i) (begin (inc n) (println (string "n = " n " -> " (thousands_separator i))) (setq i (+ i i -1)))) (inc i)
)
(exit) </lang>
n = 1 -> 43 n = 2 -> 89 n = 3 -> 179 n = 4 -> 359 n = 5 -> 719 n = 6 -> 1_439 n = 7 -> 2_879 n = 8 -> 5_779 n = 9 -> 11_579 n = 10 -> 23_159 n = 11 -> 46_327 n = 12 -> 92_657 n = 13 -> 185_323 n = 14 -> 370_661 n = 15 -> 741_337 n = 16 -> 1_482_707 n = 17 -> 2_965_421 n = 18 -> 5_930_887 n = 19 -> 11_861_791 n = 20 -> 23_723_597 n = 21 -> 47_447_201 n = 22 -> 94_894_427 n = 23 -> 189_788_857 n = 24 -> 379_577_741 n = 25 -> 759_155_483 n = 26 -> 1_518_310_967 n = 27 -> 3_036_621_941 n = 28 -> 6_073_243_889 n = 29 -> 12_146_487_779 n = 30 -> 24_292_975_649 n = 31 -> 48_585_951_311 n = 32 -> 97_171_902_629 n = 33 -> 194_343_805_267 n = 34 -> 388_687_610_539 n = 35 -> 777_375_221_081 n = 36 -> 1_554_750_442_183 n = 37 -> 3_109_500_884_389 n = 38 -> 6_219_001_768_781 n = 39 -> 12_438_003_537_571 n = 40 -> 24_876_007_075_181 n = 41 -> 49_752_014_150_467 n = 42 -> 99_504_028_301_131
Perl 6
Hmm.
Demonstrate the best way to accomplish this.
The best way is probably to not use an explicit loop. Just calculate the sequence directly.
<lang perl6># the actual sequence logic my @seq = grep *.is-prime, (42, { .is-prime ?? $_+<1 !! $_+1 } … *);
- display code
say (1+$_).fmt("%-4s"), @seq[$_].flip.comb(3).join(',').flip.fmt("%20s") for ^42;</lang>
- Output:
1 43 2 89 3 179 4 359 5 719 6 1,439 7 2,879 8 5,779 9 11,579 10 23,159 11 46,327 12 92,657 13 185,323 14 370,661 15 741,337 16 1,482,707 17 2,965,421 18 5,930,887 19 11,861,791 20 23,723,597 21 47,447,201 22 94,894,427 23 189,788,857 24 379,577,741 25 759,155,483 26 1,518,310,967 27 3,036,621,941 28 6,073,243,889 29 12,146,487,779 30 24,292,975,649 31 48,585,951,311 32 97,171,902,629 33 194,343,805,267 34 388,687,610,539 35 777,375,221,081 36 1,554,750,442,183 37 3,109,500,884,389 38 6,219,001,768,781 39 12,438,003,537,571 40 24,876,007,075,181 41 49,752,014,150,467 42 99,504,028,301,131
Phix
Phix does not allow for loop variables to be modified, so we must use a while loop and manual increment for this sort of thing. There is not, as yet, an is_prime() builtin. We can use prime_factors() returns {}, though it is probably a little bit slower as it builds the full list rather than yielding false asap - but at least we don't have to define an is_prime() function. <lang Phix>atom i=42, n=1 while n<=42 do
if prime_factors(i)={} then printf(1,"n = %-2d %,19d\n", {n, i}) n += 1 i += i-1 end if i += 1
end while</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131
Python
<lang Python>def isPrime(n):
for x in 2, 3: if not n % x: return n == x d = 5 while d * d <= n: for x in 2, 4: if not n % d: return False d += x return True
i = 42 n = 0 while n < 42:
if isPrime(i): n += 1 print('n = {:2} {:20,}'.format(n, i)) i += i - 1 i += 1</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131
REXX
<lang rexx>/*REXX pgm displays primes found: starting Z at 42, if Z is a prime, add Z, else add 1.*/ numeric digits 20; d=digits() /*ensure enough decimal digits for Z. */ parse arg limit . /*obtain optional arguments from the CL*/ if limit== | limit=="," then limit=42 /*Not specified? Then use the default.*/ n=0 /*the count of number of primes found. */
do z=42 until n==limit /* ◄──this DO loop's index is modified.*/ if isPrime(z) then do; n=n + 1 /*Z a prime? Them bump prime counter.*/ say right('n='n, 9) right(commas(z), d) z=z + z - 1 /*also, bump the DO loop index Z. */ end end /*z*/ /* [↑] a small tribute to Douglas Adams*/
exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ commas: parse arg _; do j=length(_)-3 to 1 by -3; _=insert(',', _, j); end; return _ /*──────────────────────────────────────────────────────────────────────────────────────*/ isPrime: procedure; parse arg #; if wordpos(#, '2 3 5 7')\==0 then return 1
if # // 2==0 | # // 3 ==0 then return 0 do j=5 by 6 until j*j>#; if # // j==0 | # // (J+2)==0 then return 0 end /*j*/ /* ___ */ return 1 /*Exceeded √ # ? Then # is prime. */</lang>
- output:
n=1 43 n=2 89 n=3 179 n=4 359 n=5 719 n=6 1,439 n=7 2,879 n=8 5,779 n=9 11,579 n=10 23,159 n=11 46,327 n=12 92,657 n=13 185,323 n=14 370,661 n=15 741,337 n=16 1,482,707 n=17 2,965,421 n=18 5,930,887 n=19 11,861,791 n=20 23,723,597 n=21 47,447,201 n=22 94,894,427 n=23 189,788,857 n=24 379,577,741 n=25 759,155,483 n=26 1,518,310,967 n=27 3,036,621,941 n=28 6,073,243,889 n=29 12,146,487,779 n=30 24,292,975,649 n=31 48,585,951,311 n=32 97,171,902,629 n=33 194,343,805,267 n=34 388,687,610,539 n=35 777,375,221,081 n=36 1,554,750,442,183 n=37 3,109,500,884,389 n=38 6,219,001,768,781 n=39 12,438,003,537,571 n=40 24,876,007,075,181 n=41 49,752,014,150,467 n=42 99,504,028,301,131
Ring
<lang ring>
- Project : Loops/Increment loop index within loop body
load "stdlib.ring" i = 42 n = 0 while n < 42
if isprime(i) n = n + 1 see "n = " + n + " " + i + nl i = i + i - 1 ok i = i + 1
end </lang> Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131
Scala
Like most other Block structured languages (apparently with the exception of Java), Scala's 'for' statement is for the sake of fallibility aka side effect or mutability, limited and doesn't allow either the iteration variable or the step to be modified within the loop body. Both are for serious reasons immutable.
Demonstrate the best way to accomplish this.
So instead we use tail recursion here which, with the use of immutable variables and no side effects, has no such restrictions, and we are save.
- Output:
Best seen running in your browser either by ScalaFiddle (ES aka JavaScript, non JVM) or Scastie (remote JVM).
<lang Scala>import scala.annotation.tailrec
object LoopIncrementWithinBody extends App {
private val (limit, offset) = (42L, 1)
@tailrec private def loop(i: Long, n: Int): Unit = {
def isPrime(n: Long) = n > 1 && ((n & 1) != 0 || n == 2) && (n % 3 != 0 || n == 3) && ((5 to math.sqrt(n).toInt by 2).par forall (n % _ != 0))
if (n < limit + offset) if (isPrime(i)) { printf("n = %-2d %,19d%n".formatLocal(java.util.Locale.GERMANY, n, i)) loop(i + i + 1, n + 1) } else loop(i + 1, n) }
loop(limit, offset)
}</lang>
VBA
Visual Basic for Application (VBA) allows to modify the index inside the loop.
<lang vb> Sub Main()
'Loops Increment loop index within loop body - 17/07/2018 Dim imax, i As Integer Dim n As Currency imax = 42 i = 0: n = 42 Do While i < imax If IsPrime(n) Then i = i + 1 Debug.Print ("i=" & RightX(i, 2) & " : " & RightX(Format(n, "#,##0"), 20)) n = n + n - 1 End If n = n + 1 Loop End Sub 'Main
Function IsPrime(n As Currency) Dim i As Currency If n = 2 Or n = 3 Then IsPrime = True ElseIf ModX(n, 2) = 0 Or ModX(n, 3) = 0 Then IsPrime = False Else i = 5 Do While i * i <= n If ModX(n, i) = 0 Or ModX(n, i + 2) = 0 Then IsPrime = False Exit Function End If i = i + 6 Loop IsPrime = True End If End Function 'IsPrime
Function ModX(a As Currency, b As Currency) As Currency ModX = a - Int(a / b) * b End Function 'ModX Function RightX(c, n) RightX = Right(Space(n) & c, n) End Function 'RightX</lang>
- Output:
i= 1 : 43 i= 2 : 89 i= 3 : 179 i= 4 : 359 i= 5 : 719 i= 6 : 1,439 i= 7 : 2,879 i= 8 : 5,779 i= 9 : 11,579 i=10 : 23,159 i=11 : 46,327 i=12 : 92,657 i=13 : 185,323 i=14 : 370,661 i=15 : 741,337 i=16 : 1,482,707 i=17 : 2,965,421 i=18 : 5,930,887 i=19 : 11,861,791 i=20 : 23,723,597 i=21 : 47,447,201 i=22 : 94,894,427 i=23 : 189,788,857 i=24 : 379,577,741 i=25 : 759,155,483 i=26 : 1,518,310,967 i=27 : 3,036,621,941 i=28 : 6,073,243,889 i=29 : 12,146,487,779 i=30 : 24,292,975,649 i=31 : 48,585,951,311 i=32 : 97,171,902,629 i=33 : 194,343,805,267 i=34 : 388,687,610,539 i=35 : 777,375,221,081 i=36 : 1,554,750,442,183 i=37 : 3,109,500,884,389 i=38 : 6,219,001,768,781 i=39 : 12,438,003,537,571 i=40 : 24,876,007,075,181 i=41 : 49,752,014,150,467 i=42 : 99,504,028,301,131
Visual Basic .NET
Visual Basic .Net allows to modify the index inside the loop.
<lang vbnet>Module LoopsIliwlb
Sub Main() 'Loops Increment loop index within loop body - 17/07/2018 Dim imax, i As Int32 Dim n As Int64 imax = 42 i = 0 : n = 42 While i < imax If IsPrime(n) Then i = i + 1 Console.WriteLine("i=" & RightX(i, 2) & " : " & RightX(Format(n, "#,##0"), 20)) n = n + n - 1 End If n = n + 1 End While End Sub
Function IsPrime(n As Int64) Dim i As Int64 If n = 2 Or n = 3 Then IsPrime = True ElseIf (n Mod 2) = 0 Or (n Mod 3) = 0 Then IsPrime = False Else i = 5 While i * i <= n If (n Mod i) = 0 Or (n Mod (i + 2)) = 0 Then IsPrime = False Exit Function End If i = i + 6 End While IsPrime = True End If End Function 'IsPrime
Function RightX(c, n) RightX = Right(Space(n) & c, n) End Function
End Module</lang>
- Output:
i= 1 : 43 i= 2 : 89 i= 3 : 179 i= 4 : 359 i= 5 : 719 i= 6 : 1,439 i= 7 : 2,879 i= 8 : 5,779 i= 9 : 11,579 i=10 : 23,159 i=11 : 46,327 i=12 : 92,657 i=13 : 185,323 i=14 : 370,661 i=15 : 741,337 i=16 : 1,482,707 i=17 : 2,965,421 i=18 : 5,930,887 i=19 : 11,861,791 i=20 : 23,723,597 i=21 : 47,447,201 i=22 : 94,894,427 i=23 : 189,788,857 i=24 : 379,577,741 i=25 : 759,155,483 i=26 : 1,518,310,967 i=27 : 3,036,621,941 i=28 : 6,073,243,889 i=29 : 12,146,487,779 i=30 : 24,292,975,649 i=31 : 48,585,951,311 i=32 : 97,171,902,629 i=33 : 194,343,805,267 i=34 : 388,687,610,539 i=35 : 777,375,221,081 i=36 : 1,554,750,442,183 i=37 : 3,109,500,884,389 i=38 : 6,219,001,768,781 i=39 : 12,438,003,537,571 i=40 : 24,876,007,075,181 i=41 : 49,752,014,150,467 i=42 : 99,504,028,301,131
zkl
Uses libGMP (GNU MP Bignum Library) for easy prime detection rather than write that bit of code and pollute this solution. <lang zkl>var [const] BN=Import("zklBigNum"); // libGMP n,p := 1,BN(42); do{
if(p.probablyPrime()){ println("n = %2d %,20d".fmt(n,p)); p.add(p); n+=1; } p.add(1);
}while(n<=42);</lang> zkl loop variables are iterators that don't allow direct manipulation of their underlying source. The compiler names these iterators __<index>Walker. However, by using the look ahead stack, we can keep the iterator from advancing through the source. <lang zkl>p:=BN(42); foreach n in ([1..42]){
if(p.probablyPrime()){ println("n = %2d %,20d".fmt(n,p)); p.add(p); } else{ p.add(1); __nWalker.push(n); } // p not prime, don't advance n
}</lang>
- Output:
n = 1 43 n = 2 89 n = 3 179 n = 4 359 n = 5 719 n = 6 1,439 n = 7 2,879 n = 8 5,779 n = 9 11,579 n = 10 23,159 n = 11 46,327 n = 12 92,657 n = 13 185,323 n = 14 370,661 n = 15 741,337 n = 16 1,482,707 n = 17 2,965,421 n = 18 5,930,887 n = 19 11,861,791 n = 20 23,723,597 n = 21 47,447,201 n = 22 94,894,427 n = 23 189,788,857 n = 24 379,577,741 n = 25 759,155,483 n = 26 1,518,310,967 n = 27 3,036,621,941 n = 28 6,073,243,889 n = 29 12,146,487,779 n = 30 24,292,975,649 n = 31 48,585,951,311 n = 32 97,171,902,629 n = 33 194,343,805,267 n = 34 388,687,610,539 n = 35 777,375,221,081 n = 36 1,554,750,442,183 n = 37 3,109,500,884,389 n = 38 6,219,001,768,781 n = 39 12,438,003,537,571 n = 40 24,876,007,075,181 n = 41 49,752,014,150,467 n = 42 99,504,028,301,131