البرمجة اللغز:العد التنازلي دون طرح [مغلقة]

StackOverflow https://stackoverflow.com/questions/763832

  •  11-09-2019
  •  | 
  •  

سؤال

حسنا الهدف على سبيل المثال :سطر الأوامر التطبيق الذي يفعل هذا:

Countdown.exe 7

يطبع 7 6 5 4 3 2 1

أي شكل من طرح (بما في ذلك استخدام علامة الطرح) أو سلسلة عكس ما حتى من أي وقت مضى هو مسموح به.

waaaaay من السهل جدا على ما يبدو :-) لمحة عامة عن إجابات (مبادئ على الأقل)

  1. عن طريق إضافة العودية
  2. باستخدام مودولو
  3. عن طريق دفع و ظهرت, (ربما أكثر وضوحا؟)
  4. باستخدام تجاوز
  5. باستخدام التجربة والخطأ (ربما أقل وضوحا؟)
هل كانت مفيدة؟

المحلول

ماذا عن الإضافة والمصاعدة؟

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

نصائح أخرى

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

إليك طريقة تفتقدها وتجركت وخطأ:

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

دفع 1-7 على كومة.البوب كومة واحدة.طباعة 7-1.:)

استخدم مجاملة 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.

اضغط على الأرقام في مخزن مؤقت سلسلة.

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

C / C ++، قليلا من تجاوز الحساب:

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

أشير إلى أنه لم ينشر أحد أغبى الإجابة الممكنة، لذلك سأذهب إلى الأمام وشاركه:

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

لا تكرهني: انظر؟ اعترفت انها غبية. :)

استخدام خطأ تقريب:

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

الحساب بيتس

مساحة ثابتة، مع عدم وجود إضافات أو طروقات أو مضاعف أو أقسام أو وحدة أو نفايات حسابية:

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

هذا ليس صعبا. استخدم مشغل Modulus.

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

نسخة بيثون:

import sys

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

هذا يخون، أليس كذلك؟

#!/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))

ابدأ بملف يحتوي على أرقام تنازينية من Max التي تهتم بها:

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]

نسخة سريعة وقذرة في 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
    }
}

زيادة عدد صحيح موقع مرت max_int ثم "إضافة" إلى العداد ... أو هل هذا ينظر في الطرح غير المشروع؟

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

كيندا سيئة ولكنه يفعل الوظيفة

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

هل نحن غولف هذا؟

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

هاسكل:

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 هذا: نمط المطابقة على إضافة رقمين. أنه عموما غير المستخدمة. وبعد طريقة أكثر اصطلاحية للقيام بذلك هي مع هذا الإصدار من Func:

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

أو، مع رقم واحد لكل سطر:

import System.Environment (getArgs)
import Data.Traversable

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

هل هذا العدد؟ يستخدم فقط تعليمات إضافة ...

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

بيرل:

$n = $ARGV[0];

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

الطرح هو وهم على أي حال

أحب فكرة ديلان بينيت - بسيطة، براغماتية وتلتزم بمبدأ القبيل، الذي IMHO هو أحد أهم المفاهيم التي يجب أن نحاول دائما مراعاةها عندما نقوم بتطوير البرمجيات. بعد كل شيء نكتب التعليمات البرمجية في المقام الأول بالنسبة للبشر الآخر للحفاظ عليه، وليس لأجهزة الكمبيوتر قراءتها. حل ديلان في جيد القديم ج:



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

في 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 القوائم ك Intts:

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

من المحتمل أن يجعل هذا في ملف قابل للتنفيذ هو الجزء الأصعب ويترك بمثابة تمرين للقارئ.

lisp المشترك

عد من 7 (مع العودية، أو مثل هنا، باستخدام loop و downto):

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

بدلا من ذلك، ربما أكثر تسلية التليمات. باستخدام أرقام معقدة، نضيف ببساطة أنا تربيع مرارا وتكرارا:

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

أنا أحب العودية

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

يمكن أن تكون نسخة بديلة بيرل:

#! / USR / المحلية / بن / بيرل طباعة العكس الانضمام (""، 1 .. $ argv [0]). "ن"؛
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top