Join 3,375 readers in helping fund MetaFilter (Hide)


The shortest programming distance between one and infinity?
August 23, 2011 8:31 AM   Subscribe

What is the shortest possible program (in any well-known programming language) that will count up indefinitely and display the output as it's counting?

Basically, I want the program to display all integers starting from 1, each on its own line, until the program is stopped.

It doesn't matter what kind of language this is written in, but I'm looking for the shortest possible code in characters.

So far I've managed to get it down to 27 characters in a few languages, and I'm wondering if that can be beat.

I'm sure there are lots of catches and caveats here such as "well, what exactly constitutes a programming language?" and "I could just write my own programming language that does this in one character." But I'm primarily looking for examples in widely-known languages. But any clever responses are welcome.
posted by joshrholloway to Technology (80 answers total) 10 users marked this as a favorite
 
Here's 26 characters in PHP: $i=1;while(1){echo $i++;}
posted by hobgadling at 8:38 AM on August 23, 2011


An obvious way takes 34 characters in Haskell:

main=mapM_ (putStrLn.show) [1..]

posted by Dr Dracator at 8:39 AM on August 23, 2011


hobgadling, can't you also strip out the curly brackets and closing semi-colon, and it will still run? (at work, so I can't test it myself)
posted by misterbrandt at 8:42 AM on August 23, 2011


misterbrandt, I just tested it, and you have to have the closing semicolon, but you can drop the curly brackets, you're right. So that drops it down to 24 characters.
posted by hobgadling at 8:45 AM on August 23, 2011


I can do it in 15 in bash: while true;do echo $((i++)); done
posted by mkb at 8:46 AM on August 23, 2011 [1 favorite]


Hang on, I mangled the command line that piped that command to wc. It's 34.
posted by mkb at 8:47 AM on August 23, 2011


ruby 26:
(1..(1.0/0)).each{|i| p i}
posted by czytm at 8:48 AM on August 23, 2011


PHP can run without declaring variables or values and without brackets or spaces if the action is clear -- this worked on mine:

while(1)echo$i++;

That's 18 characters.
posted by AzraelBrown at 8:49 AM on August 23, 2011 [1 favorite]


mkb - wc isn't needed as far as I'm reading this.
posted by colin_l at 8:50 AM on August 23, 2011


Er, 17 characters, and I failed to give props to hobgadling for the bulk of the code...
posted by AzraelBrown at 8:50 AM on August 23, 2011


I'm not sure how you're counting characters (does whitespace count?)

Python:

i=0
while i:
i+=1
print i

octave:

i=0
while i+=1
i
end
posted by Metasyntactic at 8:51 AM on August 23, 2011


Perl:

say ++$i while 1
posted by SomePerlGeek at 8:51 AM on August 23, 2011 [4 favorites]


In any kind of procedural programming, isn't this really an exercise in "which language has the shortest stdout implementation"?
posted by mkultra at 8:54 AM on August 23, 2011 [2 favorites]


...each on its own line...

The PHP one doesn't do that requirement -- to do so:

while(1)echo$i++."\n";

works, which makes 22 characters.
posted by AzraelBrown at 8:57 AM on August 23, 2011


Hey everybody: "each on its own line"

so PHP maybe (thx hobgadling and AzraelBrown):
while(1)echo$i++."/n"; 
(22)

(on preview, yeah).
posted by misterbrandt at 8:58 AM on August 23, 2011


This REXX code:

do i=1;say i;end

has only 16 characterrs.
posted by grouse at 9:00 AM on August 23, 2011


well i guess ruby could be shortened to 23: (1..1.0/0).each{|i|p i}
posted by czytm at 9:00 AM on August 23, 2011


Brainfuck with a compiler that initializes to ASCII 49: [.>] 4 characters.
posted by michaelh at 9:01 AM on August 23, 2011


Oops, [.+]
posted by michaelh at 9:01 AM on August 23, 2011


I think brainfuck gets it in 5: +[+.]

