Question

Ok, goal by example : a command-line app that does this:

Countdown.exe 7

prints 7 6 5 4 3 2 1

No form of subtracting (including use of the minus sign) or string reverse what so ever is allowed.

waaaaay too easy apparently :-) An overview of the answers (the principles at least)

  1. By adding and recursion
  2. By using modulo
  3. By pushing and popping, (maybe the most obvious?)
  4. By using overflow
  5. By using trial and error (maybe the least obvious?)
Was it helpful?

Solution

How about adding and recursion?

public void Print(int i, int max) {
  if ( i < max ) { 
    Print(i+1, max);
  }
  Console.Write(i);
  Console.Write(" ");
}

public void Main(string[] args) {
  int max = Int32.Parse(args[0]);
  Print(1, max);
}

OTHER TIPS

x = param;
while (x > 0) {
    print x;
    x = (x + param) mod (param + 1);
}

Here's a method you missed, trial and error:

import java.util.Random;

public class CountDown
{
    public static void main(String[] args)
    {
        Random rand = new Random();

        int currentNum = Integer.parseInt(args[0]);

        while (currentNum != 0)
        {
            System.out.print(currentNum + " ");
            int nextNum = 0;
            while (nextNum + 1 != currentNum) {
               nextNum = rand.nextInt(currentNum);
            }

          currentNum = nextNum;
        }
    }
}

Push 1-7 onto a stack. Pop stack one by one. Print 7-1. :)

use 2's compliment, after all this is how a computer deals with negative numbers.

int Negate(int i)
{
   i = ~i;  // invert bits
   return i + 1; // and add 1
}

void Print(int max)
{
   for( int i = max; i != 0; i += Negate(1) )
   {
     printf("%d ", i);
   }
}

see http://en.wikipedia.org/wiki/2's_complement

Prepend the numbers into a string buffer.

String out = "";
for (int i = 0; i < parm; i++)
{
   out = " " + (i+1) + out;
}
System.out.println(out);

c/c++, a bit of arithmetic overflow:

void Print(int max)
{
   for( int i = max; i > 0; i += 0xFFFFFFFF )
   {
      printf("%d ", i);
   }
}

I note that nobody posted the stupidest possible answer, so I'll go ahead and share it:

int main (int argc, char **argv) {
  if ( ( argc < 1 ) || ( atoi(argv[1]) != 7 ) ) {
    printf("Not supported.\n");
  } else {
    printf("7 6 5 4 3 2 1\n");
  }
}

Don't hate me: See? I admitted it's stupid. :)

use a rounding error:

void Decrement(int& i)
{
    double d = i * i;
    d = d / (((double)i)+0.000001); // d ends up being just smaller than i
    i = (int)d; // conversion back to an int rounds down.
}

void Print(int max)
{
   for( int i = max; i > 0; Decrement(i) )
   {
     printf("%d ", i);
   }
}

Bitwise Arithmetic

Constant space, with no additions, subtractions, multiplications, divisions, modulos or arithmetic negations:

#include <iostream>
#include <stdlib.h>
int main( int argc, char **argv ) {
    for ( unsigned int value = atoi( argv[ 1 ] ); value; ) {
        std::cout << value << " ";
        for ( unsigned int place = 1; place; place <<= 1 )
            if ( value & place ) {
                value &= ~place;
                break;
            } else
                value |= place;
    }
    std::cout << std::endl;
}   

This is not hard. Use the modulus operator.

for (int n = 7; n <= 49; n += 7) {
  print n mod 8;
}

A python version:

import sys

items = list(xrange(1, int(sys.argv[1])+1))
for i in xrange(len(items)):
    print items.pop()

This is cheating, right?

#!/usr/bin/env python 
def countdown(n):
    for i in range(n):
        print n
        n = n + (n + ~n)

And just for fun, its recursive brother:

def tune_up(n):
    print n
    if n == 0:
        return
    else:
        return tune_up(n + (n + ~n))

Start with a file containing descending numbers from to the max you're interested in:

7 6 5 4 3 2 1

Then... this only works up to 9999

#!/bin/sh
MAX_NUM=9999
if [ ! -e descendingnumbers.txt ]; then
    seq -f%04.0f -s\  $MAX_NUM -1 1 > descendingnumbers.txt
fi
tail descendingnumbers.txt -c $[5 * $1]

Quick and dirty version in Scala:

sealed abstract class Number
case class Elem(num: Number, value: Int) extends Number
case object Nil extends Number

var num: Number = Nil

for (i <- 1 until param)
  num = Elem(num, i)

while (num != null)
  num match {
    case Elem(n, v) => {
      System.out.print(v + " ")
      num = n
    }
    case Nil => {
      System.out.println("")
      num = null
    }
}

