Loops/Nested: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|REXX}}: expanded a comment in the REXX section header.)
(Added ColdFusion)
Line 369: Line 369:
GOBACK
GOBACK
.</lang>
.</lang>

=={{header|ColdFusion}}==
<lang cfm>
<Cfset RandNum = 0>
<Cfloop condition="randNum neq 20">
<Cfloop from="1" to="5" index="i">
<Cfset randNum = RandRange(1, 20)>
<Cfoutput>#randNum# </Cfoutput>
<Cfif RandNum eq 20><cfbreak></Cfif>
</Cfloop>
<br>
</Cfloop>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==

Revision as of 19:02, 2 July 2014

Task
Loops/Nested
You are encouraged to solve this task according to the task description, using any language you may know.

Show a nested loop which searches a two-dimensional array filled with random numbers uniformly distributed over . The loops iterate rows and columns of the array printing the elements until the value is met. Specifically, this task also shows how to break out of nested loops.

Ada

<lang ada>with Ada.Text_IO; use Ada.Text_IO; with Ada.Numerics.Discrete_Random;

procedure Test_Loop_Nested is

  type Value_Type is range 1..20;
  package Random_Values is new Ada.Numerics.Discrete_Random (Value_Type);
  use Random_Values;
  Dice : Generator;
  A : array (1..10, 1..10) of Value_Type :=
         (others => (others => Random (Dice)));

begin

Outer :

  for I in A'Range (1) loop
     for J in A'Range (2) loop
        Put (Value_Type'Image (A (I, J)));
        exit Outer when A (I, J) = 20;
     end loop;
     New_Line;
  end loop Outer;

end Test_Loop_Nested;</lang>

Sample output:
 16 3 1 17 13 5 4 2 19 1
 5 5 17 15 17 2 5 5 17 13
 16 10 10 20

ALGOL 68

Translation of: C

- note: This specimen retains the original C coding style.

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards)

<lang algol68>main: (

   [10][10]INT a; INT i, j;
   FOR i FROM LWB a TO UPB a DO
       FOR j FROM LWB a[i] TO UPB a[i] DO
           a[i][j] := ENTIER (random * 20 + 1)
       OD
   OD ;
   FOR i FROM LWB a TO UPB a DO
       FOR j FROM LWB a[i] TO UPB a[i] DO
           print(whole(a[i][j], -3));
           IF a[i][j] = 20 THEN
               GO TO xkcd com 292 # http://xkcd.com/292/ #
           FI
       OD;
       print(new line)
   OD;

xkcd com 292:

   print(new line)

)</lang>

Sample output:
  8 14 17  6 18  1  1  7  9  6
  8  9  1 15  3  1 10 19  6  7
 12 20

AutoHotkey

<lang AutoHotkey>Loop, 10 {

 i := A_Index
 Loop, 10
 {
   j := A_Index
   Random, a%i%%j%, 1, 20
 }

}

Loop, 10 {

 i := A_Index
 Loop, 10
 {
   j := A_Index
   If (a%i%%j% == 20)
     Goto finish
 }

}

finish:

 MsgBox % "a[" . i . "][" . j . "]" is 20

Return</lang>

AWK

To break from two loops, this program uses two break statements and one b flag. <lang awk>BEGIN { rows = 5 columns = 5

# Fill ary[] with random numbers from 1 to 20. for (r = 1; r <= rows; r++) { for (c = 1; c <= columns; c++) ary[r, c] = int(rand() * 20) + 1 }

# Find a 20. b = 0 for (r = 1; r <= rows; r++) { for (c = 1; c <= columns; c++) { v = ary[r, c] printf " %2d", v if (v == 20) { print b = 1 break } } if (b) break print } }</lang>

BASIC

Works with: QuickBasic version 4.5

<lang qbasic>DIM a(1 TO 10, 1 TO 10) AS INTEGER CLS FOR row = 1 TO 10

       FOR col = 1 TO 10
               a(row, col) = INT(RND * 20) + 1
       NEXT col

NEXT row

FOR row = LBOUND(a, 1) TO UBOUND(a, 1)

       FOR col = LBOUND(a, 2) TO UBOUND(a, 2)
               PRINT a(row, col)
               IF a(row, col) = 20 THEN END
       NEXT col

NEXT row</lang>

BBC BASIC

<lang bbcbasic> DIM array(10,10)

     FOR row% = 0 TO 10
       FOR col% = 0 TO 10
         array(row%,col%) = RND(20) + 1
       NEXT
     NEXT row%
     FOR row% = 0 TO 10
       FOR col% = 0 TO 10
         PRINT "row "; row%, "col ";col%, "value "; array(row%,col%)
         IF array(row%,col%) = 20 EXIT FOR row%
       NEXT
     NEXT row%

</lang> EXIT FOR can jump out of multiple nested loops by specifying a control variable.

bc

Arrays have only one dimension, so we use a[i * c + j] instead of a[i, j].

Translation of: AWK

<lang bc>s = 1 /* Seed of the random number generator */

/* Random number from 1 to 20. */ define r() { auto r while (1) { /* * Formula (from POSIX) for random numbers of low * quality, from 0 to 32767. */ s = (s * 1103515245 + 12345) % 4294967296 r = (s / 65536) % 32768

/* Prevent modulo bias. */ if (r >= 32768 % 20) break } return ((r % 20) + 1) }

r = 5 /* Total rows */ c = 5 /* Total columns */

/* Fill array a[] with random numbers from 1 to 20. */ for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { a[i * c + j] = r() } }

/* Find a 20. */ b = 0 for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { v = a[i * c + j] v /* Print v and a newline. */ if (v == 20) { b = 1 break } } if (b) break /* Print "==" and a newline. */ "== " } quit</lang>

C

Using goto (note: gotos are considered harmful): <lang c>#include <stdlib.h>

  1. include <time.h>
  2. include <stdio.h>

int main() {

   int a[10][10], i, j;
   srand(time(NULL));
   for (i = 0; i < 10; i++)
       for (j = 0; j < 10; j++)
           a[i][j] = rand() % 20 + 1;
   for (i = 0; i < 10; i++) {
       for (j = 0; j < 10; j++) {
           printf(" %d", a[i][j]);
           if (a[i][j] == 20)
               goto Done;
       }
       printf("\n");
   }

Done:

   printf("\n");
   return 0;

}</lang>

C++

Works with: C++11

<lang cpp>#include<cstdlib>

  1. include<ctime>
  2. include<iostream>

using namespace std; int main() {

   int arr[10][10];
   srand(time(NULL));
   for(auto& row: arr)
       for(auto& col: row)
           col = rand() % 20 + 1;
   ([&](){
      for(auto& row : arr)
          for(auto& col: row)
          {
              cout << col << endl;
              if(col == 20)return;
          }
   })();
   return 0;

}</lang>

C#

Uses goto as C# has no way to break from multiple loops <lang csharp>using System;

class Program {

   static void Main(string[] args) {
       int[,] a = new int[10, 10];
       Random r = new Random();
       for (int i = 0; i < 10; i++) {
           for (int j = 0; j < 10; j++) {
               a[i, j] = r.Next(0, 20) + 1;
           }
       }
       
       for (int i = 0; i < 10; i++) {
           for (int j = 0; j < 10; j++) {
               Console.Write(" {0}", a[i, j]);
               if (a[i, j] == 20) {
                   goto Done;
               }
           }
           Console.WriteLine();
       }
   Done:
       Console.WriteLine();
   }

}</lang>

Chapel

<lang chapel>use Random;

var nums:[1..10, 1..10] int; var rnd = new RandomStream();

[ n in nums ] n = floor(rnd.getNext() * 21):int; delete rnd;

