Loops/With multiple ranges: Difference between revisions

m
No edit summary
m (→‎{{header|Wren}}: Minor tidy)
 
(20 intermediate revisions by 15 users not shown)
Line 7:
Some languages allow multiple '''loop''' ranges, such as the '''PL/I''' example (snippet) below.
 
<langsyntaxhighlight lang="pli"> /* all variables are DECLARED as integers. */
prod= 1; /*start with a product of unity. */
sum= 0; /* " " " sum " zero. */
Line 30:
/*SUM and PROD are used for verification of J incrementation.*/
display (' sum= ' || sum); /*display strings to term.*/
display ('prod= ' || prod); /* " " " " */</langsyntaxhighlight>
 
 
Line 42:
 
Show all output here.
<syntaxhighlight lang="text"> A simple PL/I DO loop (incrementing or decrementing) has the construct of:
 
DO variable = start_expression {TO ending_expression] {BY increment_expression} ;
Line 71:
 
In the example above, the clause: -seven to +seven by x
will cause the variable J to have to following values (in this order): -7 -2 3 </langsyntaxhighlight>
 
 
Line 94:
{{trans|Nim}}
 
<langsyntaxhighlight lang="11l">V prod = 1
V s = 0
 
Line 122:
V m = max(ss.len, ps.len)
print(‘ sum = ’ss.rjust(m))
print(‘prod = ’ps.rjust(m))</langsyntaxhighlight>
 
{{out}}
Line 132:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program loopnrange64.s */
Line 332:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 342:
Ada does not support multiple ranges in a single loop.
{{trans|C++}}
<syntaxhighlight lang="ada">
<lang Ada>
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Vectors;
Line 407:
 
end Main;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 415:
=={{header|ALGOL 60}}==
{{works with|MARST}}
<langsyntaxhighlight lang="algol60">begin
integer prod, sum, x, y, z, one, three, seven;
integer j;
Line 440:
outstring(1, "prod= "); outinteger(1, prod); outstring(1, "\n")
end
</syntaxhighlight>
</lang>
{{out}}
<pre> sum= 348173
Line 449:
{{Trans|ALGOL W}}
As with most of the other languages, Algol 68 doesn't support multiple loop ranges, so a sequence pf loops is used instead.
<langsyntaxhighlight lang="algol68">BEGIN
# translation of task PL/1 code, with minimal changes, semicolons required by #
# PL/1 but not allowed in Algol 68 removed, unecessary rounding removed #
Line 478:
print(("prod= ", whole(prod,0), newline)) # " " " " #
END
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 487:
=={{header|ALGOL W}}==
As with most of the other languages, Algol W doesn't support multiple loop ranges, so a sequence pf loops is used instead.
<langsyntaxhighlight lang="algolw">begin
% translation of task PL/1 code, with minimal changes, semicolons required by %
% PL/1 but redundant in Algol W retained ( technically they introduce empty %
Line 517:
write(s_w := 0, " sum= ", sum); %display strings to term.%
write(s_w := 0, "prod= ", prod); % " " " " %
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 523:
prod= -793618560
</pre>
 
=={{header|Amazing Hopper}}==
<syntaxhighlight lang="c">
#include <jambo.h>
 
Main
prod=1, sum=0, x=5, y=-5,z=-2,one=1, three=3, seven=7, j=0
Set decimal '0'
Let ' j := Neg(three) '
Iterator( j+=three, Less equal( j, Pow(3,3) ), Set 'j'; Gosub(Body) )
Let ' j := Neg(seven) '
Iterator( j+=x, Less equal( j, seven ), Set 'j'; Gosub(Body) )
j=555, Iterator( ++j, Less equal( j, Add(550,y) ), Set 'j'; Gosub(Body) )
j=22, Iterator( j-=three, Greater equal( j, -28 ), Set 'j'; Gosub(Body) )
j=x, Iterator( j+=z, Greater equal( j, y ), Set 'j'; Gosub(Body) )
j=1927, Iterator( ++j, Less equal( j, 1939 ), Set 'j'; Gosub(Body) )
Let ' j := Pow(11,x)'
Iterator( ++j, Less equal( j, Add( Pow(11,x),one) ), Set 'j'; Gosub(Body) )
 
Printnl ( "SUM = ", sum, "\nPROD = ",prod )
End
 
Subrutines
 
Define ' Body, j '
Let( sum := Add(sum, Abs(j) ) )
When ( Less ( Abs(prod), Pow(2,27) ) And (Not zero(j)) ) {
Let( prod := Mul(prod, j) )
}
Return
</syntaxhighlight>
{{out}}
<pre>
SUM = 348173
PROD = -793618560
</pre>
 
=={{header|Applesoft BASIC}}==
All of the numeric variables are Floating Point but get displayed as integers. The variable ONE is named UNO because ON is a keyword.
<syntaxhighlight lang="gwbasic">100 ::::::::: REMALL VARIABLES ARE DECLARED AS INTEGERS.
110 PROD= 1 : REMSTART WITH A PRODUCT OF UNITY.
120 SUM= 0:: REM " " " SUM " ZERO.
130 X= +5
140 Y= -5
150 Z= -2
160 UNO= 1
170 THREE= 3
180 SEVEN= 7
190 REM(BELOW) ^ IS EXPONENTIATION: 4^3=64
200 DO(0) = -THREE : T0(0) = 3^3 : BY(0) = THREE
210 DO(1) = -SEVEN : T0(1) = +SEVEN : BY(1) = X
220 DO(2) = 555 : T0(2) = 550 - Y
230 DO(3) = 22 : T0(3) = -28 : BY(3) = -THREE
240 DO(4) = 1927 : T0(4) = 1939
250 DO(5) = X : T0(5) = Y : BY(5) = Z
260 DO(6) = 11^X : T0(6) = 11^X + UNO
270 FOR I = 0 TO 6 : FINISH= T0(I) : BY = BY(I)
280 START = DO(I) : IF NOT BY THEN BY = 1
290 FOR J = START TO FINISH STEP BY
300 REM ABS(N) = ABSOLUTE VALUE
310 SUM= SUM + ABS(J) : REMADD ABSOLUTE VALUE OF J.
320 IF ABS(PROD)<2^27 AND J<>0 THEN PROD=PROD*J:REMPROD IS SMALL ENOUGH AND J NOT 0, THEN MULTIPLY IT.
330 NEXT J, I
340 REMSUM AND PROD ARE USED FOR VERIFICATION OF J INCREMENTATION.
350 PRINT " SUM= ";:N=SUM :GOSUB400:REMDISPLAY STRINGS TO TERM.
360 PRINT "PROD= ";:N=PROD:GOSUB400:REM " " " "
370 END
400 N$ = STR$ ( ABS ( INT (N))):O$ = "":D = -1: FOR I = LEN (N$) TO 1 STEP - 1:C$ = MID$ (N$,I,1) : O$ = MID$ (",",1 + (D < 2)) + O$ : D = (D + 1) * (D < 2) : O$ = C$ + O$: NEXT I: PRINT MID$ ("-",1 + (N > = 0))O$: RETURN</syntaxhighlight>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program loopnrange.s */
Line 725 ⟶ 794:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 732 ⟶ 801:
-793618560
</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">multiLoop: function [ranges, it, blk][
loop ranges 'rng [
loop rng 'r [
let it r
do blk
]
]
]
 
