tags:

views:

3781

answers:

38

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?)
A: 

What about adding negative 1?

Daniel A. White
no, that's subtracting by one by very definition. To make it more clear :don't use the minus sign
Peter
+36  A: 

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);
}
JaredPar
That would not work the way he has it as a parameter. But it could be modified.
Daniel A. White
@Daniel, see the updated sample
JaredPar
Yea. I guess you updated when i was typing that.
Daniel A. White
haha, exact the solution i came up with, I searched a bit longer I must admit.
Peter
Doest it make sense in CW to accept an answer?
Peter
@Peter, I think generally speaking most people eventually accept an answer for a community WIKI question. It's by no means required though.
JaredPar
I meant : does rep still counts for the answerer? I accept an answer in any way, but will wait a bit , cause I don't want people to stop answering
Peter
@Peter, people get 0 rep for votes on a community WIKI answer (up or down). I think the person who's answer is accepted still gets the 15 points.
JaredPar
nice one really.
dr. evil
It's not for me to judge the solutions, just a bit of fun after all, so I accept whoever answered correctly first, and that was you.
Peter
Why do i always find it hard to think of recursion? :S
Galilyou
@Galilyou - the answer is here http://stackoverflow.com/questions/763832/programming-riddle-counting-down-without-subtracting/763838#763838
Tim Post
+45  A: 
x = param;
while (x > 0) {
    print x;
    x = (x + param) mod (param + 1);
}
jos
+1 for good use of modulo arithmetic.
Don Werve
Mod is division, which by definition is a form of subtraction. I would say that this doesn't count.
Scott Wisniewski
Modulus is not division. q(x) != r(x).Math solved this problem.
Stefan Kendall
clever subtraction! me like ^_^
hasen j
@Scott — I would content that neither of those statements are true. Modulus is typically *defined in terms of* division, but that doesn't *make it* division. Ditto for division != subtraction.
Ben Blank
+1 for the simplicity
Agusti-N
+12  A: 

Prepend the numbers into a string buffer.

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

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
    }
}
andri
There's a minus sign!! .... I'm kidding :-P
chakrit
+1  A: 

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

Assaf Lavie
It's another case of overflow, ok for me
Peter
+15  A: 

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

JP Alioto
isnt't it considered array reversion??
Nicolas Irisarri
There are many many ways to implement a stack.
JP Alioto
The recursive solution just used the call stack as its stack; this is simply a not-necessarily-recursive interpretation.
Stefan Kendall
The callstack is not a data structure.
JP Alioto
@JP, so if you want to countdown from 100.000.000 you will create a stack of 100.000.000 elements and then pop the stack.....
Agusti-N
+1  A: 
 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

Nicolas Irisarri
+12  A: 

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

void Print(int max)
{
   for( int i = max; i > 0; i += 0xFFFFFFFF )
   {
      printf("%d ", i);
   }
}
Scott Langham
damn.. 39 seconds faster ;)
fforw
Technically, adding a negative number is performing subtraction! d=
sybreon
does not work when int==64bit
friol
yes, true. i think my other answer with the 2's compliment was probably better. this is just an optimization of that that happens to require a 32 bit machine.
Scott Langham
This is the solution I thought of first :)
Trap
+1  A: 
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);
        }
    }
}
fforw
looks strangely familiar, i like it though! worthy of an up vote.
Scott Langham
+7  A: 

This is not hard. Use the modulus operator.

for (int n = 7; n <= 49; n += 7) {
  print n mod 8;
}
Dylan Bennett
upvoted for creativity, but please fix the infinite loop
wowest
The idea is good, but it doesn't work for any n other than 7.
Kevlar
A: 
// 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);
   }
}
Scott Langham
+3  A: 

A python version:

import sys

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

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);
   }
}
Scott Langham
Pretty nifty, Scott. Way to exploit type-casting.
The Wicked Flea
Thanks! .
Scott Langham
A: 

