Loops/Break

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

Show a loop which prints random numbers (each number newly generated each loop) from 0 to 19 (inclusive). If a number is 10, stop the loop after printing it, and do not generate any further numbers. Otherwise, generate and print a second random number before restarting the loop. If the number 10 is never generated as the first number in a loop, loop forever.

Ada

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

procedure Test_Loop_Break 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, B : Value_Type;

begin

  loop
     A := Random (Dice);
     Put_Line (Value_Type'Image (A));
     exit when A = 10;
     B := Random (Dice);
     Put_Line (Value_Type'Image (B));
  end loop;

end Test_Loop_Break;</lang>

AutoHotkey

<lang AutoHotkey>Loop {

 Random, var, 0, 19
 output = %output%`n%var%
 If (var = 10)
   Break
 Random, var, 0, 19
 output = %output%`n%var%

} MsgBox % output</lang>

BASIC

Works with: QuickBasic version 4.5

<lang qbasic>do

   a = int(rnd * 20)
   print a
   if a = 10 then exit loop 'EXIT FOR works the same inside FOR loops
   b = int(rnd * 20)
   print b

loop</lang>

C

<lang c>#include <stdlib.h>

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

int main() {

   int a, b;
   srand(time(NULL));
   while (1) {
       a = rand() % 20; /* not exactly uniformly distributed, but doesn't matter */
       printf("%d\n", a);
       if (a == 10) break;
       b = rand() % 20; /* not exactly uniformly distributed, but doesn't matter */
       printf("%d\n", b);
   }
   return 0;

}</lang>

C#

<lang csharp>class Program {

   static void Main(string[] args)
   {
       Random random = new Random();
       while (true)
       {
           int a = random.Next(20);
           Console.WriteLine(a);
           if (a == 10)
               break;
           int b = random.Next(20)
           Console.WriteLine(b);
       }
          
       Console.ReadLine();
   }       

}</lang>

Chef

"Liquify" is now depreciated in favor of "Liquefy", but my interpreter/compiler (Acme::Chef) works only with "Liquify" so that's how I'm leaving it. At least it'll work no matter which version you use.

<lang Chef>Healthy Vita-Sauce Loop - Broken.

Makes a whole lot of sauce for two people.

Ingredients. 0 g Vitamin A 1 g Vitamin B 2 g Vitamin C 3 g Vitamin D 4 g Vitamin E 5 g Vitamin F 6 g Vitamin G 7 g Vitamin H 8 g Vitamin I 9 g Vitamin J 10 g Vitamin K 11 g Vitamin L 12 g Vitamin M 13 g Vitamin N 14 g Vitamin O 15 g Vitamin P 16 g Vitamin Q 17 g Vitamin R 18 g Vitamin S 19 g Vitamin T 20 g Vitamin U 21 g Vitamin V 22 g Vitamin W 32 g Vitamin X 24 g Vitamin Y 25 g Vitamin Z

Method. Liquify Vitamin X. Put Vitamin N into 1st mixing bowl. Fold Vitamin Y into 1st mixing bowl. Liquify Vitamin Y. Clean 1st mixing bowl. Put Vitamin K into 1st mixing bowl. Fold Vitamin Z into 1st mixing bowl. Liquify Vitamin Z. Clean 1st mixing bowl. Put Vitamin Y into 4th mixing bowl. Put Vitamin Z into 4th mixing bowl. Pour contents of the 4th mixing bowl into the 2nd baking dish. Put Vitamin A into 2nd mixing bowl. Put Vitamin B into 2nd mixing bowl. Put Vitamin C into 2nd mixing bowl. Put Vitamin D into 2nd mixing bowl. Put Vitamin E into 2nd mixing bowl. Put Vitamin F into 2nd mixing bowl. Put Vitamin G into 2nd mixing bowl. Put Vitamin H into 2nd mixing bowl. Put Vitamin I into 2nd mixing bowl. Put Vitamin J into 2nd mixing bowl. Put Vitamin K into 2nd mixing bowl. Put Vitamin L into 2nd mixing bowl. Put Vitamin M into 2nd mixing bowl. Put Vitamin N into 2nd mixing bowl. Put Vitamin O into 2nd mixing bowl. Put Vitamin P into 2nd mixing bowl. Put Vitamin Q into 2nd mixing bowl. Put Vitamin R into 2nd mixing bowl. Put Vitamin S into 2nd mixing bowl. Put Vitamin T into 2nd mixing bowl. Verb the Vitamin V. Mix the 2nd mixing bowl well. Fold Vitamin U into 2nd mixing bowl. Put Vitamin U into 3rd mixing bowl. Remove Vitamin K from 3rd mixing bowl. Fold Vitamin V into 3rd mixing bowl. Put Vitamin X into 1st mixing bowl. Put Vitamin V into 1st mixing bowl. Verb until verbed. Pour contents of the 1st mixing bowl into the 1st baking dish.

Serves 2.</lang>

Clojure

<lang lisp>(loop [[a b & more] (repeatedly #(rand-int 20))]

 (println a)
 (when-not (= 10 a) 
   (println b) 
   (recur more)))</lang>

Common Lisp

<lang lisp>(loop

   (setq a (random 20))
   (print a)
   (if (= a 10)
       (return))
   (setq b (random 20))
   (print b))</lang>

D

Works with: Tango

Using Mersenne twister;

<lang D>import tango.io.Stdout; import tango.math.random.Twister;

void main() {

   alias Twister.instance r;
   uint x;
   while (~1) {
       x = r.natural(20);
       Stdout (x) (" ");
       if (x == 10) break;
       Stdout (r.natural(20)).newline;
   }

}</lang>

E

<lang e>while (true) {

   def a := entropy.nextInt(20)
   print(a)
   if (a == 10) {
       println()
       break
   }
   println(" ", entropy.nextInt(20))

}</lang>

Factor

Using with-return: <lang factor>[

   [ 20 random [ . ] [ 10 = [ return ] when ] bi 20 random . t ] loop

] with-return</lang>

Idiomatic Factor: <lang factor>[ 20 random [ . ] [ 10 = not ] bi 20 random . ] loop</lang>

Forth

<lang forth>include random.fs

main
 begin  20 random dup . 10 <>
 while  20 random .
 repeat ;

\ use LEAVE to break out of a counted loop

main
 100 0 do
   i random dup .
   10 = if leave then
   i random .
 loop ;</lang>

Fortran

Works with: Fortran version 90 and later

<lang fortran>program Example

 implicit none
 real :: r
 integer :: a, b
 do
    call random_number(r)
    a = int(r * 20)
    write(*,*) a
    if (a == 10) exit
    call random_number(r)
    b = int(r * 20)
    write(*,*) b
 end do

end program Example</lang>

Haskell

<lang haskell>import Control.Monad import System.Random

loopBreak n k = do

 r <- randomRIO (0,n)
 print r
 unless (r==k) $ do
   print =<< randomRIO (0,n)
   loopBreak n k</lang>

Use: <lang haskell>loopBreak 19 10</lang>

HicEst

<lang hicest>1 DO i = 1, 1E20 ! "forever"

    a = INT( RAN(10, 10) )
    WRITE(name) a
    IF( a == 10) GOTO 10
    b = INT( RAN(10, 10) )
    WRITE(name) b
  ENDDO

10

END</lang>

Icon

<lang Icon>procedure main()

   while 10 ~= writes(?20-1) do write(", ",?20-1)

end</lang> Notes:

  • For any positive integer i, ?i produces a value j where 1 <= j <= i
  • Although this can be written with a break (e.g. repeat expression & break), there is no need to actually use one. (And it's ugly).
  • Programmers new to Icon/Unicon need to understand that just about everything returns values including comparison operators, I/O functions like write/writes.
  • This program will perform similarly but not identically under Icon and Unicon because the random operator ?i behaves differently. While both produce pseudo-random numbers a different generator is used. Also, the sequence produced by Icon begins with the same seed value and is repeatable whereas the sequence produced by Unicon does not.

J

<lang j>loopexample=: verb define

 while. 1 do.
   smoutput n=. ?20
   if. 10=n do.return.end.
   smoutput ?20
 end.

)</lang>

Java

<lang java>import java.util.Random;

Random rand = new Random(); while(true){

   int a = rand.nextInt(20);
   System.out.println(a);
   if(a == 10) break;
   int b = rand.nextInt(20);
   System.out.println(b);

}</lang>

JavaScript

<lang javascript>for (;;) {

 var a = Math.floor(Math.random() * 20);
 print(a);
 if (a == 10) 
   break;
 a = Math.floor(Math.random() * 20);
 print(a);

}</lang> The print() function is available in the Rhino JavaScript shell.

Lisaac

<lang Lisaac>Section Header

+ name := TEST_LOOP_BREAK;

Section Public

- main <- (

 + a, b : INTEGER;
 `srand(time(NULL))`;
 {
   a := `rand()`:INTEGER % 20; // not exactly uniformly distributed, but doesn't matter
   a.print;
   '\n'.print;
   a == 10
 }.until_do {
   b := `rand()`:INTEGER % 20; // not exactly uniformly distributed, but doesn't matter
   b.print;
   '\n'.print;
 }

);</lang>

Lua

<lang lua>repeat

 k = math.random(19)
 print(k)
 if k == 10 then break end
 print(math.random(19)

until false</lang>

M4

<lang M4>define(`randSeed',141592653)dnl define(`setRand',

  `define(`randSeed',ifelse(eval($1<10000),1,`eval(20000-$1)',`$1'))')dnl

define(`rand_t',`eval(randSeed^(randSeed>>13))')dnl define(`random',

  `define(`randSeed',eval((rand_t^(rand_t<<18))&0x7fffffff))randSeed')dnl

dnl define(`loopbreak',`define(`a',eval(random%20))`a='a ifelse(a,10,`',`define(`b',eval(random%20))`b='b loopbreak')')dnl dnl loopbreak</lang>

Output:

a=17
b=3
a=0
b=15
a=10

Modula-3

<lang modula3>MODULE Break EXPORTS Main;

IMPORT IO, Fmt, Random;

VAR a,b: INTEGER;

BEGIN

 WITH rand = NEW(Random.Default).init() DO
   LOOP
     a := rand.integer(min := 0, max := 19);
     IO.Put(Fmt.Int(a) & "\n");
     IF a = 10 THEN EXIT END;
     b := rand.integer(min := 0, max := 19);
     IO.Put(Fmt.Int(b) & "\n");
   END;
 END;

END Break.</lang>

MOO

<lang moo>while (1)

 a = random(20) - 1;
 player:tell(a);
 if (a == 10)
   break;
 endif
 b = random(20) - 1;
 player:tell(b);

endwhile</lang>

OCaml

<lang ocaml># Random.self_init();; - : unit = ()

  1. while true do
   let a = Random.int 20 in
   print_int a;
   print_newline();
   if a = 10 then raise Exit;
   let b = Random.int 20 in
   print_int b;
   print_newline()
 done;;

15 18 2 13 10 Exception: Pervasives.Exit.</lang>

Octave

<lang octave>while(1)

 a = floor(unifrnd(0,20, 1));
 disp(a)
 if ( a == 10 )
   break
 endif
 b = floor(unifrnd(0,20, 1));
 disp(b)

endwhile</lang>

Oz

We can implement this either with recursion or with a special type of the for-loop. Both can be considered idiomatic. <lang oz>for break:Break do

  R = {OS.rand} mod 20

in

  {Show R}
  if R == 10 then {Break}
  else {Show {OS.rand} mod 20}
  end

end</lang>

Perl

<lang perl>while (1) {

   my $a = int(rand(20));
   print "$a\n";
   if ($a == 10) {
       last;
   }
   my $b = int(rand(20));
   print "$b\n";

}</lang>

Perl 6

Works with: Rakudo version #21 "Seattle"

<lang perl6>loop {

   my $n = (0..19).pick;
   say $n;
   last if $n == 10;
   say (0..19).pick;

}</lang>

PHP

<lang php>while (true) {

   $a = rand(0,19);
   echo "$a\n";
   if ($a == 10)
       break;
   $b = rand(0,19);
   echo "$b\n";

}</lang>

PicoLisp

Literally: <lang PicoLisp>(use R

  (loop
     (println (setq R (rand 1 19)))
     (T (= 10 R))
     (println (rand 1 19)) ) )</lang>

Shorter: <lang PicoLisp>(until (= 10 (println (rand 1 19)))

  (println (rand 1 19)) )</lang>

PL/I

<lang PL/I> do forever;

  k = random()*19;
  put (k);
  if k = 10 then leave;
  k = random()*19;
  put skip list (k);

end; </lang>

Pike

<lang pike>int main(){

  while(1){
     int a = random(20);
     write(a + "\n");
     if(a == 10){
        break;
     }
     int b = random(20);
     write(b + "\n");
  }

}</lang>

PowerShell

<lang powershell>$r = New-Object Random for () {

   $n = $r.Next(20)
   Write-Host $n
   if ($n -eq 10) {
       break
   }
   Write-Host $r.Next(20)

}</lang>

PureBasic

<lang PureBasic>If OpenConsole()

 Repeat
   a = Random(19)
   PrintN(Str(a))
   If a = 10
     Break
   EndIf 
   b = Random(19)
   PrintN(Str(b))
   PrintN("")
 ForEver
 Print(#CRLF$ + #CRLF$ + "Press ENTER to exit")
 Input()
 CloseConsole()

EndIf</lang>

Python

<lang python>import random

while True:

   a = random.randrange(20)
   print a
   if a == 10:
       break
   b = random.randrange(20)
   print b</lang>

R

Works with: R version 2.8.1

<lang R>sample0to19 <- function() sample(0L:19L, 1,replace=TRUE) repeat {

 result1 <- sample0to19()
 if (result1 == 10L)
 {
   print(result1)
   break
 }
 result2 <- sample0to19()
 cat(result1, result2, "\n")

}</lang>

REBOL

<lang REBOL>REBOL [ Title: "Loop/Break" Author: oofoe Date: 2009-12-19 URL: http://rosettacode.org/wiki/Loop/Break ]

random/seed 1 ; Make repeatable.

random/seed now ; Uncomment for 'true' randomness.

r20: does [(random 20) - 1]

forever [ prin x: r20 if 10 = x [break] print rejoin [" " r20] ] print ""</lang>

Output:

14 11
19 15
6 11
12 11
3 14
10

REXX

<lang rexx>do forever

 a = random(19)
 say a
 if a = 10 then leave
 b = random(19)
 say b

end</lang>


Ruby

<lang ruby>loop do

   a = rand(20)
   puts a
   if a == 10
       break
   end
   b = rand(20)
   puts b

end</lang>

Scala

Works with: Scala version 2.7

A break library method is available in Scala 2.8 but not 2.7

<lang Scala> import scala.util.Random

val rand = new Random var doNext = true


while(doNext) {

 val first = rand.nextInt(20)
 println(first)
 if (first != 10) {
   val second = rand.nextInt(20)
   println(second)
 } else {
   doNext = false
 }

} </lang>

Suneido

<lang Suneido>forever

   {
   Print(i = Random(20))
   if i is 10
       break
   Print(i = Random(20))
   }

</lang>

TI-89 BASIC

<lang ti89b>Local x Loop

 rand(20)-1 → x
 Disp x                     © new line and text
 If x = 10 Then
   Exit
 EndIf
 Output 64, 50, rand(20)-1  © paint text to the right on same line

EndLoop</lang>

Tcl

<lang tcl>while true {

   set a [expr int(20*rand())]
   puts $a
   if {$a == 10} {
       break
   }
   set b [expr int(20*rand())]
   puts $b

}</lang>

Unicon

See Icon.

VBScript

Implementation

Based on BASIC version. Demonstrates breaking out of do/loop and for/next (Exit is good for getting out of functions and subs as well)

<lang vb> do a = int( rnd * 20) wscript.stdout.write a if a = 10 then exit do b = int( rnd * 20 ) wscript.echo vbnullstring,b loop

dim i for i = 1 to 100000 a = int( rnd * 20) wscript.stdout.write a if a = 10 then exit for b = int( rnd * 20 ) wscript.echo vbnullstring,b next </lang>