Increment a signed integer passed max_int and then "Add" it to the counter... or is this consider illegitimate subtraction?

    public void print (int i)
    {
        Console.Out.Write("{0} ", i);
        int j = i;
        while (j > 1)
        {
            int k = 1;
            while (k+1 < j)
                k++;
            j = k;
            Console.Out.Write("{0} ", k );
        }
    }

Kinda nasty but it does the job

public class CountUp
{
    public static void main(String[] args)
    {

        int n = Integer.parseInt(args[0]);

        while (n != 0)
        {
            System.out.print(n + " ");
            n = (int)(n + 0xffffffffL);
        }
    }
}
// count up until found the number. the previous number counted is
// the decremented value wanted.
void Decrement(int& i)
{
  int theLastOneWas;
  for( int isThisIt = 0; isThisIt < i; ++isThisIt )
  {
    theLastOneWas = isThisIt;
  }
  i = theLastOneWas;
}

void Print(int max)
{
   for( int i = max; i > 0; Decrement(i) )
   {
     printf("%d ", i);
   }
}

Are we golfing this?

import sys
for n in reversed(range(int(sys.argv[1]))):print n+1,
#!/usr/bin/env ruby

ARGV[0].to_i.downto(1) do |n|
  print "#{n} "
end
puts ''

Haskell:

import System.Environment (getArgs)

func :: Integer -> [String]
func 0 = []
func n@(x+1) = show n:func x

main = putStrLn . unwords . func . read . head =<< getArgs

A 'feature' called n+k patterns allows this: pattern matching on the addition of two numbers. It is generally not used. A more idiomatic way to do it is with this version of func:

func n = foldl (flip $ (:) . show) [] [1..n]

or, with one number per line:

import System.Environment (getArgs)
import Data.Traversable

main = foldrM (const . print) () . enumFromTo 1 . read . head =<< getArgs

Does this count? Only uses an add instruction...

int _tmain(int argc, _TCHAR* argv[])
{
   int x = 10;
   __asm mov eax,x;
   __asm mov ebx,0xFFFFFFFF;
   while (x > 0)
   {
      __asm add eax,ebx;
      __asm mov x,eax;
      __asm push eax;
      printf("%d ",x);
      __asm pop eax;
   }
   return 0;
}

Perl:

$n = $ARGV[0];

while ($n > 0) {
  print "$n ";
  $n = int($n * ($n / ($n+1)));
}

subtraction is an illusion anyways

I like Dylan Bennett's idea - simple, pragmatic and it adheres to the K.I.S.S principle, which IMHO is one of the most important concepts we should always try to keep in mind when we develop software. After all we write code primarily for other human beings to maintain it, and not for computers to read it. Dylan's solution in good old C:



#include <stdio.h>
int main(void) {
        int n;
        for (n = 7; n <= 49; n += 7) {
                printf("%d ", n % 8);
        }
}

In C, using a rotating memory block (note, not something I'm proud of...):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_MAX 10

void rotate_array (int *array, int size) {
  int tmp = array[size - 1];
  memmove(array + 1, array, sizeof(int) * (size - 1));
  array[0] = tmp;
}

int main (int argc, char **argv) {
  int idx, max, tmp_array[MAX_MAX];

  if (argc > 1) {
    max = atoi(argv[1]);
    if (max <= MAX_MAX) {
      /* load the array */
      for (idx = 0; idx < max; ++idx) {
        tmp_array[idx] = idx + 1;
      }
      /* rotate, print, lather, rinse, repeat... */
      for (idx = 0; idx < max; ++idx) {
        rotate_array(tmp_array, max);
        printf("%d ", tmp_array[0]);
      }
      printf("\n");
    }
  }

  return 0;
}

And a common lisp solution treating lists as ints:

(defun foo (max)
  (format t "~{~A~^ ~}~%"
          (maplist (lambda (x) (length x)) (make-list max))))

Making this into an executable is probably the hardest part and is left as an exercise to the reader.

Common Lisp

Counting down from 7 (with recursion, or like here, using loop and downto):

(loop for n from 7 downto 1 do (print n))

Alternatively, perhaps a more amusing soluting. Using complex numbers, we simply add i squared repeatedly:

(defun complex-decrement (n)
  "Decrements N by adding i squared."
  (+ n (expt (complex 0 1) 2)))

(loop for n = 7 then (complex-decrement n)
      while (> n 0) do (print n))

I like recursive

function printCountDown(int x, int y) {
  if ( y != x ) printCountDown(x, y++);
  print y + " ";
}

You can also use multiplication

function printNto1(int x) {
  for(int y=x*(MAXINT*2+1);y<=(MAXINT*2+1);y++) {
    print (y*(MAXINT*2+1)) + " ";
  }
}

An alternative perl version could be:

#!/usr/local/bin/perl
print reverse join(" ",1 .. $ARGV[0]) . "\n";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top