Perl:

$n = $ARGV[0];

while ($n > 0) {
  print "$n ";
  $n = int($n * ($n / ($n+1)));
}
Chris Thornhill
+11  A: 

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

Scott Langham
Although isn't what you are doing essentially subtracting, since you're adding negative 1?
Jacob Schlather
Well, the result is the same as if a subtraction had been done, but you'll see the example uses a +=, so it's a plus. But, the effect is the same as if a subtraction had been done. But, you could argue the effect of any other answer to this question is to have subtracted 1... so you could also say this answer is essentially the same as 'adding and recursion', which is the accepted answer. Or you could say it's essentially the same as prepending numbers into a string buffer or whatever. :)
Scott Langham
+1  A: 

Are we golfing this?

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

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

subtraction is an illusion anyways

leed25d
in that case, please subtract the balance of your bank account and give it to me. (assuming it's not already negative)
Scott Langham
+1  A: 

Haskell:

import System.Environment (getArgs)

func :: Integer -> [String]
func 0 = []
func [email protected](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
Gracenotes
A: 

Count up from -7 & don't print the minus sign:

#!/usr/bin/env python
for i in range(-7, 0): print str(i)[1],
Toby White
The problem called for no form of subtraction, including using a minus sign. You didn't meet that requirement.
abelenky
Yeah but he's a cheeky bastard!
ChristianLinnell
+3  A: 

Back in my day we did our own homework.

Ted Dziuba
A: 

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);
        }
}

A: 

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.

A: 

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))
Sebastian Krog
+2  A: 

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))
not-too-smatr
+7  A: 

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;
}
Boojum
What a clever solution! +1
Trap
Btw you could get rid of that 'else'
Trap
+14  A: 

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;
        }
    }
}
kenj0418
got a chuckle out of that one...
jim
A: 

Output to temporary string, then reverse it, then reverse individual numbers:

string ret;
for(int i=0;i<atoi(argv[1]);i++)
  ret += " " + itoa(i);

for(int i=0;i<ret.length()/2;i++)
   exchange(ret[i],ret[ret.length()-i-1]);

for(const char* t=&ret[0];t&&strchr(t,' ');t=strchr(t,' '))
for(int i=0;i<(strchr(t,' ')-t)/2;i++)
   exchange(t[i],t[strchr(t,' ')-t-1]);

printf(ret.c_str());
AareP
+2  A: 

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]
justinhj
A: 

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)) + " ";
  }
}
A: 

An alternative perl version could be:

#!/usr/local/bin/perl
print reverse join(" ",1 .. $ARGV[0]) . "\n";
andygavin
A: 

C:

char buf[2][50];
int buf_no, i;

buf_no = buf[0][0] = buf[1][0] = 0;

for (i = 1; i <= 7; ++i, buf_no = !buf_no) 
 sprintf(buf[buf_no], "%d %s", i, buf[!buf_no]);

printf(buf[!buf_no]);
Mark Jones
A: 

PHP

<?=implode(",", array_reverse( range(1, $_GET['limit']) ) )?>
tj111
A: 

And now for abusing string functions!

using System;
public class Countdown {
    public static void Main(string[] args){
        int start = 10;
        string buffer;
        if (args.Length > 0) start = int.Parse(args[0]);
        buffer = "".PadRight(start, 'z');
        while (buffer.Length > 0){
            Console.Write(buffer.Length.ToString() + " ");
            buffer = buffer.Substring(1);
        }
        Console.WriteLine();
    }
}
MiffTheFox
+9  A: 

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. :)

Steven Fisher
A: 

Another Scala implementation

class Countdown(countFrom: Int, countTo: Int) {
  def printListInReverse() = {
    val standardCount = for (i <- countFrom to countTo) yield i
    println(standardCount.reverse.mkString(" "))
  }
}
Mond Ray Mond
+1  A: 

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;
}
Paul

related questions