x: 5
y: neg 5
z: neg 2
one: 1
three: 3
seven: 7
 
totalSum: 0
totalProduct: 1
 
multiLoop @[
range.step:three neg three 3^3
range.step:x neg seven seven
range 555 550-y
range.step:neg three 22 neg 28
range 1927 1939
range.step: z x y
range 11^x 1+11^x
] 'i [
totalSum: totalSum + abs i
if and? (abs totalProduct) < 2^27
i <> 0 ->
totalProduct: totalProduct * i
]
 
print ["Sum:" totalSum]
print ["Product:" totalProduct]</syntaxhighlight>
 
{{out}}
 
<pre>Sum: 348173
Product: -793618560</pre>
 
=={{header|AutoHotkey}}==
As with most of the other languages, AutoHotkey doesn't support multiple loop ranges, so a workaround function is used instead.
<langsyntaxhighlight AutoHotkeylang="autohotkey">for_J(doFunction, start, stop, step:=1){
j := start
while (j<=stop) && (start<=stop) && (step>0)
Line 741 ⟶ 853:
while (j>=stop) && (start>stop) && (step<0)
%doFunction%(j), j+=step
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">prod := 1
sum := 0
x := +5
Line 769 ⟶ 881:
prod *= j
}
return</langsyntaxhighlight>
{{out}}
<pre>sum = 348,173
prod = -793,618,560</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f LOOPS_WITH_MULTIPLE_RANGES.AWK
BEGIN {
Line 803 ⟶ 916:
}
function abs(x) { if (x >= 0) { return x } else { return -x } }
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 812 ⟶ 925:
=={{header|BASIC256}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">
<lang BASIC256>
global sum, prod
 
Line 836 ⟶ 949:
print "prod= "; int(prod)
end
</syntaxhighlight>
</lang>
 
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
Line 875 ⟶ 988:
printf("prod = % 'ld\n", prod);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 885 ⟶ 998:
=={{header|C sharp}}==
Multiple ranges don't exist in C# out-of-the-box but it is easy to make something.
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 923 ⟶ 1,036:
static IEnumerable<int> Concat(params IEnumerable<int>[] ranges) => ranges.Aggregate((acc, r) => acc.Concat(r));
static int Pow(this int b, int e) => (int)Math.Pow(b, e);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 933 ⟶ 1,046:
C++ doesn't natively support multiple ranges, but we can simulate that using a list and then iterating over the values in that list.
 
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <cmath>
#include <vector>
Line 980 ⟶ 1,093:
cout << "sum = " << sum << "\n";
cout << "prod = " << prod << "\n";
}</langsyntaxhighlight>
{{out}}
<pre>sum = 348173
prod = -793618560</pre>
 
=={{header|Chipmunk Basic}}==
{{works with|Chipmunk Basic|3.6.4}}
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">100 cls
110 prod = 1 : sum = 0
120 x = 5 : y = -5 : z = -2
130 uno = 1 : tres = 3 : siete = 7
140 for j = -tres to (3^3) step tres : process(j) : next j
150 for j = -siete to siete step x : process(j) : next j
160 for j = 555 to 550-y : process(j) : next j
170 for j = 22 to -28 step -tres : process(j) : next j
180 for j = 1927 to 1939 : process(j) : next j
190 for j = x to y step z : process(j) : next j
200 for j = (11^x) to (11^x)+uno : process(j) : next j
210 print " sum= ";sum
220 print "prod= ";prod
230 end
240 sub process(x)
250 sum = sum+abs(x)
260 if abs(prod) < (2^27) and x <> 0 then prod = prod*x
270 end sub</syntaxhighlight>
{{out}}
<pre> sum= 348173
prod= -793618560</pre>
 
