Programming Challenge #3


Another little puzzle to keep you thinking. I saw this problem during the reign of the dinosaurs, and thought it was pretty clever.

El problemo

Write some code that prints 543210012345.

You code must meet the following conditions:

  • You must use single a loop (eg. for or while) and each iteration of your loop may only print one character digit.
  • No if statements, no ternary operators.
  • No strings, no arrays. Numbers only.
  • You may only use at most one variable.
  • You may use language-specific functions / methods (but it’s not necessary).

As always, use any programming language you like and post up your answers in the comments. Once there have been several attempts, I’ll post up my suggested answers. It’ll be interesting to see the different ways people do this, and the various optimization techniques that are utilized.

Good luck!

Note: When leaving a comment, indent your code blocks by four space or one tab so the formatting is saved and you don’t have to escape characters. For inline code, wrap it in backticks, eg. `This is some code`


Back to Top ↑

47 Comments so far

Leave a comment

Pages: « 1 [2] Show All

  1. 18

    Oooh, good point Jonathan. (Although my Ruby solution still works then.)

    for (int i = 11; i >= -11; i -= 2) putchar(’0′ + (abs(i) >> 1));

  2. 19

    (Aside: Hi! Long time RSS subscriber, first time poster)

    Hi! Thanks for commenting. :)

    The requirement to print only a single character in each iteration of the loop seems confusing in light of the ‘no strings’ restriction

    I did mean integer, but during a brief moment of insanity, I wrote character. I’ve fixed that up now. Thanks for pointing that out.

  3. 20
    (-6..6).to_a.each { |i|
        begin
            1 / i
            print i.abs - 1
        rescue
        end
    }
    

    not so nice as other solutions though

  4. 21

    My humble suggestion is adaptable as much as the dinosaurs were - died unable to adapt to the changing environment… urghh requirements, right? :-)

    print 5432100

    1.times { print 12345 }

    The .times method executes a single loop. There is no statement saying that I should write the loop myself…

    No algorithm magic, ugly? Yes, but it is simple, does not make me think, it is readable and works :)

    Regards!

  5. 22

    I forgot to mention that Ruby is the language in use… Sorry for that!

  6. 23

    Lunohodov, your suggestion is quite clever (I’d almost call it cheeky :P ) but you’re only allowed to print one digit in each iteration of your loop. Perhaps that wasn’t clear enough.

    Nice try, though. :D

  7. 24

    My solution in Ruby (without the disguised arrays that Agnoster and Michal used :P )

    a = 5.5
    
    while a > -6
      print a.to_i.abs.to_s
      a -= 1
    end
    
  8. 25

    My solution in C++, fairly scalable:

    #include <math.h>
    
    using namespace std;
    
    int main( int argc, char ** argv )
    {
        int n = 5;
        for ( double i = pow(10,n)+1; i > pow(10,-n-1); i = i / 10 )
                cout << abs((int)log10(i));
        return 0;
    }
    
  9. 26

    Kris, that’s clever!

    My C++ isn’t that great, but does that code output 0 twice? It seems to me that it would output 54321012345 (with only one 0).

  10. 27

    Yeah it does output zero twice. That is actually what the +1 is for in the initializer of the for loop. Without the +1, it would only output zero once.

  11. 28

    Sphynx: If you’re going to consider k.upto(n) to be a “disguised array” (which it’s not - it’s possible it’s a disguised range but it’s definitely not an array - and at any rate I strongly doubt it, considering the implementation would make more sense as a for loop), then you have to consider your to_s (which seems totally unnecessary to me) to be the use of a string, so… disqualified. :-P

    But if you insist, can you at least agree this is not a “disguised array”?
    -11.step(11,2){|x|print x.abs>>1}

    Kris: You and I must have very different notions of the word “scalable”. Almost all the other solutions (apart from the first one, and the ones that try to fake it) can handle fairly arbitrary ranges, whereas your solution doesn’t work anywhere past n=500 (well… depending on the limits of your machine and C implementation - but exponentiation seriously stunts your range of attack). Besides which you’re using some very slow functions. log is slower than pow is slower than dividing is slower than bitshifting.

  12. 29

    Now you guys are taking it a bit too seriously.

    No one cares about scalability or performance. I think all anyone cares about is “neat”.

    All of the solutions have dealt with the rules in an interesting way (sometimes avoiding the rules altogether). I think, unless we have any more new solutions (and not just rehashes of what we’ve seen already) we should stop here. ;-)

    Sorry about the poor formatting last night. I assumed the preview would give me some WYSIWYG but I guess not. For the next challenge I’ll just use backticks and trust the server will format it right. ;-)

    BTW Nice “Python sucks, Ruby rules” jab earlier Agnoster… ;-)

  13. 30

    Jonathan - never said that. Just said whitespace sensitivity is a nightmare for code transmission. I never said “Python sucks” - it’s a fantastic language, fairly performant, clean-ish and a good selection of libraries. If you have production work to do (and you can’t afford to write it in C), if performance matters, if you need access to lots of libraries, go for Python (or Java). If you want to do something clever, succinct, and beautiful, and then post it in a blog comment without it getting mangled… well, the Ruby’s a good choice.

  14. 31

    Heh, fair enough. ;-)

    So no more entries? I’m still waiting for the version that calculates PI to enough digits to find the number sequence…

  15. 32

    Agnoster: ‘Range’ or ‘Array’, it still isn’t “Numbers only.” :P But I’m kindof new to Ruby, and looking carefully, I have to admit it wasn’t a range… more like a for-loop in disguise.
    And the to_s, well, that could have been left out, I guess… But what language doesn’t use a (behind the scenes) conversion to a string before printing? Like all the "%d"’s?

  16. 33

    Sphynx: If we’re talking “behind the scenes”, they all use strings to output (unless you count my C solution with putchar differently), but they also all use conditionals for loops, and multiple registers to hold different values when you get down into the nuts and bolts.

  17. 34

    Jonathan,

    assumed the preview would give me some WYSIWYG but I guess not. For the next challenge I’ll just use backticks and trust the server will format it right.

    Don’t worry, I’ve added javascript Markdown to the live preview so it’ll be pretty much WYSIWYG now. I’ve made it lazy-loading though, so it may take a second after you type something for it to start formatting with Markdown.

    Just a reminder,

    Code blocks are indented by one tab or four spaces. They look like this.
    

    `Inline code wrapped in backticks (the key to the left of the "1")`

    So hopefully there’ll be no more formatting issues.

  18. 35

    Here’s another solution (in C).

    #include <stdio.h>
    
    int main(int argc, const char *argv[])
    {
        char i;
        for (i = '5'; i >= '0' - 6; i--)
            putchar(i + (1 - (i / '0')) * ((('0' - i) << 1) - 1));
    
        return 0;
    }
    
  19. 36

    Ooh, I like Qwerty Denzel’s solution.

    Here’s my solution (no floating point, no explicit abs())

    int i = -11;
    
    while (i < 12) {
        printf("%d", (i * ((i >=0 ) - (i < 0))) >> 1);
        i += 2;
    }
    
  20. 37

    for (float i = 5.0; i > -6.0; i -= 0.99 ) {
    printf(”%d”, abs((int)i));
    }

  21. 38
    #include<stdio.h>
    
    int main (void)
    {
        int i = 54;
        for (;i>48&&putchar(--i)||i==48&&putchar(i--)||i<48&&i>42&&putchar(96-i--););
        putchar('\n');
        return 0;
    }
    
  22. 39
    #include <stdio.h>
    
    main()
    {
            long long i=543210012345LL;
            while (i > 0) {
                    putchar((i%10)+'0');
                    i /= 10;
            }
            putchar('\n');
    }
    
  23. 40

    Here’s kind of a hacky C# solution that i through together in about 30 seconds:

        static void DoIt()
        {
            double value = 5.5;
            while (value > -6)
            {
                Console.Write(Math.Floor(Math.Abs(value)));
                value -= 1;
            }
            Console.WriteLine();
            Console.WriteLine("Done");
        }
    
  24. 41

    Here is another solution that I believe is unique from all of the other solutions seen so far.

    #include <stdio.h>
    
    /* pattern(n) produces as output for n = [-6,5]: 000000111111. */
    #define pattern(n) ((1 + (n + n + 1)%2)/2)
    #define dscterm(n) ((pattern(n) - 1)*(n + 1))
    #define ascterm(n) (pattern(n)*n)
    
    /* limit can be any integer > 0.                                  */
    /* If limit is > 10 then use itoa() inside putchar().             */
    /* general: limit = n will produce as output: (n-1)...00...(n-1). */
    /* limit = 6 will produce as output: 543210012345.                */
    #define limit 6
    
    int main(int argc, char *argv[])
    {
        int i;
        for (i=-limit; i<limit; i++)
            putchar(0x30 + dscterm(i) + ascterm(i));
    
        putchar('\\n');
    
        return 0;
    }
    
  25. 42

    Using Mathematica:

    FromDigits[ Abs[ Join [ NestList[# - 1 &, 5, 5], NestList[# - 1 &, 0, 5] ] ] ]

  26. 43

    Not that you asked for a recursive version, but…

    #! /bin/python
    
    def pal( n ):
        print n,
        try:
            1/n
            pal( n-1)
        except:
            pass
        print n,
    
    pal(5)
    
  27. 44

    And for completeness, here it is again, but in erlang:

    filename:pal.erl

    -module( pal ) .
    -export( [duh/1] ).

    duh( -1 ) -> 0;
    duh(N) -> io:format( “~p”,[N]), duh(N-1), io:format(”~p”,[N]).

    pal:duh(5).

  28. 45

    Here is a solution using Turing

    for i:1..12
    put (abs(i-(13-i))-1)/2 ..
    end for

  29. 46

    system(”curl -s http://lipidity.com/development/programming-challenge-3/“);

  30. 47

    public class chal3{
        public static void main(String[] args){
            double i = 5;
            while (i > -6){
                System.out.print(Math.abs((int)i));
                i = i - .99999;
            }
            System.out.println();
        }
    }

    Totally taking advantage of rounding errors. Any port in a storm.

    Anyway. Java is totally not meant for this. Half of the code is wasted on constructors and other junk. Which lead to a breakthrough.

        public static void main(String[] args){
        System.out.println(args[0]);
        }
    

    Java chal3 543210012345
    

    Now that’s what I call ENTERPRISE!

Pages: « 1 [2] Show All

RSS feed for comments on this post. TrackBack URI

Leave a comment

Comments may be edited for formatting.