Stack Overflow: Printing 1 to 1000 in C
stackoverflow.com
stackoverflow.com
Cute puzzle, nice to see some inventive torturing of C, and various dialects that people believe are C.
To be fair, the SO question specifies "using C or C++", not just C.
Any Language Lawyers around?
Is pointer arithmetic not allowed? Or calling main()?
So, for an array of function pointer that would be legal behaviour, but for pointers to plain functions, it is undefined behaviour.
If you do want to put a (non-function) pointer into an integer, convert to (C99) [u]intptr_t. Of course, that does not have to be defined...
A program I'm writing now uses void* as a generic function pointer, which I cast to different function signatures as required depending on usage. I'm guessing that's considered harmful, is there a better or more idiomatic way to do this?
Architectures where code pointers are bigger than data pointers are fairly exotic, I think. The AS/400 might be an example, I'm not sure. However! You can avoid that particular problem by using (void* )(void) as your generic function pointer type, rather than simply void *.
That said, this is not that likely to be a problem in practice on Unix machines (Windows has more than one calling convention - I have no idea how much of a problem that is.)
Tiny C (from 2006, 5 years old) gives:
function pointer expected
MS C 6 (from 1998, 13 years old) gives error C2296: '-' : illegal, left operand has type 'void (__cdecl *)(int )'
Turbo C 2.01 (from 1988, 23 years old) gives: Size of structure or array not known in function
etc.I think the really clean solution (as far as I know, at least it works with all the compilers I've mentioned) is:
What ever happened to the IOCCC? (International Obfuscated C Coding Contest, ioccc.org)
The real answer is "don't work there".
, if you have to ask this question ;-)"
To prepare you for the code they shouldn't realistically have in production. Oh.
: o dup . cr 1+ ;
: t o o o o o o o o o o ;
: h t t t t t t t t t t ;
: thousand h h h h h h h h h h drop ;
1 thousandTail-recursive calls (like the linked solution uses, though C compilers usually do not implement 'proper' tail calls) or short-cut conditionals might not look like but are still loops or conditionals.
So, why the answer is funny it does not answer the original question.
With optimizations turned on, gcc turns a tail recursive function into the equivalent of a for loop.
At least now I know that latest gcc can do tail-call optimizations.
#include <stdio.h>
#define print printf("%d\n", n++);
#define times2(x) x x
#define times5(x) x x x x x
#define pow3(x,f) x(x(x(f)))
int main() {
int n = 1;
pow3(times2, pow3(times5, print));
return 0;
} #define NOT_A_LOOP(x) while(x)
Enumerator is just Ruby object goo over a loop.#include someone_else_did_it_so_we_dont_know(x)
Just as those other answers in C relied on GOTOs somewhere.
Which, of course, is passing the buck to Range#to_a
No stinking loops!
def f(a):
print a
print a+1
{999: int}.get(a,f)(a+2)
f(1)
Note, I had to count by twos, because when I counted by ones, I got a "maximum recursion limit exceeded" error.Basically, the concept is to call f recursively, until you get to 999 (and had printed 999 and 1000), at which time you call some non-recursive function (I call "int").
At 999, the inner-called f function terminates, leading to the unwinding of the stack (each previous f function terminating), and then the program ends.
This statement is the hard one to understand:
{999: int}.get(a,f)(a+2)
Basically, it's saying "Look up 'a' in this hard-coded dictionary that only has one value in it - for 999. If 'a' isn't found (as it won't be most of the time), set the look-up value to the function called 'f'. Otherwise, set the look-up value to the function called 'int'. In either case, call that looked-up value, passing the parameter of a+2." print str(range(1,1001)).strip('[]').replace(', ','\n')
Edit: added missing [ as pointed out below print "\n".join(map(str, range(1,1001)))
or print "\n".join(str(i) for i in range(1,1001))Or else you could just:
for i in range(1,1000):
print i
Plus relying on the string representation of a list isn't silly it as it doesn't change. I just didn't know if range would meet the criteria or not. MAX = 1000
def execute_if_not_equals(value, other, &block)
noop = lambda {}
[block, noop][value / other].call
end
def print(i)
execute_if_not_equals(i, MAX) do
puts(i + 1)
print(i + 1)
end
end
print(0)
[edit]: updated to not use != operator which is probably a cheat. f() -> f(1).
f(1001) -> ok;
f(N) -> io:fwrite("~p~n", [N]), f(N + 1). z="0123456789"
print map(lambda x:int("".join(x))+1,zip(sorted(zip(*z)[0]*100),
sorted(zip(*z)[0]*10)*10,
zip(*z)[0]*100))
Only downside is that it prints as a list (so it has the format of [1,2,3..]) ('\n').join(map(str, [1,2,3])) from __future__ import print_function
z="0123456789"
map(print,map(lambda x: int("".join(x))+1,zip(sorted(z*100),
sorted(z*10)*10, z*100)))
The way it works is to create 3 strings, one for each digit-place. The first digit, when counting from 000 to 999, is 100 zeros, followed by 100 ones, followed by 100 twos, etc. That is represented by sorted(z*100)
The middle digit is 10 zeros, 10 ones, etc... and repeat this 10 times. So this is sorted(z*10)*10.
The least significant digit is represented by a string that just counts and starts over. it's 1000 characters long: "0123456789012345..." and represented by z*100.
I define an unnamed function (using lambda), that does the following: Join the three digits, make it an int, and add 1. So the result of this is a list of numbers from 1 to 1000. In other words, map(lambda x: int("".join(x))+1,zip(sorted(z*100),
sorted(z*10)*10, z*100)))
is about the same as if I just used range(1,1001)Then I map it to the new print function that is available in Python 3.0, or with the import statement.
A simpler version would use range, but that seems a little too simple:
from __future__ import print_function
map(print,range(1,1000))
Now that I think about it, this last one is the right answer! mapM_ (putStrLn . show) [1..1000]mapM_ print [1..1000]
but yeah, ...haskell +1 for that :D
(map (lambda (n)
(displayln n))
(cdr (build-list 1001 values))) $,="\n"; print 1..1000 var items = [];
var rec = function(item) {
var func = [];
func[true] = function(item) { items.push(item); [item-1].map(rec); };
func[false] = function(item) {};
return func[Boolean(item)](item);
};
var item = [1000];
item.map(rec);
console.log(items.reverse().join(','));
Won't do in browsers due to recurssion limit but change [1000] to [10] and you'll see it works.If I learned one thing from the experience it is that often the popularity of something is not a measure of how "correct" it is. It's often a measure of the compromises you are prepared to make, and also how "appealing" it is.
FWIW, thanks HN. I actually read about the question right here in the first place!
By the way, the "correct" version was added by someone else. Posts to whoever added it.
#include <cstdio>
int main(int argc, char** argv) {
void* labels[2] = { &&doing, &&done };
int i = 1;
doing:
printf("%d\n", i++);
goto *labels[i / 1001];
done:
return 0;
}
Still consider goto harmful? (Well yeah, so do I generally. But hey...)gcc printy.c printy.c: In function ‘main’: printy.c:4: warning: return type of ‘main’ is not ‘int’
My idea was to create a buffer of 1000 bytes and recursively call a function while each byte is dereferenced until it finally hits a byte which causes a segfault... but I just can't get it working.
The function pointer solution is genius...
#include<stdio.h>
void output(x) { int y; printf("%i\n", x); y = 1 / (1000 - x); output(x + 1); }
int main() { output(1); }
With gcc on Linux it has the added bonus of "Floating Point Exception", don't know if that disqualifies it.
EDIT: Nevermind, I got it:
#include<stdio.h>
int output(x) { printf("%i\n", x); (x >= 1000 ) || output(x + 1); return 1; }
int main() { output(1); }
Only thing is, the interviewer would ask, "How would this work in Windows?"
Cygwin?
(function(max){ new Array(max + 1).join(' ').replace(/\s/g, function(c, i){ console.log(i + 1); }) })(1000)
int main(void) { printf(" 1 2 3 4 5 6 7 8"); return 0; }
I bet that 1000 was in binary and he was obviously checking the guy's CQ ( compSci Quotient)
One other mod: (j/1000) could be replaced with (j>999) which is still non conditional, but faster.
#include <stdio.h>
#include <stdlib.h>
void pr(int j) {
printf("%d\n", j);
(pr + (exit - pr)*(j/1000))(j+1);
}
int main(int argc, char** argv) {
pr(1);
return 0;
} #include <stdio.h>
#include <stdlib.h>
int pk( int i )
{
static int (*v[])( int ) = { pk, abs };
printf( "%d\n", i );
return v[ i/1000 ]( i+1 );
}
int main( void )
{
pk( 1 );
return 0;
} use POSIX;
sub pk
{
print "$_[0]\n";
return ( \&pk, \&fabs )[ $_[0] / 1000 ]( $_[0] + 1 );
}
pk( 1 ); perl -e '($pk=sub { print "$_[0]\n"; ($pk, sub{}) [$_[0]/1000] ($_[0]+1) }) -> (1)' $,="\n"; print 1..1000
I don't know if it can be made shorter. My previous example was (also for the readers who don't know that) to demonstrate the "C inspired" features in Perl and almost 1-1 mapping to the C solution, minus declarations.291 printf("numbers from 1 to 1000");jondavidjohn Dec 31 '10 at 7:07
To me, abuse of vote to close is up there with deletionism on Wikipedia as making no sense, particularly in this case.
But why delete a programming-related question with lots of healthy discussion and where people are enjoying themselves? Or, for that matter, a wikipedia page that is well-written and accurate, but only of interest to a small percent of people?