=={{header|Common Lisp}}==
Using raw code and DO iterator
<langsyntaxhighlight lang="lisp">
(let ((prod 1) ; Initialize aggregator
(sum 0)
Line 1,027 ⟶ 1,165:
(format t "~&sum = ~14<~:d~>" sum)
(format t "~&prod = ~14<~:d~>" prod))
</syntaxhighlight>
</lang>
or with loop ranges and increments as list to dolist
<langsyntaxhighlight lang="lisp">
(let ((prod 1)
(sum 0)
Line 1,060 ⟶ 1,198:
(format t "~&sum = ~14<~:d~>" sum)
(format t "~&prod = ~14<~:d~>" prod))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,071 ⟶ 1,209:
{{Trans|C}}
Delphi don't have for with multiples ranges and for with different increments (except +1 and -1). The workaround is using while loop.
<syntaxhighlight lang="delphi">
<lang Delphi>
program with_multiple_ranges;
 
Line 1,177 ⟶ 1,315:
writeln(format('prod = %d ', [prod]));
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre>sum = 348173
prod = -793618560</pre>
 
=={{header|EasyLang}}==
<lang>prod = 1
sum = 0
x = 5
y = -5
z = -2
one = 1
three = 3
seven = 7
ranges[][] = [ [ -three (pow 3 3) three ] [ -seven seven x ] [ 555 (550 - y) ] [ 22 -28 (-three) ] [ 1927 1939 ] [ x y z ] [ (pow 11 x) (pow 11 x + one) ] ]
#
for i range len ranges[][]
j = ranges[i][0]
to = ranges[i][1]
inc = 1
if len ranges[i][] = 3
inc = ranges[i][2]
.
repeat
until inc > 0 and j > to or inc < 0 and j < to
sum += abs j
if abs prod < pow 2 27 and j <> 0
prod *= j
.
j += inc
.
.
print sum
print prod</lang>
 
=={{header|Eiffel}}==
Eiffel does not support multiple ranges in the same fashion as PL/I. However, it does have an across loop, which does the trick, together with an inline agent (lambda function).
<langsyntaxhighlight lang="eiffel">
class
APPLICATION
Line 1,253 ⟶ 1,361:
 
end
</syntaxhighlight>
</lang>
 
Alternatively, there is the "symbolic form" of the across loop, which modifies the code as follows:
 
<langsyntaxhighlight lang="eiffel">
class
APPLICATION
Line 1,296 ⟶ 1,404:
 
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,303 ⟶ 1,411:
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// Loops/With multiple ranges. Nigel Galloway: June 13th., 2022
let x,y,z,one,three,seven=5,-5,-2,1,3,7
let Range=[-three..three..pown 3 3]@[-7..x..seven]@[555..550-y]@[22..-three.. -28]@[1927..1939]@[x..z..y]@[pown 11 x..(pown 11 x)+1]
printfn "Sum=%d Product=%d" (Range|>Seq.sumBy(abs)) (Range|>Seq.filter((<>)0)|>Seq.fold(fun n g->if abs n<pown 2 27 then n*g else n) 1)
</syntaxhighlight>
{{out}}
<pre>
Sum=348173 Product=-793618560
</pre>
=={{header|Factor}}==
Factor doesn't have any special support for this sort of thing, but we can store iterable <code>range</code> objects in a collection and loop over them.
<langsyntaxhighlight lang="factor">USING: formatting kernel locals math math.functions math.ranges
sequences sequences.generalizations tools.memory.private ;
 
Line 1,336 ⟶ 1,455:
! SUM and PROD are used for verification of J incrementation.
sum prod [ commas ] bi@ " sum= %s\nprod= %s\n" printf
]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,342 ⟶ 1,461:
prod= -793,618,560
</pre>
 
 
=={{header|FreeBASIC}}==
{{trans|VBA}}
<langsyntaxhighlight lang="freebasic">
Dim Shared As Long prod, sum
 
Line 1,371 ⟶ 1,489:
Print Using "prod= ####,###,###"; prod
Sleep
</syntaxhighlight>
</lang>
 
=={{header|FutureBasic}}==
Note: This code uses NSInteger variables instead of int because NSInteger automatically adjusts to 32-bit or 64-bit Macintosh architecture. Also, since FB's abs() function takes either a legacy int or a float, this code uses a float for the abs() parameter to avoid a warning,
<syntaxhighlight lang="futurebasic">
window 1, @"Loops with Ranges", ( 0, 0, 400, 400 )
 
begin globals
NSInteger sum = 0
float prod = 1
end globals
 
local fn process( x as float )
sum += abs(x)
if abs(prod) < (2 ^ 27) and x <> 0 then prod = prod * x
end fn
 
NSInteger j
NSInteger x = 5, y = -5, z = -2
NSInteger one = 1, three = 3, seven = 7
 
for j = -three to (3 ^ 3) step three: fn process(j): next j
for j = -seven to seven step x: fn process(j): next j
for j = 555 to 550 - y: fn process(j): next j
for j = 22 to -28 step -three: fn process(j): next j
for j = 1927 to 1939: fn process(j): next j
for j = x to y step z: fn process(j): next j
for j = (11 ^ x) to (11 ^ x) + one: fn process(j): next j
 
print using " sum = ###,###"; sum
print using "prod =-####,###,###"; prod
 
HandleEvents
</syntaxhighlight>
 
{{out}}
<pre>
sum = 348,173
prod = -793,618,560
</pre>
 
=={{header|Go}}==
Nothing fancy from Go here (is there ever?), just a series of individual for loops.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,457 ⟶ 1,613:
fmt.Println("sum = ", commatize(sum))
fmt.Println("prod = ", commatize(prod))
}</langsyntaxhighlight>
 
{{out}}
Line 1,467 ⟶ 1,623:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">def (prod, sum, x, y, z, one, three, seven) = [1, 0, +5, -5, -2, 1, 3, 7]
 
