Loops/N plus one half: Difference between revisions
(→{{header|SNUSP}}: oops, pasted to wrong task) |
|||
Line 302:
when there is no element in one of the pipes.
yes \ | cat -n | head -n 10 | paste -d\ - <(yes , | head -n 9) | xargs echo
=={{header|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
|
Revision as of 19:13, 26 September 2008
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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> myString = "" for i in xrange(1, 11):
myString += str(i) if i == 10: break myString += ", "
print myString </python>
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