Explained:
+ : increment cell(0) to 1.
[ : execute the following command if the value in the current cell is not 0
+ increment the value at cell(0)
. : print cell(0)
] : return to the instruction just after the preceding '[' character

And on preview: michaelh had the same thought.
posted by lantius at 9:05 AM on August 23, 2011 [2 favorites]


On second thought, brainfuck will start putting out other things after 9. Rats.
posted by michaelh at 9:11 AM on August 23, 2011


The BF examples don't really work, though. The output is a string of incremented ASCII characters without line breaks. You'd have to modify the interpreter to interpret the cell values as numbers rather than ASCII characters, and it would still lack line breaks. And once we're modifying interpreters all bets are off. And BF is limited to 8-bit bytes, so to print arbitrarily high numbers you'd need to change that, too.

Speaking of arbitrarily high numbers: are any of the other above examples bounded by a datatype? The Perl example will break at 2^32 - 1 on most systems, I think, unless use bignum; is specified.
posted by jedicus at 9:14 AM on August 23, 2011


colin_l: "mkb - wc isn't needed as far as I'm reading this."

No, I mean that I only counted the length second half of the command due to fat-fingering. :)
posted by mkb at 9:15 AM on August 23, 2011


The PHP examples still start at zero. Easily remedied (22 characters):

while(1)echo++$i."\n";
posted by neckro23 at 9:22 AM on August 23, 2011


(For bonus points you can use for(;;), it appears, but that's the same number of characters.)
posted by neckro23 at 9:24 AM on August 23, 2011


...or rather it trims one character. Not enough coffee! So, 21 characters:

for(;;)echo++$i."\n";
posted by neckro23 at 9:26 AM on August 23, 2011


If you count the Unix shell environment as a programming language:
yes|sed -n =
which is 12 characters.
posted by stebulus at 9:26 AM on August 23, 2011 [8 favorites]


(while running bash)
while true ; do echo ; done | perl -ne 'print$i++."\n";'
technically, the program is in perl which is a mere 15 characters ; albeit I cheat by pumping in infinite stdin.
posted by nobeagle at 9:28 AM on August 23, 2011


awk is a little longer, 20 characters:
yes|awk '{print NR}'
posted by jozxyqk at 9:30 AM on August 23, 2011


CoffeeScript on version 1.0.12 of node.js gets it in 17 characters:
i=1;loop puts i++
posted by SemiSophos at 9:45 AM on August 23, 2011


Common Lisp:
(loop for n from 1 do (print n))
posted by vsync at 9:52 AM on August 23, 2011


say ++$i while 1

You can carve away one more -- you don't need a space between say and ++$i. But, since "say" isn't available before 5.10* and needs to be explicitly enabled, one really needs to say at least

perl -E 'say++$_ while 1'

to express this. Unless you were talking Perl 6, which I don't know.

* but users of Perl >= 5.6 can install a module to get it.
posted by Zed at 9:56 AM on August 23, 2011


APL is almost surely king of this exercise. I can't write it myself, but these examples strongly suggest that it can be done within 12 characters.
posted by identitymap at 10:02 AM on August 23, 2011


For the record, I believe this BF program could theoretically count to 9,999,999,999. So, it's the big loser.

++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++>
+++++++++++++++++++++++++++++++++++++++++++++++++>++++++++>
<>
[.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->+++++++++]>.>[<>->--------->++++++++++]-<+<<<<<<<<<<<<<<<<<<]
posted by michaelh at 10:03 AM on August 23, 2011 [1 favorite]


I was about to say that a version of APL that supports infinity would probably beat the current examples.
posted by grouse at 10:05 AM on August 23, 2011


Ugh, not escaped. That's 20 decrementers at the first <> and 3 elsewhere.
posted by michaelh at 10:05 AM on August 23, 2011


Er, the first <> is actually 20 < and the rest are three <
posted by michaelh at 10:05 AM on August 23, 2011


Befunge:
0v
 >1+:.91+,
If we remove the restriction that each number must be on its own lines it goes down to 9 characters.
posted by vsync at 10:16 AM on August 23, 2011


17 characters in befunge 93:
>0+1+:.v                                                                        
^  ,*52< 


Not exactly a widely used language, but my favorite esoteric language :)
posted by rpn at 10:16 AM on August 23, 2011


On preview: vsync's befunge version was much shorter...
posted by rpn at 10:17 AM on August 23, 2011


Shorter befunge version based on vsync (8 characters):
1+:.91+,

posted by rpn at 10:22 AM on August 23, 2011 [2 favorites]


Ah, exploiting the fact that popping an empty stack returns 0. It's been a while. I tip my hat to you sir.
posted by vsync at 10:25 AM on August 23, 2011 [1 favorite]


In R, 28 characters, and I'm cursing the fact that "while" and "print" are five characters each:

i=0;while(T){i=i+1;print(i)}
posted by madcaptenor at 10:43 AM on August 23, 2011


In R, this has only 21 characters:

repeat print((F=F+1))
posted by grouse at 10:58 AM on August 23, 2011 [1 favorite]


If we're allowing things that run interpreted rather than compiled/standalone, that Haskell example can probably be shorter (e.g. running inside ghci). I don't have a system w/ghci handy at the moment to try anything on, though.
posted by madmethods at 11:02 AM on August 23, 2011


I guess using print in R doesn't really fit the specification because it prints [1] before every line. But this should work, and is only 20 characters.

repeat dput((F=F+1))
posted by grouse at 11:23 AM on August 23, 2011


Hmm...I'm not sure you can do better than just losing the "main=", the spaces, and the "_" (i.e. just mapM). So I think that gives 24 for interpreted Haskell.
posted by madmethods at 11:25 AM on August 23, 2011


Ruby in 18 characters:

i=0;loop{p (i+=1)}
posted by yath at 11:35 AM on August 23, 2011


Yeah, mapM would do just as well as mapM_. There's not much to gain otherwise, putStrLn is where the characters are wasted and I don't think you can do without it.
posted by Dr Dracator at 11:35 AM on August 23, 2011


Actually, I don't see any reason we couldn't just use "print" rather than putStrLn.show. That can be done as "mapM print[1..]". So that's 15 characters for interpreted Haskell. That's more of a "real" language than some of the above, and I think it will print until the machine's (virtual) memory is exhausted (infinite lists / integers).
posted by madmethods at 11:37 AM on August 23, 2011 [1 favorite]


yath, I think you can leave out the declaration of i. loop{p(i+=1)} will work and that is 13 characters.
posted by czytm at 12:00 PM on August 23, 2011


ack, no you cannot. My mistake.
posted by czytm at 12:02 PM on August 23, 2011 [1 favorite]


Wait, are we making distinctions about what's a "real" language now and what isn't?

If I was to make distinctions I'd start by banning any language from the discussion that encounters an integer overflow before memory is exhausted. The question did say "infinity"...
posted by vsync at 12:07 PM on August 23, 2011


In bc:
for(;;)++n
10 characters, no integer overflow.
posted by stebulus at 1:13 PM on August 23, 2011 [1 favorite]


Oops, bc actually does have limits — on my machine, the maximum integer is 10231-1-1.

NEXT TIME, HASKELL! NEXT TIME!
posted by stebulus at 1:22 PM on August 23, 2011 [1 favorite]


A dc version is:

0[1+plfx]dsfx

12 characters.
posted by grouse at 1:31 PM on August 23, 2011


Commodore BASIC (20 characters):

1 i=i+1:printi:goto1
posted by Paquda at 1:36 PM on August 23, 2011 [1 favorite]


The java version will take likely 250 characters. I'm feeling too lazy to write it now though.
posted by dgran at 2:05 PM on August 23, 2011 [2 favorites]


Of course, there's always this at 24 characters as well:

seq 18446744073709551615

Which is cheating because it's not infinity, but the max value of 64-bit integers.
Just let me know when you're done watching it run. :)
posted by jozxyqk at 3:15 PM on August 23, 2011 [2 favorites]