for (
Line 1,490 ⟶ 1,646:
 
println " sum= ${sum}"
println "prod= ${prod}"</langsyntaxhighlight>
 
Output:
Line 1,500 ⟶ 1,656:
Haskell does not have loops. Programmers use either explicit recursion or recursive schemes (folds or unfolds) for looping. The following code mimics the PL/1 example using composition of left folds in order to handle multiple ranges:
 
<langsyntaxhighlight lang="haskell">loop :: (b -> a -> b) -> b -> [[a]] -> b
loop = foldl . foldl
 
Line 1,530 ⟶ 1,686:
, [1927 .. 1939]
, [x, x + z .. y]
, [11^x .. 11^x + one] ]</langsyntaxhighlight>
 
=={{header|J}}==
J uses the names x, y, m, n, u, v to pass arguments into explicit definitions. Treating these as reserved names is reasonable practice. Originally these had been x. , y. etceteras however the dots must have been deemed "noisy".
 
Rendered in (mostly) ALL CAPS, because this kind of code ought to be in ALL CAPS.
We've passed the range list argument literally for evaluation in local scope. Verb f evaluates and concatenates the ranges, then perhaps the ensuing for. loop looks somewhat like familiar code.
 
<syntaxhighlight lang=J>TO=: {{
<lang j>
'N M'=. 2{.y,1
NB. http://rosettacode.org/wiki/Loops/Wrong_ranges#J
x:x+M*i.>.(1+N-x)%M
NB. define range as a linear polynomial
}}
start =: 0&{
stop =: 1&{
increment =: 2&{ :: 1: NB. on error use 1
range =: (start , increment) p. [: i. [: >: [: <. (stop - start) % increment
 
f BY=: 3 :0,
 
input =. y
{{
'prod sum x y z one three seven' =. 1 0 5 _5 _2 1 3 7
PROD=: 1
J =. ([: ; range&.>) ". input
SUM=: 0
for_j. J do.
sum X=. sum: + | j5
Y=: -5
if. ((|prod)<2^27) *. (0 ~: j) do.
prod Z=. prod *: j-2
ONE=: 1
end.
THREE=: 3
SEVEN=: 7
 
for_J. ;do >cutLF {{)n
< (-THREE) TO (3^3) BY THREE
< (-SEVEN) TO (+SEVEN) BY X
< 555 TO 550-Y
< 22 TO _28 BY -THREE
< 1927 TO 1939
< X TO Y BY Z
< (11^X) TO (11^X) + ONE
}} do.
SUM=: SUM+|J
if. ((|PROD)<2^27) * J~:0 do. PROD=: PROD*J end.
end.
echo ' SUM= ',":SUM
sum , prod
echo 'PROD= ',":PROD
)
}}0</syntaxhighlight>
</lang>
 
Running this script produces this output:
<pre>
 
] A =: f '((-three), (3^3), three); ((-seven),seven,x); (555 , 550-y); (22 _28, -three); 1927 1939; (x,y,z); (0 1 + 11^x)'
<pre> SUM= 348168
348173 _7.93619e8
PROD= _793618560</pre>
20j0 ": A
348173 _793618560
</pre>
 
=={{header|Java}}==
Line 1,575 ⟶ 1,738:
Maintain formatting similar to the original code.
 
<langsyntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.List;
Line 1,621 ⟶ 1,784:
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,645 ⟶ 1,808:
to facilitate comparison with the PL/I code, this has not been done.
 
<syntaxhighlight lang="jq">
<lang jq>
# If using gojq, one may want to preserve integer precision, so:
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);
Line 1,672 ⟶ 1,835:
| "sum= \(.sum)",
"prod= \(.prod)"
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,681 ⟶ 1,844:
=={{header|Julia}}==
Julia allows concatenation of iterators with the ; iterator within a vector. An attempt was made to preserve the shape of the PL/1 code.
<langsyntaxhighlight lang="julia">using Formatting
 
function PL1example()
Line 1,712 ⟶ 1,875:
 
PL1example()
</langsyntaxhighlight> {{output}} <pre>
sum = 348,173
prod = -793,618,560
Line 1,718 ⟶ 1,881:
 
=={{header|Kotlin}}==
Nothing special here, justUsing a series of individual for loops.:
<langsyntaxhighlight scalalang="kotlin">// Version 1.2.70
 
import kotlin.math.abs
Line 1,756 ⟶ 1,919:
System.out.printf("sum = % ,d\n", sum)
System.out.printf("prod = % ,d\n", prod)
}</langsyntaxhighlight>
 
{{output}}
Line 1,763 ⟶ 1,926:
prod = -793,618,560
</pre>
 
The following version does it in a similar way to PL/I and Algol-60, i.e. without defining a function to process the loop, using a ''single'' loop, and without creating a list from which to iterate:
<syntaxhighlight lang="kotlin">
import kotlin.math.abs
import kotlin.math.pow
 
private infix fun Int.`^`(exponent: Int): Int = toDouble().pow(exponent).toInt()
 
fun main() {
var prod = 1
var sum = 0
val x = 5
val y = -5
val z = -2
val one = 1
val three = 3
val seven = 7
val p = 11 `^` x
 
for (j in sequenceOf(
-three..(3 `^` 3) step three,
-seven..seven step x,
555..550-y,
22 downTo -28 step three,
1927..1939,
x downTo y step -z,
p..p + one
).flatten()) {
sum += abs(j)
if (abs(prod) < (2 `^` 27) && j != 0) prod *= j
}
System.out.printf("sum = % ,d\n", sum)
System.out.printf("prod = % ,d\n", prod)
}</syntaxhighlight>
 
{{output}}
<pre>
sum = 348,173
prod = -793,618,560
</pre>
 
=={{header|Lua}}==
Not directly supported, i.e. no ''true'' multi-range loops, but.. all that's really needed is a helper function to populate the list of values, aiming to specify the ranges with a syntax as-close-as-manageable to mimic that given in task description (iteration is then trivial):
<syntaxhighlight lang="lua">-- support:
function T(t) return setmetatable(t, {__index=table}) end
table.range = function(t,a,b,c) local s=T{} for i=a,b,c or 1 do s[#s+1]=i end return s end
table.clone = function(t) local s=T{} for k,v in ipairs(t) do s[k]=v end return s end
table.chain = function(t,u) local s=t:clone() for i=1,#u do s[#s+1]=u[i] end return s end
unpack = unpack or table.unpack -- polyfill 5.2 vs 5.3
 
-- impl:
-- Multi-Range-Loop
-- param: table of tables of range specs
-- return: iterator over the chain of all ranges
function mrl(tt)
local s=T{}
for _,t in ipairs(tt) do s=s:chain(T{}:range(unpack(t))) end
return ipairs(s)
end
 
-- demo:
prod,sum,x,y,z,one,three,seven = 1,0,5,-5,-2,1,3,7
for _,j in mrl{
{ -three, 3^3, three },
{ -seven, seven, x },
{ 555, 550-y },
{ 22, -28, -three },
{ 1927, 1939 },
{ x, y, z },
{ 11^x, 11^x+1 }} do
sum = sum + math.abs(j)
if math.abs(prod) < 2^27 and j~=0 then prod = prod * j end
end
print(" sum= " .. sum)
print("prod= " .. prod)</syntaxhighlight>
{{out}}
<pre> sum= 348173
prod= -793618560</pre>
 
=={{header|M2000 Interpreter}}==
Line 1,771 ⟶ 2,012:
In M2000 expressions can change numeric type to hold the produced value. Variables take once the type, so we get overflow if we pass a value frome an expression which can't convert to variable's type.
 
<langsyntaxhighlight M2000lang="m2000 Interpreterinterpreter">Module MultipleLoop {
def long prod=1, sum=0, x=+5,y=-5, z=-2, one=1, three=3, seven=7, j
Range=lambda (a, b, c=1) ->{
Line 1,797 ⟶ 2,038:
}
MultipleLoop
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 1,805 ⟶ 2,046:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">prod = 1;
sum = 0;
x = 5;
Line 1,830 ⟶ 2,071:
]
sum
prod</langsyntaxhighlight>
{{out}}
<pre>348173
Line 1,841 ⟶ 2,082:
This solution is the obvious one, but it supposes that the direction of the loop is known (i.e. the sign of the step is known) as we have to choose between iterators “countup” and “countdown”. Using this method, the PL/1 example can be translated the following way:
 
<syntaxhighlight lang="nim">
<lang Nim>
import math, strutils
 
Line 1,873 ⟶ 2,114:
let m = max(s.len, p.len)
echo " sum = ", s.align(m)
echo "prod = ", p.align(m)</langsyntaxhighlight>
 
Note that for “countdown” we must change the sign of the step to insure that it is positive.
Line 1,884 ⟶ 2,125:
If the sign of the step is not known (or may vary), it is no longer possible to use the previous method. One could use a while loop but it seems better to use an iterator.
 
<langsyntaxhighlight Nimlang="nim">import math, strutils
 
var
Line 1,927 ⟶ 2,168:
let m = max(s.len, p.len)
echo " sum = ", s.align(m)
echo "prod = ", p.align(m)</langsyntaxhighlight>
 
Note that we have defined a function “initRange” to create the ranges. This is needed to make the step optional. If we suppressed this requirement (i.e. we required the step to be always specified), we could get ride of “initRange” and write the loop this way:
 
<langsyntaxhighlight Nimlang="nim">for j in loop((-three, 3^3, three),
(-seven, seven, x),
(555, 550 - y),
Line 1,939 ⟶ 2,180:
(11^x, 11^x + one)):
sum += abs(j)
if abs(prod) < 2^27 and j != 0: prod *= j</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use constant one => 1;
use constant three => 3;
use constant seven => 7;
Line 1,977 ⟶ 2,218:
 
printf "%-8s %12s\n", 'Sum:', commatize $sum;
printf "%-8s %12s\n", 'Product:', commatize $prod;</langsyntaxhighlight>
{{out}}
<pre>Sum: 348,173
Line 1,983 ⟶ 2,224:
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">prod</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (renamed as sum is a Phix builtin)</span>
Line 2,012 ⟶ 2,253:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" sum = %,d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"prod = %,d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prod</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 2,018 ⟶ 2,259:
prod = -793,618,560
</pre>
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="Phixmonti">/# Rosetta Code problem: https://rosettacode.org/wiki/Loops/With_multiple_ranges
by Galileo, 11/2022 #/
 
include ..\Utilitys.pmt
 
1 var prod
0 var total
+5 var x
-5 var y
-2 var z
1 var one
3 var three
7 var seven
 
( ( three neg 3 3 power three )
( seven neg seven x )
( 555 550 y - 1 )
( 22 -28 three neg )
( 1927 1939 1 )
( x y z )
( 11 x power 11 x power one + 1 ) )
 
len for
get for
dup abs total + var total
dup prod abs 2 27 power < and if prod * var prod else drop endif
endfor
endfor
 
( " sum = " total "\n" "prod = " prod ) lprint</syntaxhighlight>
{{out}}
<pre> sum = 348173
prod = -793618560
=== Press any key to exit ===</pre>
 
=={{header|Picat}}==
Picat has support for multiple loop variables, but the index variables for each range must be different:
<langsyntaxhighlight Picatlang="picat">foreach(I in 1..3, J in 4..6, K in 7..9)
% ...
end</langsyntaxhighlight>
 
Here's a variant using the single loop variable <code>J</code>.
<langsyntaxhighlight Picatlang="picat">go =>
Prod= 1,
Sum= 0,
Line 2,051 ⟶ 2,328:
println(sum=Sum),
println(prod=Prod),
nl.</langsyntaxhighlight>
 
{{out}}
Line 2,058 ⟶ 2,335:
 
Another approach is to first concatenate the ranges and then flatten to a single list:
<langsyntaxhighlight Picatlang="picat"> % ...
foreach(J in [-Three..Three..3**3,
-Seven..X.. +Seven,
Line 2,074 ⟶ 2,351:
end,
% ...
</syntaxhighlight>
</lang>
 
 
 
=={{header|Prolog}}==
Prolog does not have the richness of some other languages where it comes to loops, variables and the like, but does have some rather interesting features such as difference lists and backtracking for generating solutions.
<langsyntaxhighlight lang="prolog">for(Lo,Hi,Step,Lo) :- Step>0, Lo=<Hi.
for(Lo,Hi,Step,Val) :- Step>0, plus(Lo,Step,V), V=<Hi, !, for(V,Hi,Step,Val).
for(Hi,Lo,Step,Hi) :- Step<0, Lo=<Hi.
Line 2,119 ⟶ 2,394:
calc_values(Sum, Product) :- % Find the sum and product
findall(V, range_value(V), Values),
calc_values(Values, 0, 1, Sum, Product).</langsyntaxhighlight>
 
<pre>?- calc_values(Sum, Product).
Line 2,126 ⟶ 2,401:
 
=={{header|PureBasic}}==
<langsyntaxhighlight lang="purebasic">#X = 5 : #Y = -5 : #Z = -2
#ONE = 1 : #THREE = 3 : #SEVEN = 7
Define j.i
Line 2,164 ⟶ 2,439:
PrintN("prod = " + ifn(prod))
Input()
EndIf</langsyntaxhighlight>
{{out}}
<pre>sum = 348,173
Line 2,171 ⟶ 2,446:
=={{header|Python}}==
Pythons range function does not include the second argument hence the definition of _range()
<langsyntaxhighlight lang="python">from itertools import chain
 
prod, sum_, x, y, z, one,three,seven = 1, 0, 5, -5, -2, 1, 3, 7
Line 2,188 ⟶ 2,463:
if abs(prod) < 2**27 and (j != 0):
prod *= j
print(f' sum= {sum_}\nprod= {prod}')</langsyntaxhighlight>
 
{{out}}
Line 2,197 ⟶ 2,472:
 
=={{header|QB64}}==
<syntaxhighlight lang="qb64">
<lang QB64>
'Task
'Simulate/translate the above PL/I program snippet as best as possible
Line 2,252 ⟶ 2,527:
 
Loop
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 2,268 ⟶ 2,543:
Displaying the j sequence as well since it isn't very large.
 
<syntaxhighlight lang="raku" perl6line>sub comma { ($^i < 0 ?? '-' !! '') ~ $i.abs.flip.comb(3).join(',').flip }
 
my \x = 5;
Line 2,308 ⟶ 2,583:
put "\nLiteral minded variant:";
put ' Sum: ', comma [+] $j».abs;
put ' Product: ', comma ([\*] $j.grep: so +*).first: *.abs > 2²⁷;</langsyntaxhighlight>
{{Out}}
<pre>j sequence: -3 0 3 6 9 12 15 18 21 24 27 -7 -2 3 555 22 19 16 13 10 7 4 1 -2 -5 -8 -11 -14 -17 -20 -23 -26 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 5 3 1 -1 -3 -5 161051 161052
Line 2,320 ⟶ 2,595:
=={{header|Red}}==
As "to" has another meaning in Red, we name "->" the range operator.
<syntaxhighlight lang="text">Red ["For loop with multiple ranges"]
 
->: make op! function [start end][
Line 2,357 ⟶ 2,632:
if all [(absolute prod) < power 2 27 j <> 0] [prod: prod * j]
]
print ["sum: " sum "^/prod:" prod]</langsyntaxhighlight>
{{Out}}
<pre>sum: 348173
Line 2,370 ⟶ 2,645:
various &nbsp; '''do''' &nbsp; iterating clauses (ranges) into
separate &nbsp; '''do''' &nbsp; loops, &nbsp; and have them invoke a subroutine to perform the actual computations.
<langsyntaxhighlight lang="rexx">/*REXX program emulates a multiple─range DO loop (all variables can be any numbers). */
prod= 1;
sum= 0;
Line 2,398 ⟶ 2,673:
meat: sum= sum + abs(j);
if abs(prod)<2**27 & j\==0 then prod= prod * j;
return;</langsyntaxhighlight>
{{out|output|text= &nbsp; when using the same variable values:}}
<pre>
Line 2,407 ⟶ 2,682:
=={{header|Ring}}==
{{trans|Phix}}
<langsyntaxhighlight lang="ring">
prod = 1
total = 0
Line 2,439 ⟶ 2,714:
see "total = " + total + nl
see "product = " + prod + nl
</syntaxhighlight>
</lang>
{{out}}
<pre>
total = 348173
product = -793618560
</pre>
 
=={{header|RPL}}==
It's not exactly idiomatic, but it works.
≪ 5 -5 -2 1 3 7 → x y z one three seven
≪ { { '-three' '3^3' 'three' }
{ '-seven' 'seven' 'x' }
{ 555 '550-y' }
{ 22 -28 '-three' }
{ 1927 1939 }
{ 'x' 'y' 'z' }
{ '11^x' '11^x+one' } } → ranges
≪ 1 0
1 ranges SIZE '''FOR''' n
ranges n GET
'''IF''' DUP SIZE 2 == '''THEN''' 1 + '''END'''
LIST→ DROP EVAL → from to by
≪ from EVAL to EVAL '''FOR''' j
j ABS +
'''IF''' OVER ABS 2 27 ^ < j AND '''THEN''' SWAP j * SWAP '''END'''
by '''STEP'''
'''NEXT''' SWAP
≫ ≫ ≫ '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
2: 348173
1: -793618560
</pre>
 
=={{header|Ruby}}==
Uses chaining of enumerables, which was introduced with Ruby 2.6
<langsyntaxhighlight Rubylang="ruby">x, y, z, one, three, seven = 5, -5, -2, 1, 3, 7
 
 
enums = (-three).step(3**3, three) +
Line 2,463 ⟶ 2,767:
prod = enums.inject(1){|prod, j| ((prod.abs < 2**27) && j!=0) ? prod*j : prod}
puts "Product (but not really): #{prod}"
</syntaxhighlight>
</lang>
{{out}}
<pre>Sum of absolute numbers: 348173
Line 2,471 ⟶ 2,775:
=={{header|Smalltalk}}==
Ranges (called ''Interval'' in Smalltalk) are collections, which - like all collections - can be concatenated with the <tt>,</tt> (comma) message. Intervals are created by sending a <tt>to:</tt> or <tt>to:by:</tt> message to a magnitude-like thingy (i.e. other than numbers are possible):
<langsyntaxhighlight lang="smalltalk">prod := 1.
sum := 0.
x := 5.
Line 2,494 ⟶ 2,798:
].
Transcript show:' sum = '; showCR:sum.
Transcript show:'prod = '; showCR:prod</langsyntaxhighlight>
The above creates a temporary "collection of ranges" and enumerates that, which might be inconvenient, if the collections are huge.
<br>One alternative is to loop over each individually.
Line 2,501 ⟶ 2,805:
and we usually don't want to the code to be non-local (i.e. define another method for it).
<br>That's what blocks (aka lambdas or anonymous functions) are perfect for:
<langsyntaxhighlight lang="smalltalk">prod := 1.
sum := 0.
x := 5.
Line 2,526 ⟶ 2,830:
(11**x to: 11**x + one ) do:action.
Transcript show:' sum = '; showCR:sum.
Transcript show:'prod = '; showCR:prod</langsyntaxhighlight>
 
As another alternative to the first solution above, we can loop over the ranges. This avoids the concatenations and generation of the intermediate big collection (which does not really make a difference here, but would, if each collection consisted of millions of objects):
{{works with|Smalltalk/X}}<langsyntaxhighlight lang="smalltalk">...
{
(three negated to: 3**3 by: three ) .
Line 2,544 ⟶ 2,848:
]
].
...</langsyntaxhighlight>
Notice: this creates only 8 objects and also demonstrates an alternative element selection scheme, which may be more readable.
{{out}}
Line 2,551 ⟶ 2,855:
 
Note) Dialects with no <tt>**</tt>-method should use <tt>raisedTo:</tt>, or else define an alias for it in Number as:
<langsyntaxhighlight lang="smalltalk">** arg
^ self raisedTo: arg</langsyntaxhighlight>
 
 
=={{header|True BASIC}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="qbasic">
SUB process(x)
LET sum = sum + abs(x)
Line 2,596 ⟶ 2,900:
PRINT "prod= "; prod
END
</syntaxhighlight>
</lang>
 
 
=={{header|TXR}}==
 
<syntaxhighlight lang="txrlisp">(defmacro mfor (:form f (var . range-triplets) . forms)
(with-gensyms (body toval stepval test)
^(let (,var)
(flet ((,body () ,*forms))
,*(append-each ((rt (tuples 3 range-triplets)))
(mac-param-bind f (from to step) rt
^((set ,var ,from)
(for* ((,toval ,to)
(,stepval ,step)
(,test (if (<= ,var ,toval)
(fun <=) (fun >=))))
([,test ,var ,toval])
((inc ,var ,stepval))
(,body)))))))))
 
(let ((prod 1) (sum 0)
(x 5) (y -5) (z -2)
(one 1) (three 3) (seven 7))
(mfor (j (- three) (expt 3 3) three
(- seven) seven x
555 (- 550 y) 1
22 -28 (- three)
1927 1939 1
x y z
(expt 11 x) (succ (expt 11 x)) 1)
(upd sum (+ (abs j)))
(if (and (< (abs prod) (ash 1 27))
(nzerop j))
(upd prod (* j))))
(put-line `sum = @sum; prod = @prod`))</syntaxhighlight>
 
{{out}}
 
<pre>sum = 348173; prod = -793618560</pre>
 
=={{header|uBasic/4tH}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="text">p = 1 ' product
s = 0 ' sum
 
x = 5
y = -5
z = -2
 
o = 1 ' one
t = 3 ' three
v = 7 ' seVen
For j = -t To (3 ^ 3) Step t: Proc _Process(j) : Next
For j = -v To v Step x: Proc _Process(j) : Next
For j = 555 To 550 - y: Proc _Process(j) : Next
For j = 22 To -28 Step -t: Proc _Process(j) : Next
For j = 1927 To 1939: Proc _Process(j) : Next
For j = x To y Step z: Proc _Process(j) : Next
For j = (11 ^ x) To (11 ^ x) + o: Proc _Process(j) : Next
Print Using " sum= +###,###"; s
Print Using "prod= +###,###,###"; p
End
 
_Process
Param (1)
s = s + Abs(a@)
If (Abs(p) < (2 ^ 27)) * (a@ # 0) Then p = p * a@
Return</syntaxhighlight>
{{out}}
<pre> sum= 348,173
prod= -793,618,560
 
0 OK, 0:537</pre>
 
=={{header|Vala}}==
<langsyntaxhighlight lang="vala">const int CHARBIT = 8;
long prod = 1;
long sum = 0;
Line 2,645 ⟶ 3,023:
stdout.printf("sum = %10ld\n", sum);
stdout.printf("prod = %10ld\n", prod);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,653 ⟶ 3,031:
 
=={{header|VBA}}==
<langsyntaxhighlight VBlang="vb">Dim prod As Long, sum As Long
Public Sub LoopsWithMultipleRanges()
Dim x As Integer, y As Integer, z As Integer, one As Integer, three As Integer, seven As Integer, j As Long
Line 2,680 ⟶ 3,058:
sum = sum + Abs(x)
If Abs(prod) < pow(2, 27) And x <> 0 Then prod = prod * x
End Sub</langsyntaxhighlight>
{{out}}
<pre> sum= 348.173
Line 2,691 ⟶ 3,069:
 
Using the following to provide the functionality of the For loop as a function,
<langsyntaxhighlight lang="vbnet">Partial Module Program
' Stop and Step are language keywords and must be escaped with brackets.
Iterator Function Range(start As Integer, [stop] As Integer, Optional [step] As Integer = 1) As IEnumerable(Of Integer)
Line 2,698 ⟶ 3,076:
Next
End Function
End Module</langsyntaxhighlight>
 
and Enumerable.Concat (along with extension method syntax) to splice the ranges, the program ends up looking like this:
 
<langsyntaxhighlight lang="vbnet">Imports System.Globalization
 
Partial Module Program
Line 2,737 ⟶ 3,115:
Console.WriteLine(String.Format(format, "prod= {0:N}", prod))
End Sub
End Module</langsyntaxhighlight>
 
To improve the program's appearance, a ConcatRange method can be defined to combine the two method calls,
<langsyntaxhighlight lang="vbnet"> <Runtime.CompilerServices.Extension>
Function ConcatRange(source As IEnumerable(Of Integer), start As Integer, [stop] As Integer, Optional [step] As Integer = 1) As IEnumerable(Of Integer)
Return source.Concat(Range(start, [stop], [step]))
End Function</langsyntaxhighlight>
 
which results in a loop that looks like this:
<langsyntaxhighlight lang="vbnet"> For Each j In Range(-three, CInt(3 ^ 3), 3 ).
ConcatRange(-seven, +seven, x ).
ConcatRange(555, 550 - y ).
Line 2,753 ⟶ 3,131:
ConcatRange(x, y, z ).
ConcatRange(CInt(11 ^ x), CInt(11 ^ x) + one )
Next</langsyntaxhighlight>
 
An alternative to avoid the repeated method calls would be to make a Range function that accepts multiple ranges, in this case as a parameter array of tuples.
<langsyntaxhighlight lang="vbnet"> Function Range(ParamArray ranges() As (start As Integer, [stop] As Integer, [step] As Integer)) As IEnumerable(Of Integer)
' Note: SelectMany is equivalent to bind, flatMap, etc.
Return ranges.SelectMany(Function(r) Range(r.start, r.stop, r.step))
End Function</langsyntaxhighlight>
 
resulting in:
<langsyntaxhighlight lang="vbnet"> For Each j In Range((-three, CInt(3 ^ 3), 3 ),
(-seven, +seven, x ),
(555, 550 - y, 1 ),
Line 2,769 ⟶ 3,147:
(x, y, z ),
(CInt(11 ^ x), CInt(11 ^ x) + one, 1 ))
Next</langsyntaxhighlight>
 
Note, however, that the inability to have a heterogenous array means that specifying the step is now mandatory. Using a parameter array of arrays is slightly less clear but results in the tersest loop.
<langsyntaxhighlight lang="vbnet"> Function Range(ParamArray ranges As Integer()()) As IEnumerable(Of Integer)
Return ranges.SelectMany(Function(r) Range(r(0), r(1), If(r.Length < 3, 1, r(2))))
End Function</langsyntaxhighlight>
 
<langsyntaxhighlight lang="vbnet"> For Each j In Range({-three, CInt(3 ^ 3), 3 },
{-seven, +seven, x },
{555, 550 - y },
Line 2,783 ⟶ 3,161:
{x, y, z },
{CInt(11 ^ x), CInt(11 ^ x) + one })
Next</langsyntaxhighlight>
 
{{out|note=for all variations}}
Line 2,791 ⟶ 3,169:
=={{header|Wren}}==
{{trans|Go}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var prod = 1
Line 2,851 ⟶ 3,229:
}
 
SystemFmt.print("sum = %(Fmt.dc($,d", sum))")
SystemFmt.print("prod = %(Fmt.dc($,d", prod))")</langsyntaxhighlight>
 
{{out}}
Line 2,861 ⟶ 3,239:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">func IPow(A, B); \Return A**B
int A, B;
return fix(Pow(float(A), float(B)));
Line 2,894 ⟶ 3,272:
Text(0, " Sum= "); IntOut(0, Sum); CrLf(0); \display strings to term.
Text(0, "Prod= "); IntOut(0, Prod); CrLf(0); \ " " " "
end</langsyntaxhighlight>
 
{{out}}
Line 2,904 ⟶ 3,282:
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="yabasic">
sub process(x)
sum = sum + abs(x)
Line 2,926 ⟶ 3,304:
print "prod= ", prod using "####,###,###"
end
</syntaxhighlight>
</lang>
 
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">prod,sum := 1,0; /* start with a product of unity, sum of 0 */
x,y,z := 5, -5, -2;
one,three,seven := 1,3,7;
Line 2,940 ⟶ 3,318:
}
/* SUM and PROD are used for verification of J incrementation */
println("sum = %,d\nprod = %,d".fmt(sum,prod));</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits