Loops/N plus one half: Difference between revisions
Line 256: | Line 256: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
<python> |
<python> |
||
myOutput = [] |
|||
for i in xrange(1, 11): |
for i in xrange(1, 11): |
||
myOutput.append(i) |
|||
if i == 10: |
if i == 10: |
||
break |
break |
||
myOutput.append(", ") |
|||
print |
print ''.join(myOutput) |
||
</python> |
</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). |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
Revision as of 20:03, 17 November 2008
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
<qbasic> DIM i AS Integer
FOR i=1 TO 10
PRINT i; IF i=10 THEN EXIT FOR PRINT ", ";
NEXT i </qbasic>
C++
<cpp>
- 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>
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
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).
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