Footnote: This sort of challenge is called "Code golf".
posted by Orb2069 at 3:29 PM on August 23, 2011 [3 favorites]


seq 18446744073709551615

Cute, but not a very good solution. This will print 1e+06 from 100,000 to 100,005, then 1.00001+e06 until 100,010, etc. Even if you use seq -f%1.f, since this uses floating point internally, there will be numbers that will repeat or not appear well before 18446744073709551615.
posted by grouse at 4:00 PM on August 23, 2011


One thing in the problem is considering not just the size of the program, but the size that gets carried along with it for running (ie, vm, runtime libraries and so on). I would think that if you look at a microcomputer, say APPLE II, you could do a fairly decent bignum implementation that in overall runtime and code cost would be tiny. Whereas if you're saying that source size is the determining factor, then typical high-level languages will win out.

FORTH will end up with some pretty short implementations in both source and runtime.

:c 0 begin dup = 1+ 0 until ;
c

:c dup = 1+ recurse ;
0 c

The latter in code space would be (I think) 7 "words" or 28 bytes in a typical threaded implementation and a minimal implementation of enough FORTH to do this could be about 2K, possibly way less.

If you're working 6502 and are happy to live with 512 digits, I could probably give you an Apple II version that tops out at 50 bytes plus the Apple II IO routine (if you want to count that).
posted by plinth at 4:04 PM on August 23, 2011


[seq] will print 1e+06 from 100,000 to 100,005,

(Not that it matters very much, but..)
Not on my Ubuntu box it doesn't.

$seq 100000 100020
100000
100001
100002
100003
100004
100005
100006
100007
100008
100009
100010
100011
100012
100013
100014
100015
100016
100017
100018
100019
100020

posted by jozxyqk at 4:32 PM on August 23, 2011


Sorry, I meant 1000000, not 100000.
posted by grouse at 4:40 PM on August 23, 2011


$seq 1000000 1000020
1000000
1000001
1000002
1000003
1000004
1000005
1000006
1000007
1000008
1000009
1000010
1000011
1000012
1000013
1000014
1000015
1000016
1000017
1000018
1000019
1000020

posted by jozxyqk at 5:02 PM on August 23, 2011


yath's Ruby program will work without the parentheses, giving 16 characters:

i=0;loop{p i+=1}

You can get down to 15 by abusing the global 'line number' variable, $., that Ruby sets for you:

loop{p$.;$.+=1}
posted by chrismear at 5:05 PM on August 23, 2011 [1 favorite]


Here's what I get:

$ seq 1000000 1000020
1e+06
1e+06
1e+06
1e+06
1e+06
1e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00001e+06
1.00002e+06
1.00002e+06
1.00002e+06
1.00002e+06
1.00002e+06
1.00002e+06

$ uname -srv
Linux 2.6.18-238.1.1.el5 #1 SMP Tue Jan 4 13:32:19 EST 2011

posted by grouse at 5:11 PM on August 23, 2011


i=0;loop{p i+=1}

Ruby in 16
posted by soma lkzx at 8:40 PM on August 23, 2011


dgran, even with nice indentation it's only 156:
public class ForeverNumbers {
    public static void main(String[] a) {
        int n = 1;
        while (true)
            System.out.println(n++);
    }
}
Here's one that's a little bigger (232 characters) by virtue of counting much much longer:
import java.math.BigInteger;

public class ForevererNumbers {
    public static void main(String[] a) {
        BigInteger n = BigInteger.ZERO;
        while (true)
            System.out.println(n = n.add(BigInteger.ONE));
    }
}
posted by vsync at 8:48 PM on August 23, 2011 [1 favorite]


[1033] ~ % seq 1000000 1000020
1000000
1000001
1000002
1000003
1000004
1000005
1000006
1000007
1000008
1000009
1000010
1000011
1000012
1000013
1000014
1000015
1000016
1000017
1000018
1000019
1000020
[1034] ~ % uname -a
Linux racer 2.6.38-gentoo-r6 #2 SMP Fri Jun 17 20:26:24 UTC 2011 x86_64 AMD Phen         
om(tm) II X4 945 Processor AuthenticAMD GNU/Linux

