Loop/n plus one half

From Rosetta Code

Jump to: navigation, search

Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.

Code examples should be formatted along the lines of one of the existing prototypes.

Quite often one needs loops which are run "n+1/2" times, i.e. in the last iteration one executes only part of the loop body. The goal of this task is to demonstrate the best way to do this.

Write a loop which writes the comma-separated list

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

using separate output statements for the number and the comma.

Contents

[edit] Ada

 
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
 
procedure Loop_And_Half is
   I : Positive := 1;
begin
   loop
      Put(Item => I, Width => 1);
      exit when I = 10;
      Put(", ");
      I := I + 1;
   end loop;
   New_Line;
end Loop_And_Half;
 

[edit] ALGOL 68

main:(
  FOR i FROM 1 WHILE
    print(i);
# WHILE # i < 10 DO
    print(", ")
  OD;
  print(new line)
)

[edit] BASIC

Works with: FreeBASIC version 0.20

Works with: RapidQ

 
DIM i AS INTEGER
 
FOR i=1 TO 10
    PRINT i;
    IF i=10 THEN EXIT FOR
    PRINT ", ";
NEXT i
 


[edit] C++

 
#include <iostream>
 
int main()
{
  for (int i = 1; ; i++)
  {
    std::cout << i;
    if (i == 10)
      break;
    std::cout << ", ";
  }
  std::cout << std::endl;
  return 0;
}

[edit] ColdFusion

With tags:

<cfloop index = "i" from = "1" to = "10">
  #i#
  <cfif i EQ 10>
    <cfbreak />
  </cfif>
  , 
</cfloop>

With script:

<cfscript>
  for( i = 1; i <= 10; i++ )
  {
    writeOutput( i );
    
    if( i == 10 )
    {
      break;
    }
    writeOutput( ", " );
  }
</cfscript>

[edit] D

for (int i = 1; ; i++) {
  writef(i);
  if (i == 10) break;
  writef(", ");
}
writefln();

[edit] E

A typical loop+break solution:

var i := 1
while (true) {
    print(i)
    if (i >= 10) { break }
    print(", ")
    i += 1
}

Using the loop primitive in a semi-functional style:

var i := 1
__loop(fn {
    print(i)
    if (i >= 10) {
        false
    } else {
        print(", ")
        i += 1
        true 
    }
})


[edit] Forth

: comma-list ( n -- )
  dup 1 ?do  i 1 .r ." , " loop
  . ;
: comma-list ( n -- )
  dup 1+ 1 do
    i 1 .r
    dup i = if leave then   \ or DROP UNLOOP EXIT to exit loop and the function
    [char] , emit space
  loop drop ;
: comma-list ( n -- )
  1
  begin  dup 1 .r
         2dup <>
  while  ." , " 1+
  repeat 2drop ;

[edit] Fortran

Works with: Fortran version 90 and later

DO i = 1, 10
  IF (i /= 10) THEN
    WRITE (*, "(I1,A)", ADVANCE="NO") i, ", "
  ELSE
    WRITE (*, "(I2)") i
  END IF
END DO

[edit] Haskell

loop :: IO ()
loop = mapM_ action [1 .. 10]
  where action n = do
            putStr $ show n
            putStr $ if n == 10 then "\n" else ", "

It is, however, arguable whether mapM_ counts as a loop.

[edit] Java

 
public static void main(String[] args) {
    for (int i = 1; ; i++) {
        System.out.print(i);
        if (i == 10)
            break;
        System.out.print(", ");
    }
    System.out.println();
}
 

[edit] MAXScript

for i in 1 to 10 do
(
    format "%" i
    if i == 10 then exit
    format "%" ", "
)

[edit] Make

NEXT=`expr $* + 1`
MAX=10
RES=1

all: 1-n;

$(MAX)-n:
       @echo $(RES)

%-n:
       @-make -f loop.mk $(NEXT)-n MAX=$(MAX) RES=$(RES),$(NEXT)

Invoking it

|make -f loop.mk MAX=10
1,2,3,4,5,6,7,8,9,10

[edit] OCaml

let last = 10 in
for i = 1 to last do
  print_int i;
  if i <> last then
    print_string ", ";
done;
print_newline();
let ints = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] in
let str_ints = List.map string_of_int ints in
print_string (String.concat ", " str_ints ^ "\n") ;

[edit] Pascal

 
program numlist(output);
 
var
  i: integer;
 
begin
  for i := 1 to 10 do
    begin
      write(i);
      if i <> 10 then
        write(', ')
    end;
  writeln;
end.
 

[edit] Perl

 
foreach $i (1..11) {
    print $i;
    last if $i == 10;
    print ', ';
}
print "\n";
 

[edit] Pop11

lvars i;
for i from 1 to 10 do
    printf(i, '%p');
    quitif(i = 10);
    printf(', ', '%p');
endfor;
printf('\n', '%p');

[edit] Python

 
myOutput = []
for i in xrange(1, 11):
    myOutput.append(i)
    if i == 10:
        break
    myOutput.append(", ")
print ''.join(myOutput)
 

Note: this example uses the Python idiom of building a string as a list and joining the parts together (on an empty string) which is generally far more efficient than instantiating new strings at every step along the way. (Strings are immutable so each expression using "some string" + "some other string" is building new objects rather than appending to existing ones).

[edit] Scheme

It is possible to use continuations:

(call-with-current-continuation
 (lambda (esc)
   (do ((i 1 (+ 1 i))) (#f)
     (display i)
     (if (= i 10) (esc (newline)))
     (display ", "))))

But usually making the tail recursion explicit is enough:

(let loop ((i 0))
  (display i)
  (if (= i 10)
      (newline)
      (begin
        (display ", ")
        (loop (+ 1 i)))))

[edit] SNUSP

@\>@\>@\>+++++++++<!/+.  >-?\#  digit and loop test
 |  |  \@@@+@+++++# \>>.<.<</    comma and space
 |  \@@+@@+++++#      
 \@@@@=++++#

[edit] Tcl

proc range {from to} {
   if {$to>$from} {concat [range $from [incr to -1]] $to}
}

join [range 1 10] ,
= 1,2,3,4,5,6,7,8,9

[edit] UnixPipes

The last iteration is handled automatically for us when there is no element in one of the pipes.

yes \ | cat -n | head -n 10 | paste -d\  - <(yes , | head -n 9) | xargs echo

[edit] V

[loop 
   [ [10 =] [puts]
     [true] [dup put ',' put succ loop]
   ] when].

Using it

|1 loop
=1,2,3,4,5,6,7,8,9,10
Personal tools