// this shows a clumsy explicit way of iterating, to actually create nested loops: label outer for i in nums.domain.dim(1) {

       for j in nums.domain.dim(2) {
               write(" ", nums(i,j));
               if nums(i,j) == 20 then break outer;
       }
       writeln();

}</lang>

Clojure

We explicitly return a status flag from the inner loop: <lang clojure>(ns nested)

(defn create-matrix [width height]

 (for [_ (range width)]
   (for [_ (range height)]
     (inc (rand-int 20)))))

(defn print-matrix [matrix]

 (loop [[row & rs] matrix]
   (when (= (loop [[x & xs] row]
              (println x)
              (cond (= x 20) :stop
                    xs (recur xs)
                    :else :continue))
            :continue)
     (when rs (recur rs)))))

(print-matrix (create-matrix 10 10))</lang>

COBOL

<lang cobol> IDENTIFICATION DIVISION.

      PROGRAM-ID. Nested-Loop.
      DATA DIVISION.
      LOCAL-STORAGE SECTION.
      78  Table-Size VALUE 10.
      01  Table-Area.
          03  Table-Row OCCURS Table-Size TIMES
                  INDEXED BY Row-Index.
              05  Table-Element PIC 99 OCCURS Table-Size TIMES
                  INDEXED BY Col-Index.
      01  Current-Time PIC 9(8).
      PROCEDURE DIVISION.
  • *> Seed RANDOM.
          ACCEPT Current-Time FROM TIME
          MOVE FUNCTION RANDOM(Current-Time) TO Current-Time
  • *> Put random numbers in the table.
  • *> The AFTER clause is equivalent to a nested PERFORM VARYING
  • *> statement.
          PERFORM VARYING Row-Index FROM 1 BY 1
                      UNTIL Table-Size < Row-Index
                  AFTER Col-Index FROM 1 BY 1
                      UNTIL Table-Size < Col-Index
              COMPUTE Table-Element (Row-Index, Col-Index) =
                  FUNCTION MOD((FUNCTION RANDOM * 1000), 20) + 1
          END-PERFORM
  • *> Search through table for 20.
  • *> Using proper nested loops.
          PERFORM VARYING Row-Index FROM 1 BY 1
                  UNTIL Table-Size < Row-Index
              PERFORM VARYING Col-Index FROM 1 BY 1
                      UNTIL Table-Size < Col-Index
                  IF Table-Element (Row-Index, Col-Index) = 20
                      EXIT PERFORM
                  ELSE
                      DISPLAY Table-Element (Row-Index, Col-Index)
                  END-IF
              END-PERFORM
          END-PERFORM
          GOBACK
          .</lang>

ColdFusion

<lang cfm> <Cfset RandNum = 0> <Cfloop condition="randNum neq 20"> <Cfloop from="1" to="5" index="i"> <Cfset randNum = RandRange(1, 20)> <Cfoutput>#randNum# </Cfoutput> <Cfif RandNum eq 20><cfbreak></Cfif> </Cfloop>
</Cfloop> </lang>

Common Lisp