posted by vsync at 8:51 PM on August 23, 2011


jozxyqk and I actually continued the seq conversation over MeMail, and I believe it is because RHEL5 uses an old version of seq (5.97). But unless they have stopped using floating point numbers, you will still run into trouble eventually.
posted by grouse at 8:54 PM on August 23, 2011


The shortest I can do in PostScript is 16 characters:
{0 count =}loop
This program will probably run out of stack space before the integer overflow, but I'm not sure that should be counted in its favour.
posted by stebulus at 1:00 AM on August 24, 2011 [1 favorite]


Another solution in the Unix shell environment:
yes \ |nl
9 characters, but the output has some extra whitespace.
posted by stebulus at 1:44 AM on August 24, 2011 [3 favorites]


Some pedantry: the last answer is pretty cool, but yes and nl are full-fledged executables, not shell builtins. If we allow this we might as well write a 15-line FORTRAN implementation, compile it with -o a and get a hole in one.
posted by Dr Dracator at 1:05 PM on August 24, 2011


Some pedantry: the last answer is pretty cool, but yes and nl are full-fledged executables, not shell builtins.

Yeah, but they're standard parts of the UNIX environment, and your "a" binary isn't.
posted by grouse at 1:59 PM on August 24, 2011


If we allow this we might as well

Using Unix tools does stretch the conditions of the puzzle a bit, but this slope is not so slippery.

I think the right standard for this kind of puzzle is an aesthetic one, and that "yes \ |nl" is a more aesthetically satisfying solution than "a". All solutions need to specify a context in which the code is to be understood; it is more satisfying if that context is a standard language or environment than if it is entirely ad hoc. The Unix shell environment (including tools) is standard; a previously compiled program that does the desired job is ad hoc.

The OP alluded to the same issue: "I could just write my own programming language that does this in one character." Again, unsatisfying because it needs substantial ad hoc context. It's also why nobeagle called it "cheating" not to count the characters used to produce a special input that a program needs to do the job. (Too bad for me, since otherwise my earlier attempt would count as just 1 character!)

...

Now that I look into it, I find that POSIX/SUS specifies nl, but apparently not yes. So maybe there's some question about how "standard" the context is in these solutions.
posted by stebulus at 3:25 PM on August 24, 2011


This is like trying to decide the tallest building in the world or extreme points of a country, where there are multiple definitions to use. Winners in a number of categories, so far:
1       ad hoc                                      a
8       esoteric programming language      Befunge  1+:.91+,
9       common command-line environment    UNIX     yes \ |nl
10      calculator language                bc       for(;;)++n
12      standard command-line environment  UNIX     yes|sed -n =
15      common functional language         Haskell  mapM print[1..]
15      common procedural language         Ruby     loop{p$.;$.+=1}
16      standard language                  REXX     do i=1;say i;end
Obviously, the definition of common and esoteric is a little bit subjective but Wikipedia's assignment is good enough for me. "Standard" means that there is an independent national or international standard specifying the behavior. I apologize for errors!
posted by grouse at 5:38 PM on August 24, 2011 [5 favorites]


Hmm it ain't pretty but here's 20 characters for Mathematica:

1//.i_:>i+1+0Print@i
posted by hAndrew at 10:10 PM on August 24, 2011


In bash, 16 characters:
echo $SHLVL;bash
The ad hoc context is that this program has to be your ~/.bashrc (Don't do this! It puts an infinite loop in your login sequence!)
posted by stebulus at 2:33 PM on August 25, 2011


In bash again, 25 characters:
f(){ echo $#;f $@ x;};f x
This is pure bash, no external executables needed, and doesn't have the absurd requirement of being in .bashrc. It will fail when it hits the limit on command-line length, I guess.
posted by stebulus at 11:38 PM on August 25, 2011 [1 favorite]


« Older Who pays the fees on a Visa de...   |  How can my husband and I balan... Newer »
This thread is closed to new comments.