编程之谜:无需减法计数

时间:2009-04-18 17:48:08

标签: puzzle

好的,以示例为目标:执行此操作的命令行应用程序:

Countdown.exe 7

打印7 6 5 4 3 2 1

不允许任何形式的减法(包括使用减号)或字符串反转。

waaaaay显然太容易了:-)概述答案(至少是原则)

  1. 通过添加和递归
  2. 使用modulo
  3. 通过推动和弹出,(也许是最明显的?)
  4. 使用溢出
  5. 使用反复试验(可能最不明显?)

37 个答案:

答案 0 :(得分:46)

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

答案 1 :(得分:38)

添加和递归怎么样?

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

答案 2 :(得分:17)

这是你错过的方法,试验和错误:

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

答案 3 :(得分:15)

将1-7推入堆栈。弹出堆栈一个接一个。打印7-1。 :)

答案 4 :(得分:13)

使用2的补码,毕竟这是计算机处理负数的方式。

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

请参阅http://en.wikipedia.org/wiki/2's_complement

答案 5 :(得分:11)

c / c ++,有点算术溢出:

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

答案 6 :(得分:11)

将数字前置到字符串缓冲区中。

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

答案 7 :(得分:10)

我注意到没有人发布最愚蠢的回答,所以我会继续分享它:

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

不要恨我:看?我承认这是愚蠢的。 :)

答案 8 :(得分:8)

使用舍入错误:

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

答案 9 :(得分:7)

按位算术

恒定空间,没有加法,减法,乘法,除法,模数或算术否定:

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

答案 10 :(得分:7)

这并不难。使用模数运算符。

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

答案 11 :(得分:3)

这是作弊,对吧?

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

只是为了好玩,它的递归兄弟:

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

答案 12 :(得分:3)

python版本:

import sys

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

答案 13 :(得分:2)

从包含从您感兴趣的最大数字开始的降序编号的文件开始:

7 6 5 4 3 2 1

然后......这只能达到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]

答案 14 :(得分:1)

这算得上吗?仅使用添加指令...

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

答案 15 :(得分: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

称为n + k模式的'特征'允许这样:在添加两个数字时进行模式匹配。它是generally not used。一个更惯用的方法是使用这个版本的func:

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

或,每行一个数字:

import System.Environment (getArgs)
import Data.Traversable

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

答案 16 :(得分:1)

#!/usr/bin/env ruby

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

答案 17 :(得分: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 );
        }
    }

有点讨厌,但它完成了工作

答案 18 :(得分:1)

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

答案 19 :(得分:1)

增加一个有符号整数传递max_int然后“加”到计数器......或者这是否算是非法减法?

答案 20 :(得分: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);
        }
    }
}

答案 21 :(得分: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);
   }
}

答案 22 :(得分:1)

我们打高尔夫吗?

import sys
for n in reversed(range(int(sys.argv[1]))):print n+1,

答案 23 :(得分:0)

在C中,使用旋转内存块(注意,不是我引以为傲的东西......):

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

一个常见的lisp解决方案将列表视为int:

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

将其变成可执行文件可能是最困难的部分,并留给读者练习。

答案 24 :(得分:0)

Common Lisp

从7开始倒计时(使用loopdownto进行递归,或者像这里一样):

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

或者,也许是一个更有趣的解决方案。使用复数,我们只需重复加上i平方:

(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))

答案 25 :(得分:0)

我喜欢Dylan Bennett的想法 - 简单,实用,并且遵循K.I.S.S原则,恕我直言是我们在开发软件时应该始终牢记的最重要的概念之一。毕竟我们主要为其他人编写代码来维护它,而不是计算机来读它。迪伦在旧C中的解决方案:



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

答案 26 :(得分:0)

另一个Scala实现

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

答案 27 :(得分:0)

的Perl:

$n = $ARGV[0];

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

答案 28 :(得分:0)

我喜欢递归

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

您也可以使用乘法

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

答案 29 :(得分:0)

另一种perl版本可能是:

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

答案 30 :(得分: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]);

答案 31 :(得分:0)

<强> PHP

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

答案 32 :(得分:0)

现在滥用字符串函数!

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

答案 33 :(得分:0)

无论如何,减法是一种幻觉

答案 34 :(得分:-1)

添加否定1怎么样?

答案 35 :(得分:-1)

输出到临时字符串,然后将其反转,然后反转单个数字:

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

答案 36 :(得分:-1)

从-7&amp;不要打印减号:

#!/usr/bin/env python
for i in range(-7, 0): print str(i)[1],