Loops/N plus one half: Difference between revisions

From Rosetta Code
Content added Content deleted
(added common lisp and ruby)
Line 87: Line 87:
}
}
</cfscript>
</cfscript>

=={{header|Common Lisp}}==
<lisp>(loop for i from 1 upto 10 do
(princ i)
(if (= i 10) (return))
(princ ", "))</lisp>


=={{header|D}}==
=={{header|D}}==
Line 266: Line 272:


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

=={{header|Ruby}}==
<ruby>for i in 1..10 do
print i
break if i == 10
print ", "
end
puts</ruby>


=={{header|Scheme}}==
=={{header|Scheme}}==

Revision as of 03:25, 27 November 2008

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

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.

Ada

<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; </ada>

ALGOL 68

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

BASIC

Works with: FreeBASIC version 0.20
Works with: RapidQ

<qbasic> DIM i AS Integer

FOR i=1 TO 10

   PRINT i;
   IF i=10 THEN EXIT FOR
   PRINT ", ";

NEXT i </qbasic>


C++

<cpp>

  1. include <iostream>

int main() {

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

}</cpp>

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>

Common Lisp

<lisp>(loop for i from 1 upto 10 do

 (princ i)
 (if (= i 10) (return))
 (princ ", "))</lisp>

D

<d>for (int i = 1; ; i++) {

 writef(i);
 if (i == 10) break;
 writef(", ");

} writefln();</d>

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


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 ;

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

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.

Java

<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();

} </java>

MAXScript

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

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

OCaml

<ocaml>let last = 10 in for i = 1 to last do

 print_int i;
 if i <> last then
   print_string ", ";

done; print_newline();</ocaml>

<ocaml>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") ;</ocaml>

Pascal

<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. </pascal>

Perl

<perl> foreach $i (1..11) {

   print $i;
   last if $i == 10;
   print ', ';

} print "\n"; </perl>

Pop11

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

Python

<python> myOutput = [] for i in xrange(1, 11):

   myOutput.append(i)
   if i == 10:
       break
   myOutput.append(", ")

print .join(myOutput) </python>

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

Ruby

for i in 1..10 do

  print i
  break if i == 10
  print ", "

end puts

Scheme

It is possible to use continuations: <scheme>(call-with-current-continuation

(lambda (esc)
  (do ((i 1 (+ 1 i))) (#f)
    (display i)
    (if (= i 10) (esc (newline)))
    (display ", "))))</scheme>

But usually making the tail recursion explicit is enough: <scheme>(let loop ((i 0))

 (display i)
 (if (= i 10)
     (newline)
     (begin
       (display ", ")
       (loop (+ 1 i)))))</scheme>

SNUSP

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

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

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

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