Loops/Nested: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 288: Line 288:


The , after print element suppresses printing a line break. The above has been programmed on Python 2.6; I assume it also works on other Python 2.x versions, but it needs some minor changes in Python 3.
The , after print element suppresses printing a line break. The above has been programmed on Python 2.6; I assume it also works on other Python 2.x versions, but it needs some minor changes in Python 3.

But the normal way to solve this problem in Python is to use a return inside a function:
<lang python>from random import randint

def do_scan(m):
for row in m:
for item in row:
print item,
if item == 20:
print
return
print

m = [[randint(1, 20) for x in xrange(10)] for y in xrange(10)]
do_scan(m)</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==

Revision as of 11:28, 23 June 2009

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>

D

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

void main() {

   int[10][10] m;
   foreach (ref row; m)
       foreach (ref item; row)
           item = rand % 20 + 1;
   outer:
   foreach (row; m)
       foreach (item; row) {
           writef(item, ' ');
           if (item == 20)
               break outer;
       }
   writefln;

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

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

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>

Python

Python has only inner loop breaks. Below are two solutions around this problem, the first uses exception handling:

<lang python> import random class Found20(Exception):

   pass

number_array = [[random.randrange(1,21) for x in xrange(10)] for y in xrange(10)]

try:

   for row in number_array:
       for element in row:
           print element,
           if element == 20:
               raise Found20
       print

except Found20:

   print

</lang>

The second uses a flag variable:

<lang python> import random

number_array = [[random.randrange(1,21) for x in xrange(10)] for y in xrange(10)] found20 = False

for row in number_array:

   for element in row:
       print element,
       if element == 20:
           found20 = True
           break
   print
   if found20:
       break

</lang>

The , after print element suppresses printing a line break. The above has been programmed on Python 2.6; I assume it also works on other Python 2.x versions, but it needs some minor changes in Python 3.

But the normal way to solve this problem in Python is to use a return inside a function: <lang python>from random import randint

def do_scan(m):

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

m = [[randint(1, 20) for x in xrange(10)] for y in xrange(10)] do_scan(m)</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