Loops/Nested

From Rosetta Code
Revision as of 17:53, 18 June 2009 by rosettacode>Glennj (→‎{{header|Ruby}}: improve wording of intro)
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 two-dimensional array filled with random number uniformly distributed on [1..20]. The loops iterate rows and columns of the array printing the iterated elements of, until the value 20 is met.

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

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>

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>

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>

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 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 

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;
           }
           System.out.println();
       }
       System.out.println();
   }

}</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>

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>

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>

[[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

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