<lang lisp>(let ((a (make-array '(10 10))))

 (dotimes (i 10)
   (dotimes (j 10)
     (setf (aref a i j) (1+ (random 20)))))
  
 (block outer
   (dotimes (i 10)
     (dotimes (j 10)
       (princ " ")
       (princ (aref a i j))
       (if (= 20 (aref a i j))
           (return-from outer)))
     (terpri))
   (terpri)))</lang>

D

<lang d>import std.stdio, std.random;

void main() {

   int[10][10] mat;
   foreach (ref row; mat)
       foreach (ref item; row)
           item = uniform(1, 21);
   outer:
   foreach (row; mat)
       foreach (item; row) {
           write(item, ' ');
           if (item == 20)
               break outer;
       }
   writeln();

}</lang>

Delphi/Pascal

<lang delphi>var

 matrix: array[1..10,1..10] of Integer;
 row, col: Integer;
 broken: Boolean;

begin

 // Launch random number generator
 randomize;
 // Filling matrix with random numbers
 for row := 1 to 10 do
   for col := 1 to 10 do
     matrix[row, col] := Succ(Random(20));
 // Displaying values one by one, until at the end or reached number 20
 Broken := False;
 for row := 1 to 10 do
 begin
   for col := 1 to 10 do
   begin
     ShowMessage(IntToStr(matrix[row, col]));
     if matrix[row, col] = 20 then
     begin
       Broken := True;
       break;
     end;
   end;
   if Broken then break;
 end;

end;</lang>

dc

A single Q command can break multiple nested loops.

Translation of: bc

<lang dc>1 ss [Seed of the random number generator.]sz

[*

* lrx -- (number)
* Push a random number from 1 to 20.
*]sz

[

[                [If preventing modulo bias:]sz
 sz               [Drop this random number.]sz
 lLx              [Loop.]sz
]SI
[                [Loop:]sz
 [*
  * Formula (from POSIX) for random numbers of low quality.
  * Push a random number from 0 to 32767.
  *]sz
 ls 1103515245 * 12345 + 4294967296 % ss
 ls 65536 / 32768 %
 d 32768 20 % >I  [Prevent modulo bias.]sz
]d SL x
20 % 1 +         [Be from 1 to 20.]sz
LLsz LIsz        [Restore L, I.]sz

]sr


5 sb [b = Total rows]sz 5 sc [c = Total columns]sz

[Fill array a[] with random numbers from 1 to 20.]sz [ [Inner loop for j:]sz

lrx            [Push random number.]sz
li lc * lj +   [Push index of a[i, j].]sz
:a             [Put in a[].]sz
lj 1 + d sj    [j += 1]sz
lc >I          [Loop while c > j.]sz

]sI [ [Outer loop for i:]sz

0 d sj         [j = 0]sz
lc >I          [Enter inner loop.]sz
li 1 + d si    [i += 1]sz
lb >L          [Loop while b > i.]sz

]sL 0 d si [i = 0]sz lb >L [Enter outer loop.]sz

[Find a 20.]sz [ [If detecting a 20:]sz

li lj + 3 + Q  [Break outer loop.]sz

]sD [ [Inner loop for j:]sz

li lc * lj +   [Push index of a[i,j].]sz
;a             [Push value from a[].]sz
p              [Print value and a newline.]sz
20 =D          [Detect a 20.]sz
lj 1 + d sj    [j += 1]sz
lc >I          [Loop while c > j.]sz

]sI [ [Outer loop for i:]sz

0 d sj         [j = 0]sz
lc >I          [Enter inner loop.]sz
[==

]P [Print "==" and a newline.]sz

li 1 + d si    [i += 1]sz
lb >L          [Loop while b > i.]sz

]sL 0 d si [i = 0]sz lb >L [Enter outer loop.]sz</lang> In this program, li lj + 3 + Q breaks both the inner loop and the outer loop. We must count how many levels of string execution to break. Our loops use tail recursion, so each iteration is a level of string execution. We have i + 1 calls to outer loop L, and j + 1 calls to inner loop I, and 1 call to condition D; so we break i + j + 3 levels with li lj + 3 + Q.

E

<lang e>def array := accum [] for i in 1..5 { _.with(accum [] for i in 1..5 { _.with(entropy.nextInt(20) + 1) }) }

escape done {

   for row in array {
       for x in row {
           print(`$x$\t`)
           if (x == 20) {
               done()
           }
       }
       println()
   }

} println("done.")</lang>

Erlang

<lang Erlang> -module( loops_nested ).

-export( [task/0] ).

task() ->

      Size = 20,
      Two_dimensional_array = [random_array(Size) || _X <- lists:seq(1, Size)],
      print_until_found( [], 20, Two_dimensional_array ).


print_until_found( [], N, [Row | T] ) -> print_until_found( print_until_found_row(N, Row), N, T ); print_until_found( _Found, _N, _Two_dimensional_array ) -> io:fwrite( "~n" ).

print_until_found_row( _N, [] ) -> []; print_until_found_row( N, [N | T] ) -> [N | T]; print_until_found_row( N, [H | T] ) ->

       io:fwrite( "~p ", [H] ),
       print_until_found_row( N, T ).

random_array( Size ) -> [random:uniform(Size) || _X <- lists:seq(1, Size)]. </lang>

Euphoria

<lang euphoria>sequence a a = rand(repeat(repeat(20, 10), 10))

integer wantExit wantExit = 0

for i = 1 to 10 do

   for j = 1 to 10 do

printf(1, "%g ", {a[i][j]}) if a[i][j] = 20 then wantExit = 1 exit end if

   end for
   if wantExit then

exit

   end if

end for</lang> exit only breaks out of the innermost loop. A better way to do this would be a procedure.

Fantom

There is no specific way to break out of nested loops (such as a labelled break, or goto). Instead, we can use exceptions and a try-catch block. <lang fantom>class Main {

 public static Void main ()
 {
   rows := 10
   cols := 10
   // create and fill an array of given size with random numbers
   Int[][] array := [,]
   rows.times
   {
     row := [,]
     cols.times { row.add(Int.random(1..20)) }
     array.add (row)
   }
   // now do the search
   try
   {
     for (i := 0; i < rows; i++)
     {
       for (j := 0; j < cols; j++)
       {
         echo ("now at ($i, $j) which is ${array[i][j]}")
         if (array[i][j] == 20) throw (Err("found it"))
       }
     }
   }
   catch (Err e)
   {
     echo (e.msg)
     return // and finish
   }
   echo ("No 20")
 }

}</lang>

Forth

<lang forth>include random.fs

10 constant X 10 constant Y

,randoms ( range n -- ) 0 do dup random 1+ , loop drop ;

create 2darray 20 X Y * ,randoms

main
 Y 0 do
   cr
   X 0 do
     j X * i + cells 2darray + @
     dup .
     20 = if unloop unloop exit then
   loop
 loop ;</lang>

Fortran

Works with: Fortran version 77 and later

<lang fortran> PROGRAM LOOPNESTED

       INTEGER A, I, J, RNDINT

C Build a two-dimensional twenty-by-twenty array.

       DIMENSION A(20,20)

C It doesn't matter what number you put here.

       CALL SDRAND(123)

C Fill the array with random numbers.

       DO 20 I = 1, 20
         DO 10 J = 1, 20
           A(I, J) = RNDINT(1, 20)
  10     CONTINUE
  20   CONTINUE

C Print the numbers.

       DO 40 I = 1, 20
         DO 30 J = 1, 20
           WRITE (*,5000) I, J, A(I, J)

C If this number is twenty, break out of both loops.

           IF (A(I, J) .EQ. 20) GOTO 50
  30     CONTINUE
  40   CONTINUE

C If we had gone to 40, the DO loop would have continued. You can C label STOP instead of adding another CONTINUE, but it is good C form to only label CONTINUE statements as much as possible.

  50   CONTINUE
       STOP

C Print the value so that it looks like one of those C arrays that C makes everybody so comfortable.

5000   FORMAT('A[', I2, '][', I2, '] is ', I2)
     END

C FORTRAN 77 does not have come with a random number generator, but it C is easy enough to type "fortran 77 random number generator" into your C preferred search engine and to copy and paste what you find. The C following code is a slightly-modified version of: C C http://www.tat.physik.uni-tuebingen.de/ C ~kley/lehre/ftn77/tutorial/subprograms.html

     SUBROUTINE SDRAND (IRSEED)
       COMMON  /SEED/ UTSEED, IRFRST
       UTSEED = IRSEED
       IRFRST = 0
       RETURN
     END
     INTEGER FUNCTION RNDINT (IFROM, ITO)
       INTEGER IFROM, ITO
       PARAMETER (MPLIER=16807, MODLUS=2147483647,                     &
    &              MOBYMP=127773, MOMDMP=2836)
       COMMON  /SEED/ UTSEED, IRFRST
       INTEGER HVLUE, LVLUE, TESTV, NEXTN
       SAVE    NEXTN
       IF (IRFRST .EQ. 0) THEN
         NEXTN = UTSEED
         IRFRST = 1
       ENDIF
       HVLUE = NEXTN / MOBYMP
       LVLUE = MOD(NEXTN, MOBYMP)
       TESTV = MPLIER*LVLUE - MOMDMP*HVLUE
       IF (TESTV .GT. 0) THEN
         NEXTN = TESTV
       ELSE
         NEXTN = TESTV + MODLUS
       ENDIF
       IF (NEXTN .GE. 0) THEN
         RNDINT = MOD(MOD(NEXTN, MODLUS), ITO - IFROM + 1) + IFROM
       ELSE
         RNDINT = MOD(MOD(NEXTN, MODLUS), ITO - IFROM + 1) + ITO + 1
       ENDIF
       RETURN
     END</lang>
Sample output:
A[ 1][ 1] is  2
A[ 1][ 2] is 16
A[ 1][ 3] is 16
A[ 1][ 4] is  3
A[ 1][ 5] is 16
A[ 1][ 6] is 15
A[ 1][ 7] is 18
A[ 1][ 8] is 14
A[ 1][ 9] is  9
A[ 1][10] is 10
A[ 1][11] is 12
A[ 1][12] is 15
A[ 1][13] is  3
A[ 1][14] is 19
A[ 1][15] is 20
Works with: Fortran version 90 and later

<lang fortran>program Example

 implicit none
 real :: ra(5,10)
 integer :: ia(5,10)
 integer :: i, j
 call random_number(ra)
 ia = int(ra * 20.0) + 1

outer: do i = 1, size(ia, 1)

        do j = 1, size(ia, 2)
          write(*, "(i3)", advance="no") ia(i,j)
          if (ia(i,j) == 20) exit outer
        end do
        write(*,*)
      end do outer
      

end program Example</lang>

Sample output:
 14  2  1 11  8  1 14 11  3 15
  7 15 16  6  7 17  3 20 

GAP

<lang gap># You can't break an outer loop unless you return from the whole function. n := 40; a := List([1 .. n], i -> List([1 .. n], j -> Random(1, 20)));;

Find := function(a, x)

   local i, j, n;
   n := Length(a);
   for i in [1 .. n] do
       for j in [1 .. n] do
           if a[i][j] = x then
               return [i, j];
           fi;
       od;
   od;
   return fail;

end;

Find(a, 20);</lang>

Go

<lang go>package main

import (

   "fmt"
   "math/rand"
   "time"

)

func main() {

   rand.Seed(time.Now().UnixNano())
   values := make([][]int, 10)
   for i := range values {
       values[i] = make([]int, 10)
       for j := range values[i] {
           values[i][j] = rand.Intn(20) + 1
       }
   }

outerLoop:

   for i, row := range values {
       fmt.Printf("%3d)", i)
       for _, value := range row {
           fmt.Printf(" %3d", value)
           if value == 20 {
               break outerLoop
           }
       }
       fmt.Printf("\n")
   }
   fmt.Printf("\n")

}</lang>

Groovy

Translation of: Java

Solution: <lang groovy>final random = new Random() def a = [] (0..<10).each {

   def row = []
   (0..<10).each {
       row << (random.nextInt(20) + 1)
   }
   a << row

}

a.each { println it } println ()

Outer: for (i in (0..<a.size())) {

   for (j in (0..<a[i].size())) {
       if (a[i][j] == 20){
           println ([i:i, j:j])
           break Outer
       }
   }

}</lang>

Output:
[1, 19, 14, 16, 3, 12, 14, 18, 12, 6]
[6, 3, 8, 9, 17, 4, 10, 15, 17, 17]
[5, 12, 13, 1, 8, 18, 8, 15, 3, 20]
[8, 9, 6, 7, 2, 20, 17, 13, 6, 16]
[18, 6, 11, 13, 16, 20, 7, 3, 1, 14]
[6, 6, 19, 9, 9, 7, 16, 16, 3, 20]
[7, 6, 12, 7, 16, 14, 13, 18, 15, 15]
[19, 14, 14, 6, 4, 19, 5, 10, 13, 12]
[7, 6, 6, 12, 3, 9, 17, 12, 20, 7]
[10, 7, 15, 4, 17, 13, 14, 16, 8, 8]

[i:2, j:9]

Haskell

<lang haskell>import Data.List

breakIncl p = uncurry ((. take 1). (++)). break p

taskLLB k = map (breakIncl (==k)). breakIncl (k`elem`)</lang>

Example:

<lang haskell>mij :: Int mij = takeWhile(not.null). unfoldr (Just. splitAt 5) $

     [2, 6, 17, 5, 14, 1, 9, 11, 18, 10, 13, 20, 8, 7, 4, 16, 15, 19, 3, 12]
  • Main> mapM_ (mapM_ print) $ taskLLB 20 mij

2 6 17 5 14 1 9 11 18 10 13 20</lang>

HicEst

<lang hicest>REAL :: n=20, array(n,n)

array = NINT( RAN(10,10) )

DO row = 1, n

 DO col = 1, n
   WRITE(Name) row, col, array(row,col)
   IF( array(row, col) == 20 ) GOTO 99
 ENDDO

ENDDO

99 END</lang>

Icon and Unicon

Icon and Unicon use 'break' to exit loops and execute an expression argument. To exit nested loops 'break' is repeated as the expression. <lang Icon>procedure main()

every !(!(L  := list(10)) := list(10))  := ?20 # setup a 2d array of random numbers up to 20

every i := 1 to *L do # using nested loops

  every j := 1 to *L[i] do
     if L[i,j] = 20 then 
        break break write("L[",i,",",j,"]=20")

end</lang> <lang Icon>every x := L[i := 1 to *L,1 to *L[i]] do

   if x = 20 then break write("L[",i,",",j,"]=20")  # more succinctly  

every if !!L = 20 then break write("Found !!L=20") # even more so (but looses the values of i and j</lang>

J

In J, using loops is usually a bad idea.

Here's how the problem statement (ignoring the "requirement" for loops) could be solved, without loops: <lang J>use=: ({.~ # <. 1+i.&20)@:,</lang> Here's how the problem could be solved, using loops: <lang J>doubleLoop=:verb define

 for_row.i.#y do.
   for_col.i.1{$y do.
     smoutput t=.(<row,col) { y
     if.20=t do.return.end.
   end.
 end.

)</lang>

Example use:
   use ?.20 20 $ 21
6 17 13 3 5 16 10 4 20
   doubleLoop ?.20 20 $ 21
6
17
13
3
5
16
10
4
20

The first approach is probably a couple thousand times faster than the second.

(In real life, good problem definitions might typically involve "use cases" (which are specified in terms of the problem domain, instead in terms of irrelevant details). Of course "Rosetta Code" is about how concepts would be expressed in different languages. However, even here, tasks which dwell on language-specific issues are probably not a good use of people's time.)

Java

<lang java>import java.util.Random;

public class NestedLoopTest {

   public static final Random gen = new Random();
   public static void main(String[] args) {
       int[][] a = new int[10][10];
       for (int i = 0; i < a.length; i++)
           for (int j = 0; j < a[i].length; j++)
               a[i][j] = gen.nextInt(20) + 1;
       Outer:for (int i = 0; i < a.length; i++) {
           for (int j = 0; j < a[i].length; j++) {
               System.out.print(" " + a[i][j]);
               if (a[i][j] == 20)
                   break Outer; //adding a label breaks out of all loops up to and including the labelled loop
           }
           System.out.println();
       }
       System.out.println();
   }

}</lang>

JavaScript

Demonstrates use of break with a label. Uses print() function from Rhino. <lang javascript>// a "random" 2-D array var a = [[2, 12, 10, 4], [18, 11, 9, 3], [14, 15, 7, 17], [6, 19, 8, 13], [1, 20, 16, 5]];

outer_loop: for (var i in a) {

   print("row " + i);
   for (var j in a[i]) {
       print(" " + a[i][j]);
       if (a[i][j] == 20) 
           break outer_loop;
   }

} print("done");</lang>

Lasso

<lang Lasso>local(a) = array(

   array(2, 12, 10, 4), 
   array(18, 11, 9, 3), 
   array(14, 15, 7, 17), 
   array(6, 19, 8, 13), 
   array(1, 20, 16, 5)

)

// Query expression with i in delve(#a) do {

   stdoutnl(#i)
   #i == 20 ? return

}

// Nested loops

  1. a->foreach => {
   #1->foreach => {
       stdoutnl(#1)
       #1 == 20 ? return
   }

}</lang>

Liberty BASIC

<lang lb>dim ar(10,10) for i = 1 to 10

   for j = 1 to 10
       ar(i, j) = int(rnd(1) * 20) + 1
   next

next

flag=0 for x = 1 to 10

   for y = 1 to 10
       print ar(x,y)
       if ar(x,y) = 20 then
           flag=1
           exit for
       end if
   next
   if flag then exit for

next print "Completed row ";x;" and column ";y</lang>

Lisaac

<lang Lisaac>Section Header

+ name := TEST_LOOP_NESTED;

- external := `#include <time.h>`;

Section Public

- main <- (

 + a : ARRAY2[INTEGER];
 + i, j: INTEGER;
 `srand(time(NULL))`;
 a := ARRAY2[INTEGER].create(0, 0) to (9, 9);
 0.to 9 do { ii : INTEGER;
   0.to 9 do { jj : INTEGER;
     a.put (`rand()`:INTEGER % 20 + 1) to (ii, jj);
   };
 };
 { i < 10 }.while_do {
   j := 0;
   { j < 10 }.while_do {
     ' '.print;
     a.item(i, j).print;
     (a.item(i, j) = 20).if {
       i := 999;
       j := 999;
     };
     j := j + 1;
   };
   i := i + 1;
   '\n'.print;
 };
 '\n'.print;

);</lang>

<lang logo>make "a mdarray [10 10]

for [j 1 10] [for [i 1 10] [mdsetitem list :i :j :a (1 + random 20)]]

to until.20

 for [j 1 10] [
   for [i 1 10] [
     type mditem list :i :j :a
     type "| |
     if equal? 20 mditem list :i :j :a [stop]
   ]
   print "||
 ]

end until.20</lang>

Lua

<lang lua>t = {} for i = 1, 20 do

 t[i] = {}
 for j = 1, 20 do t[i][j] = math.random(20) end

end function exitable()

 for i = 1, 20 do
   for j = 1, 20 do
     if t[i][j] == 20 then 
       return i, j
     end
   end
 end

end print(exitable())</lang>

Maple

<lang Maple>(m,n) := LinearAlgebra:-Dimensions(M): for i from 1 to m do

 for j from 1 to n do
   print(M[i,j]);
   if M[i,j] = 20 then
     (i,j):=m,n; next;
   end if;
 end do;

end do:</lang>

Mathematica

<lang Mathematica>Do[ Print[mi, j];

   If[mi, j === 20, Return[]], 
 {i, 1, Dimensions[m]1}, 
 {j, 1, Dimensions[m]2}]</lang>

MATLAB / Octave

Loops are considered slow in Matlab and Octave, it is preferable to vectorize the code. <lang Matlab> a = ceil(rand(100,100)*20); [ix,iy]=find(a==20,1)</lang> A non-vectorized version of the code is shown below in Octave

Maxima

<lang maxima>data: apply(matrix, makelist(makelist(random(100), 20), 20))$

find_value(a, x) := block(

  [p, q],
  [p, q]: matrix_size(a),
  catch(
     for i thru p do
        for j thru q do
           if a[i, j] = x then throw([i, j]),
     'not\ found
  )

)$

find_value(data, 100); not found</lang>

MOO

<lang moo>a = make(10, make(10)); for i in [1..10]

 for j in [1..10]
   a[i][j] = random(20);
 endfor

endfor for i in [1..10]

 s = "";
 for j in [1..10]
   s += tostr(" ", a[i][j]);
   if (a[i][j] == 20)
     break i;
   endif
 endfor
 player:tell(s);
 s = "";

endfor player:tell(s);</lang>

MUMPS

<lang MUMPS>NESTLOOP

;.../loops/nested
;set up the 2D array with random values
NEW A,I,J,K,FLAG,TRIGGER
SET K=15 ;Magic - just to give us a size to work with
SET TRIGGER=20 ;Magic - the max value, and the end value
FOR I=1:1:K FOR J=1:1:K SET A(I,J)=$RANDOM(TRIGGER)+1
;Now, search through the array, halting when the value of TRIGGER is found
SET FLAG=0
SET (I,J)=0
FOR I=1:1:K Q:FLAG  W ! FOR J=1:1:K WRITE A(I,J),$SELECT(J'=K:", ",1:"") SET FLAG=(A(I,J)=TRIGGER) Q:FLAG
KILL A,I,J,K,FLAG,TRIGGER
QUIT</lang>
Output:
USER>D NESTLOOP^ROSETTA
 
16, 4, 6, 20,
USER>D NESTLOOP^ROSETTA
 
9, 10, 10, 13, 2, 9, 6, 10, 1, 12, 12, 10, 8, 1, 13
7, 14, 12, 9, 14, 3, 20,

Nemerle

Translation of: C#

Nemerle can jump out of a named block by invoking the blocks name with an optional return value. <lang Nemerle>using System; using System.Console; using Nemerle.Imperative;

module NestedLoops {

   Main() : void
   {
       def arr = array(10, 10);
       def rnd = Random();
       
       foreach ((i, j) in $[(i, j) | i in [0 .. 9], j in [0 .. 9]])
           arr[i, j] = rnd.Next(1, 21);
           
       Finish:
       {
           foreach ((i, j) in $[(i, j) | i in [0 .. 9], j in [0 .. 9]])
           {
               Write("{0}  ", arr[i, j]);
               when (arr[i, j] == 20) Finish();
           }
       }
   }

}</lang>

NetRexx

<lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols nobinary

 say
 say 'Loops/Nested'
 rnd = Random()
 dim2 = int[10, 10]
 -- build sample data
 loop i1 = 0 for dim2.length
   loop i2 = 0 for dim2[i1].length
     dim2[i1, i2] = rnd.nextInt(20) + 1
     end i2
   end i1
 -- run test
 loop x1 = 0 for dim2.length
   say Rexx(x1 + 1).right(4)': \-' 
   loop x2 = 0 for dim2[x1].length
     say Rexx(dim2[x1, x2]).right(3) || '\-'
     if dim2[x1, x2] = 20 then leave x1
     finally
       say
     end x2
   finally
     say
   end x1</lang>

I was somewhat disappointed by the performance of the above program and started a little performance analysis on solutions of this task for the languages I know.

I created a test program with a 500 + 500 matrix, all elements set to 0 except for the last one, which I set to 20. Then I repeat the search 100 times.

The timings are:

 Seconds elapsed
 3.978      NetRexx as above
 0.032      Netrex with option binary
 7.223      ooRexx with x[i,j]
 6.490      ooRexx with x.i.j
 0.188      PL/I Matrix as coded: FIXED 
 0.058      PL/I Matrix BIN FIXED(15)

Nimrod

<lang nimrod>import math, strutils

const arrSize = 10

var a: array[0..arrSize-1, array[0..arrSize-1, int]] var s: string = ""

randomize() # different results each time this runs

for i in 0 .. arrSize-1:

  for j in countup(0,arrSize-1):
     a[i][j] = random(20)+1

block outer:

  for i in countup(0,arrSize-1):
     for j in 0 .. arrSize-1:
        if a[i][j] < 10:
           s.add(" ")
        addf(s,"$#",$a[i][j])
        if a[i][j] == 20: 
           break outer
        s.add(", ")
     s.add("\n")

echo(s)</lang>

Output:

Output is something like:

 9, 16,  3, 18,  4, 17,  2, 16,  7,  6, 
 1,  6,  1, 11,  9,  8, 12,  7, 19,  8, 
13, 16,  4,  5,  2, 20

OCaml

In the interactive interpreter:

<lang ocaml>$ ocaml

  1. Random.self_init();;

- : unit = ()

  1. let m = Array.make_matrix 10 10 0 ;;

val m : int array array =

 [|[|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|];
   [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|];
   [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|];
   [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|];
   [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]|]
  1. for i = 0 to pred 10 do
   for j = 0 to pred 10 do
     m.(i).(j) <- 1 + Random.int 20
   done;
 done;;

- : unit = ()

  1. try
   for i = 0 to pred 10 do
     for j = 0 to pred 10 do
       Printf.printf " %d" m.(i).(j);
       if m.(i).(j) = 20 then raise Exit;
     done;
     print_newline()
   done;
 with Exit ->
   print_newline()
 ;;
15 8 15 9 9 6 1 18 6 18
17 1 13 15 13 1 16 4 13 9
15 3 5 19 17 3 1 11 5 2
1 1 6 19 20

- : unit = ()</lang>

Octave

Octave has no way of exiting nested loop; so we need a control variable, or we can use the trick of embedding the loops into a function and use the return statement. (The search for "exactly 20" is changed into a search for "almost 20") <lang octave>function search_almost_twenty() % create a 100x100 matrix... m = unifrnd(0,20, 100,100); for i = 1:100

 for j = 1:100
   disp( m(i,j) )
   if ( abs(m(i,j) - 20) < 1e-2 )
     return
   endif
 endfor

endfor endfunction

search_almost_twenty()

% avoiding function, we need a control variable. m = unifrnd(0,20, 100,100); innerloopbreak = false; for i = 1:100

 for j = 1:100
   disp( m(i,j) )
   if ( abs(m(i,j) - 20) < 1e-2 )
     innerloopbreak = true;
     break;
   endif
 endfor
 if ( innerloopbreak )
   break;
 endif

endfor</lang>

OoRexx

<lang oorexx>numbers = .array~new() do i = 1 to 10

   do j = 1 to 10
       numbers[i,j] = random(1, 20)
   end

end

do i = 1 to numbers~dimension(1)

   do j = 1 to numbers~dimension(2)
       say numbers[i,j]
       if numbers[i,j] = 20 then
           leave i
   end

end</lang>

Oz

We can directly access and use the outer loop's break procedure: <lang oz>declare

 fun {CreateMatrix Width Height}
   Matrix = {List.make Height}
 in
   for Row in Matrix do
      Row = {List.make Width}
      for X in Row do
         X = {OS.rand} mod 20 +1
      end
   end
   Matrix
 end
 proc {PrintMatrix Matrix}
   %% print until we see 20
    for Row in Matrix break:OuterBreak do
       for X in Row do
          {Show X}
          if X == 20 then {OuterBreak} end
       end
    end
 end

in

 {PrintMatrix {CreateMatrix 10 10}}</lang>

PARI/GP

<lang parigp>M=matrix(10,10,i,j,random(20)+1); for(i=1,10,for(j=1,10,if(M[i,j]==20,break(2))))</lang>

Perl

<lang perl>my $a = [ map [ map { int(rand(20)) + 1 } 1 .. 10 ], 1 .. 10];

Outer: foreach (@$a) {

   foreach (@$_) {
       print " $_";
       if ($_ == 20) {
           last Outer;
       }
   }
   print "\n";

} print "\n";</lang>

Perl 6

Works with: niecza version 2012-07-29

<lang perl6>my @a := [ (1..20).roll(10) ] xx *;

LINE: for @a -> @line {

   for @line -> $elem {
       print " $elem";
       last LINE if $elem == 20;
   }
   print "\n";

} print "\n";</lang> Rakudo does not implement loop labels yet, but at least we can catch the error of trying to use one: <lang perl6>my @a := [ (1..20).roll(10) ] xx *;

try {

   # LINE:
   for @a -> @line {
       for @line -> $elem {
           print " $elem";
           last LINE if $elem == 20;
       }
       print "\n";
   }

} print "\n";</lang>

Output:
 15 6 14 13 14 7 9 16 8 18
 7 6 18 11 19 13 12 5 18 8
 17 17 9 5 4 8 17 8 3 11
 9 20

PHP

<lang php><?php for ($i = 0; $i < 10; $i++)

   for ($j = 0; $j < 10; $j++)
       $a[$i][$j] = rand(1, 20);

foreach ($a as $row) {

   foreach ($row as $element) {
       echo " $element";
       if ($element == 20)
           break 2; // 2 is the number of loops we want to break out of
   }
   echo "\n";

} echo "\n"; ?></lang>

PicoLisp

<lang PicoLisp>(for Lst (make (do 10 (link (make (do 10 (link (rand 1 20)))))))

  (T
     (for N Lst
        (printsp N)
        (T (= N 20) T) ) ) )</lang>

or: <lang PicoLisp>(catch NIL

  (for Lst (make (do 10 (link (make (do 10 (link (rand 1 20)))))))
     (for N Lst
        (printsp N)
        (and (= N 20) (throw)) ) ) )</lang>

PL/I

<lang PL/I> declare x(20,20) fixed; /* 16 August 2010. */

  x = random()*20 + 1;

loops:

  do i = 1 to hbound(x,1);
     do j = 1 to hbound(x,2);
        put (x(i,j));
        if x(i,j) = 20 then leave loops;
     end;
     if x(i,j) = 20 then leave;
  end;</lang>

PureBasic

<lang PureBasic>; Creating and filling array Dim Value(10, 5) For a = 0 To 10

 For b = 0 To 5
   Value(a, b) = Random(19) + 1
 Next

Next

iterating trough array

For a = 0 To 10

 For b = 0 To 5
   Debug Value(a, b)
   If Value(a, b) = 20
     ; 2 indicates, that there are two nested lopps to break out
     Break 2
   EndIf
 Next

Next</lang>

Python

Python has only inner loop breaks. The normal way to solve this problem in Python is to move the code in a function, and use return: <lang python>from random import randint

def do_scan(mat):

   for row in mat:
       for item in row:
           print item,
           if item == 20:
               print
               return
       print
   print

mat = [[randint(1, 20) for x in xrange(10)] for y in xrange(10)] do_scan(mat)</lang> The , after print element suppresses printing a line break. The code needs some minor changes for Python 3.

Two more solutions around this problem, the first uses exception handling: <lang python>from random import randint

class Found20(Exception):

   pass

mat = [[randint(1, 20) for x in xrange(10)] for y in xrange(10)]

try:

   for row in mat:
       for item in row:
           print item,
           if item == 20:
               raise Found20
       print

except Found20:

   print</lang>

The second uses a flag variable: <lang python>from random import randint

mat = [[randint(1, 20) for x in xrange(10)] for y in xrange(10)]

found20 = False for row in mat:

   for item in row:
       print item,
       if item == 20:
           found20 = True
           break
   print
   if found20:
       break</lang>

Qi

<lang Qi> (define random-list

 0 -> []
 M -> [(1+ (RANDOM 20)) | (random-list (1- M))])

(define random-array

 0 _ -> []
 N M -> [(random-list M) | (random-array (1- N) M)])

(define array->list

 _    []                 -> []                                  \ "end outer loop" \
 Stop [[]          | Ra] -> (array->list Stop Ra)               \ "outer loop" \
 Stop [[Stop | _ ] | _ ] -> []                                  \ "break out from inner loop" \
 Stop [[X    | Rl] | Ra] -> [X | (array->list Stop [Rl | Ra])]) \ "inner loop" \

(array->list 20 (random-array 10 10)) </lang>

R

<lang R>m <- 10 n <- 10 mat <- matrix(sample(1:20L, m*n, replace=TRUE), nrow=m); mat done <- FALSE for(i in seq_len(m)) {

  for(j in seq_len(n))
  {
     cat(mat[i,j])
     if(mat[i,j] == 20)
     {
        done <- TRUE
        break
     } 
     cat(", ")     
  }
  if(done) 
  {
     cat("\n")
     break
  }

}</lang>

or

<lang R> m <- 10; n <- 10; mat <- matrix(sample(1:20L, m*n, replace=TRUE), nrow=m); x<-which(mat==20,arr.ind=TRUE,useNames=FALSE) x<-x[order(x[,1]),] for(i in mat[1:x[1,1]-1,]) print(i) for(i in mat[x[1,1],1:x[1,2]]) print(i) </lang>

Racket

<lang racket>

  1. lang racket

(define (scan xss)

 (for* ([xs xss]
        [x  xs]
        #:final (= x 20))
   (displayln x)))

(define matrix

 (for/list ([x 10])
   (for/list ([y 10])
     (+ (random 20) 1))))

(scan matrix)</lang>

REBOL

<lang REBOL>REBOL [ Title: "Loop/Nested" Author: oofoe Date: 2010-01-05 URL: http://rosettacode.org/wiki/Loop/Nested ]

Number formatting.

zeropad: func [pad n][

   n: to-string n  insert/dup n "0" (pad - length? n)  n]
Initialize random number generator from current time.

random/seed now

Create array and fill with random numbers, range 1..20.

soup: array [10 10] repeat row soup [forall row [row/1: random 20]]

print "Loop break using state variable:" done: no for y 1 10 1 [ for x 1 10 1 [ prin rejoin [zeropad 2 soup/:x/:y " "] if 20 = soup/:x/:y [done: yes break] ] prin crlf if done [break] ]

print [crlf "Loop break with catch/throw:"] catch [ for y 1 10 1 [ for x 1 10 1 [ prin rejoin [zeropad 2 soup/:x/:y " "] if 20 = soup/:x/:y [throw 'done] ] prin crlf ] ] prin crlf</lang>

Output:
Loop break using state variable:
15 09 11 03 17 07 09 16 03 07
03 15 04 06 13 05 10 06 02 14
17 05 06 12 03 19 03 03 17 04
17 15 14 17 15 07 06 16 13 11
02 08 12 16 04 14 03 19 02 02
02 13 14 14 15 01 10 07 17 03
07 17 20

Loop break with catch/throw:
15 09 11 03 17 07 09 16 03 07
03 15 04 06 13 05 10 06 02 14
17 05 06 12 03 19 03 03 17 04
17 15 14 17 15 07 06 16 13 11
02 08 12 16 04 14 03 19 02 02
02 13 14 14 15 01 10 07 17 03
07 17 20

REXX

Since the two-dimensional array could potentially not be large enough to contain the target (20), it's possible to not find the target.
Code was added to this REXX program to reflect that possibility and issue an appropriate message (whether the target was found or not). <lang rexx>/*REXX program loops through a 2-dimensional array to look for a '20'. */ parse arg rows cols targ . /*obtain optional args from C.L. */ if rows== | rows==',' then rows=60 /*Rows not specified? Use default*/ if cols== | cols==',' then cols=10 /*Cols " " " " */ if targ== | targ==',' then targ=20 /*Targ " " " " */ w=max(length(rows),length(cols),length(targ)) /*for formatting output.*/ not='not' /* [↓] construct the 2-dim array.*/

         do     row=1  for rows       /*1st dimension of the array.    */
             do col=1  for cols       /*2nd     "      "  "    "       */
             @.row.col=random(1,targ) /*generate some random numbers.  */
             end   /*row*/
         end       /*col*/

/*═════════════════════════════════════now, search for the target {20}.*/

         do     r=1  for rows
             do c=1  for cols
             say left('@.'r"."c,3+w+w) '=' right(@.r.c,w)    /*display.*/
             if @.r.c==targ  then do; not=; leave r; end     /*found ? */
             end   /*c*/
         end       /*r*/

say right(space('Target' not 'found:') targ, 33, '─')

                                      /*stick a fork in it, we're done.*/</lang>

output when using the defaults:

@.1.1   = 19
@.1.2   = 14
@.1.3   = 16
@.1.4   =  8
@.1.5   =  1
@.1.6   =  4
@.1.7   = 11
@.1.8   =  7
@.1.9   = 15
@.1.10  = 16
@.2.1   = 11
@.2.2   =  4
@.2.3   =  3
@.2.4   =  6
@.2.5   = 18
@.2.6   =  7
@.2.7   =  5
@.2.8   =  7
@.2.9   =  2
@.2.10  =  7
@.3.1   = 20
─────────────────Found target: 20

output when using the input of:   2 2

@.1.1   = 14
@.1.2   =  6
@.2.1   = 13
@.2.2   = 13
─────────────Target not found: 20

Ruby

As the break command only jumps out of the innermost loop, this task requires Ruby's catch/throw functionality. <lang ruby>srand ary = (1..20).to_a.shuffle.each_slice(4).to_a p ary

catch :found_it do

 for row in ary
   for element in row
     print "%2d " % element
     throw :found_it if element == 20
   end
   puts ","
 end

end

puts "done"</lang>

Output:
[[2, 12, 10, 4], [18, 11, 9, 3], [14, 15, 7, 17], [6, 19, 8, 13], [1, 20, 16, 5]]
 2 12 10  4 ,
18 11  9  3 ,
14 15  7 17 ,
 6 19  8 13 ,
 1 20 done

Run BASIC

<lang runbasic>dim a(10,10) cls for row = 1 TO 10

       for col = 1 TO 10
               a(row,col) = INT(20 * RND(1) + 1)
       next col

next row

for row = 1 to 10

       for col = 1 to 10
              print a(row, col)
               if a(row, col) = 20 then goto [end]
       next col

next row [end] print "At row:";row;" col:";col</lang>


Rust

<lang rust>// rust 0.9-pre

use std::rand::Rng;

fn main() {

   let mut matrix = [[0u8, .. 10], .. 10];
   let mut rng = std::rand::os::OSRng::new();
   for row in matrix.mut_iter() {
       for item in row.mut_iter() {
           *item = rng.gen_range(0u8, 21);
       }
   }
   'outer:
   for row in matrix.iter() {
       for &item in row.iter() {
           print!("{:2} ", item);
           if item == 20 { break 'outer; }
       }
       println!("");
   }

}</lang> Sample output:

 5  3  8 18 13  2  5 13  6 17
 5 14 20

Sather

<lang sather>class MAIN is

 main is
   a:ARRAY2{INT} := #(10,10);
   i, j :INT;
   
   RND::seed(1230);
   loop i := 0.upto!(9);
     loop j := 0.upto!(9);
        a[i, j] := RND::int(1, 20);
     end;
   end;
   loopthis ::= true;
   loop i := 0.upto!(9); while!( loopthis );
     loop j := 0.upto!(9);
       #OUT  + " " + a[i, j];
       if a[i, j] = 20 then

loopthis := false; break!; end;

     end;
   end;
 end;

end;</lang>

Scala

In Scala there is no build-in 'break' keyword. That functionality comes from a library. <lang scala>import scala.util.control.Breaks._ val a=Array.fill(5,4)(scala.util.Random.nextInt(21)) println(a map (_.mkString("[", ", ", "]")) mkString "\n") breakable {

 for(row <- a; x <- row){
   println(x)
   if (x==20) break
 }

}</lang> Sample output:

[14, 16, 5, 7]
[0, 15, 13, 20]
[0, 3, 8, 17]
[4, 20, 2, 2]
[12, 6, 11, 15]
14
16
5
7
0
15
13
20

Scheme

Using call/cc: <lang scheme>(call-with-current-continuation

(lambda (return)
  (for-each (lambda (a)

(for-each (lambda (b) (cond ((= 20 b) (newline) (return)) (else (display " ")(display b)))) a) (newline)) array)))</lang> Using tail-call: <lang scheme>(let loop ((a array))

 (if (pair? a)
     (let loop2 ((b (car a)))

(cond ((null? b) (newline) (loop (cdr a))) ((= 20 (car b)) (newline)) (else (display " ")(display (car b)) (loop2 (cdr b)))))))</lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

const proc: main is func

 local
   var integer: i is 0;
   var integer: j is 0;
   var array array integer: a is 10 times 10 times 0;
   const EXCEPTION: FOUND20 is enumlit;
 begin
   for i range 1 to 10 do
     for j range 1 to 10 do
       a[i][j] := rand(1, 20);
     end for;
   end for;
   block
     for i range 1 to 10 do
       for j range 1 to 10 do
         write(a[i][j] lpad 2 <& ", ");
         if a[i][j] = 20 then
           raise FOUND20;
         end if;
       end for;
       writeln;
     end for;
   exception
     catch FOUND20: writeln;
   end block;
 end func;</lang>
Output:
15, 10,  5,  9, 10, 13,  1,  9, 11, 10, 
 5,  6, 10, 13,  4, 13, 11, 12,  2,  4, 
 4, 16, 20, 

Sidef

<lang ruby>var arr = 10.of{ 10.of{ 20.rand.int + 1 } };

for arr { |row|

   for row { |num|
       "%3d".printf(num);
       num == 20 && break(2);
   };
   print "\n";

}

print "\n";</lang>

Output:
  9 17 14 17 17  7  1  3  9 18
  1 12  1 19  9  5  1 17 19  3
 17  2 18 12 15 10  8 13 13 14
 12 16 13 13  2 11  3 15  2  4
 15 15  8 11  5  2  1 16  8 13
 17  3  1  1  8 12  4 20

Smalltalk

Notice that the original answer (see below) was wrong (never say never say never...).

Works with: Smalltalk/X

it looks a bit wierd, but here is: loopWithExit

<lang smalltalk>|i|

i := 1. [:exit |

   Transcript showCR:i.
   i == 5 ifTrue:[ exit value:'stopped' ].
   i := i + 1.

] loopWithExit</lang> these can also be nested, and exited from the inner loop: <lang smalltalk>|i|

i := 1. [:exit1 |

   |j|
   j := 0.
   [:exit2 |
       Transcript showCR:('i is %1 / j is %2' bindWith:i with:j).
       j == 5 ifTrue:[ exit2 value: nil ].
       i == 5 ifTrue:[ exit1 value: nil ].
       j := j + 1.
   ] loopWithExit.
   i := i + 1

] loopWithExit</lang> in case your smalltalk does not have it, here's the definition: <lang smalltalk>!Block methodsFor:'looping'! loopWithExit

   "the receiver must be a block of one argument.  It is evaluated in a loop forever, 
    and is passed a block, which, if sent a value:-message, will exit the receiver block, 
    returning the parameter of the value:-message. Used for loops with exit in the middle."
   |exitBlock|
   exitBlock := [:exitValue | ^ exitValue].
   [true] whileTrue:[ self value:exitBlock ]</lang>

in the same spirit, exits could be added to many other loop constructs. However, this is really only very rarely needed in Smalltalk, because a ^(return) out of a block returns from the enclosing method which usually used to exit early from search utility methods.

There is also valueWithExit, which can be used to get out of a block early and provide an alternative value. Using that, the tasks solution is: <lang smalltalk>|v result|

v := 1 to:20 collect:[:i |

       1 to:20 collect:[:j | Random nextIntegerBetween:1 and:20 ]
    ].

result :=

   [:exit |
       1 to:20 do:[:row |
           1 to:20 do:[:col |
               |element|
               (element := (v at:row) at:col) printCR.
               element == 20 ifTrue:[ exit value:(row @ col) ].
           ]
       ].
       nil
   ] valueWithExit.

result isNil ifTrue:[

   'ouch - no 20 found' printCR.

] ifFalse:[

   '20 found at ' print. result printCR

]</lang> Output:

19
6
1
7
12
20
20 found at 1@6


Works with: GNU Smalltalk

Smalltalk has no ways of escaping from loops (single or nested), even if it is possible to extend its iteration capabilities in several ways.

The following code implements a BiArray class with a method that allows iteration over the elements (by columns and then by rows) and execution of a block if a condition is true. <lang smalltalk>"this simple implementation of a bidimensional array

lacks controls over the indexes, but has a way of iterating
over array's elements, from left to right and top to bottom"

Object subclass: BiArray [

 |cols rows elements|
 BiArray class >> columns: columns  rows: howManyRows [ 
     ^ super basicNew init: columns per: howManyRows
 ]
 init: columns per: howManyRows [
    cols := columns.
    rows := howManyRows.
    elements := Array new: ( columns * howManyRows )
 ]
 calcIndex: biIndex [ "column, row (x,y) to linear"
   ^ ( (biIndex at: 1) + (((biIndex at: 2) - 1) * cols) )
 ]
 at: biIndex [ "biIndex is an indexable containing column row"
    ^ elements at: (self calcIndex: biIndex).
 ]
 directAt: i [ ^ elements at: i ]
 at: biIndex put: anObject [
    elements at: (self calcIndex: biIndex) put: anObject
 ]
 whileTrue: aBlock do: anotherBlock [
    |i lim|
    i := 1. lim := rows * cols.
    [ ( i <= lim )
        & (aBlock value: (self directAt: i) )
    ] whileTrue: [ 
        anotherBlock value: (self directAt: i).
        i := i + 1.
      ]
 ]

].

|biarr| biarr := BiArray columns: 10 rows: 10.

"fill the array; this illustrates nested loop but not how to

escape from them"

1 to: 10 do: [ :c |

 1 to: 10 do: [ :r |
    biarr at: {c . r} put: (Random between: 1 and: 20)
 ]

].

"loop searching for 20; each block gets the element passed as argument" biarr whileTrue: [ :v | v ~= 20 ]

     do: [ :v | v displayNl ]</lang>

Tcl

Tcl only supports single-level breaks; exiting more deeply nested looping requires the use of exceptions, which are considerably more verbose before Tcl 8.6.

Works with: Tcl version 8.6

<lang tcl>set ary [subst [lrepeat 10 [lrepeat 5 {[expr int(rand()*20+1)]}]]]

try {

   foreach row $ary {
       foreach col $row {
           puts -nonewline [format %3s $col]
           if {$col == 20} {
               throw MULTIBREAK "we're done"
           }
       }
       puts ,
   }

} trap MULTIBREAK {} {} puts " done"</lang> Sample output:

 12 13 14 13 15,
  1 14  7 16  3,
 12 11  5  1  9,
 12  5  1  4  2,
  6 11 11  4 11,
  7 14 20 done

TI-89 BASIC

The Stop statement exits the containing program. <lang ti89b>Prgm

 Local mat,i,j
 © randMat(5, 5) exists but returns -9 to 9 rather than 1 to 20
 newMat(5, 5) → mat
 For i,1,rowDim(mat)
   For j,1,colDim(mat)
     rand(20) → mat[i,j]
   EndFor
 EndFor
 Disp mat
 Pause "Press a key."
 ClrIO
 For i,1,rowDim(mat)
   For j,1,colDim(mat)
     If mat[i,j] = 20 Then
       Stop
     Else
       Output i*8, j*18, mat[i,j]
     EndIf
   EndFor
 EndFor

EndPrgm</lang>

TUSCRIPT

<lang tuscript>$$ MODE TUSCRIPT LOOP row=""

LOOP/CLEAR x=1,10
x=RANDOM_NUMBERS (1,20,1)
row=APPEND(row," ",x)
 IF (x==20) THEN
  PRINT row
  EXIT,EXIT
 ENDIF
ENDLOOP
PRINT row

ENDLOOP</lang>

Output:
9 6 6 5 10 18 11 17 17 9
5 16 2 4 2 15 13 13 4 9
12 4 6 19 3 1 3 12 13 8
3 7 4 8 15 12 1 20 

UNIX Shell

Works with: Bash

Bash doesn't have two-dimentional arrays, so we fake it for this example <lang bash>size=10

for ((i=0;i<size;i++)); do

 unset t[@]
 for ((j=0;j<size;j++)); do
   t[$j]=$((RANDOM%20+1))
 done
 a[$i]="${t[*]}"

done

for ((i=0;i<size;i++)); do

 t=(${a[$i]})
 for ((j=0;j<size;j++)); do
   printf "%2d " ${t[$j]}
   [ ${t[$j]} -eq 20 ] && break 2
 done
 echo

done echo</lang>

Example output:
 7  5  4  6  4  5  2 15 10  7 
15  4 14  9 10 14 14  3  3  5 
14 20 

XPL0

<lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations def Size=10;

proc Nest(A); \Display 2-dimensional array A contents until 20 is found int A; int I, J, K; [for J:= 0 to Size-1 do

   for I:= 0 to Size-1 do
       [K:= A(I,J);
       IntOut(0, K);  ChOut(0, ^ );
       if K = 20 then return;          \there is no 'goto' instruction
       ];

]; \Nest

proc Fill(A); \Fill 2-dimensional array A with random numbers 1..20 int A; int I, J; [for J:= 0 to Size-1 do

   for I:= 0 to Size-1 do
       A(I,J):= Ran(20)+1;

]; \Fill

int Array(Size,Size); [Fill(Array);

Nest(Array);

]</lang>

zkl

Using nested lists to simulate a 5x5 array. No breakbreak so an exception is used to long jump out of the loop (just 'cause, a state var could also be used). <lang zkl>const N=5; var rows=(0).pump(N,List, (0).pump.fp(N,List,(1).random.fpM("1-",21)) ); try{

  foreach r in (N){
     foreach c in (N){ 
        x:=rows[r][c]; x.print(",");
        if (x==20) { println("Found it!"); throw(Exception.Generic); }
     }
  }
  println("Not found");

}catch(Generic){}</lang>

Output:
14,13,17,11,11,3,15,20,Found it!
3,2,10,14,10,2,2,15,2,13,11,5,12,4,17,8,10,5,14,11,10,14,11,4,1,Not found

ZX Spectrum Basic

<lang zxbasic>10 DIM a(10,10) 20 FOR i=1 TO 10: FOR j=1 TO 10 30 LET a(i,j)=INT (RND*20)+1 40 NEXT j: NEXT i 50 LET b=0: REM flag to abort loops 60 FOR i=1 TO 10: FOR j=1 TO 10 70 PRINT (" " AND a(i,j)<10);a(i,j);" "; 80 IF a(i,j)=20 THEN LET i=10: LET j=10: LET b=1: REM abort loops 90 NEXT j 100 IF b=0 THEN PRINT 110 NEXT i 120 STOP </lang>

Example output:
16  7  8  6 14  8 12 14 12  9
 7  9 14  8 18 17  3 16  1 19
 5 13  7 11 13 14  4  7 19 14
20