18

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?)
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
Peter
  • 47,963
  • 46
  • 132
  • 181

37 Answers37

46
x = param;
while (x > 0) {
    print x;
    x = (x + param) mod (param + 1);
}
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 1
    +1 for good use of modulo arithmetic. – Don Werve Apr 18 '09 at 18:30
  • Mod is division, which by definition is a form of subtraction. I would say that this doesn't count. – Scott Wisniewski Apr 18 '09 at 19:24
  • 1
    Modulus is not division. q(x) != r(x). Math solved this problem. – Stefan Kendall Apr 18 '09 at 22:15
  • clever subtraction! me like ^_^ – hasen Apr 19 '09 at 01:56
  • 1
    @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 Jun 22 '09 at 18:02
  • @ScottWisniewski Interpret "form of subtracting" widely enough and every solution to this problem becomes invalid. Even the solution I thought of involves subtraction, a massive string of ascii numbers that count down and a massive array of integers that index into it. But subtraction is only involved when I'm typing out the data. :) Then again, the requirements never specified that 8 and above would have to work. Hmm... ;) – candied_orange Nov 17 '14 at 05:49
38

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
  • 733,204
  • 149
  • 1,241
  • 1,454
17

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
  • 6,688
  • 2
  • 27
  • 23
15

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

JP Alioto
  • 44,864
  • 6
  • 88
  • 112
13

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

Graeme Perrow
  • 56,086
  • 21
  • 82
  • 121
Scott Langham
  • 58,735
  • 39
  • 131
  • 204
  • Although isn't what you are doing essentially subtracting, since you're adding negative 1? – JSchlather Jun 19 '09 at 18:45
  • 1
    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 Jun 21 '09 at 20:36
11

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
  • 179,021
  • 58
  • 319
  • 408
11

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

void Print(int max)
{
   for( int i = max; i > 0; i += 0xFFFFFFFF )
   {
      printf("%d ", i);
   }
}
Scott Langham
  • 58,735
  • 39
  • 131
  • 204
10

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
  • 44,462
  • 20
  • 138
  • 192
8

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
  • 58,735
  • 39
  • 131
  • 204
7

This is not hard. Use the modulus operator.

for (int n = 7; n <= 49; n += 7) {
  print n mod 8;
}
mpen
  • 272,448
  • 266
  • 850
  • 1,236
Dylan Bennett
  • 1,615
  • 3
  • 17
  • 20
7

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
  • 6,592
  • 1
  • 30
  • 34
3

A python version:

import sys

items = list(xrange(1, int(sys.argv[1])+1))
for i in xrange(len(items)):
    print items.pop()
ChristopheD
  • 112,638
  • 29
  • 165
  • 179
3

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
  • 599
  • 2
  • 7
  • 10
2

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
  • 11,147
  • 11
  • 58
  • 104
1

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
  • 1
  • 1
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
    }
}
andri
  • 11,171
  • 2
  • 38
  • 49
1

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

Assaf Lavie
  • 73,079
  • 34
  • 148
  • 203
1
    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 De Irisarri
  • 1,077
  • 1
  • 14
  • 27
1
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
  • 5,391
  • 1
  • 18
  • 17
1
// 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
  • 58,735
  • 39
  • 131
  • 204
1

Are we golfing this?

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

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

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
Gracenotes
  • 2,922
  • 1
  • 15
  • 8
0

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
  • 402
  • 2
  • 5
0

PHP

<?=implode(",", array_reverse( range(1, $_GET['limit']) ) )?>
TJ L
  • 23,914
  • 7
  • 59
  • 77
0

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
  • 21,302
  • 14
  • 69
  • 94
0

Another Scala implementation

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

Perl:

$n = $ARGV[0];

while ($n > 0) {
  print "$n ";
  $n = int($n * ($n / ($n+1)));
}
Chris Thornhill
  • 5,321
  • 1
  • 24
  • 21
0

subtraction is an illusion anyways

leed25d
  • 643
  • 6
  • 13
  • 8
    in that case, please subtract the balance of your bank account and give it to me. (assuming it's not already negative) – Scott Langham Apr 19 '09 at 09:41
0

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

0

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.

0

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
  • 399
  • 4
  • 10
0

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

An alternative perl version could be:

#!/usr/local/bin/perl
print reverse join(" ",1 .. $ARGV[0]) . "\n";
andygavin
  • 2,784
  • 22
  • 32
-1

What about adding negative 1?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • no, that's subtracting by one by very definition. To make it more clear :don't use the minus sign – Peter Apr 18 '09 at 17:53
-1

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
  • 1,425
  • 2
  • 9
  • 8
-1

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,355
  • 3
  • 21
  • 28