2012-02-27 2 views
6

У меня была викторина, и я писал этот код:C программирование. Программа FizzBuzz

печати Fizz, если оно делится на 3 и печатает Buzz, если она делится на 5. Он печатает FizzBuss если делится на обоих. В противном случае он напечатает цифры от 1 до 100.

Но после того как я приехал домой, я подумал, может ли записать его с меньшим количеством кода. Однако я не смог выйти с более коротким кодом. Могу ли я сделать это с более коротким кодом? Благодарю.

Это то, что я написал, и я думаю, что он работает хорошо. Но могу ли я сделать это с меньшим количеством кода.

#include <stdio.h> 

int main(void) 
{ 
    int i; 
    for(i=1; i<=100; i++) 
    { 
     if(((i%3)||(i%5))== 0) 
      printf("number= %d FizzBuzz\n", i); 
     else if((i%3)==0) 
      printf("number= %d Fizz\n", i); 
     else if((i%5)==0) 
      printf("number= %d Buzz\n", i); 
     else 
      printf("number= %d\n",i); 

    } 

    return 0; 
} 
+0

Является ли это домашнее задание? (Кстати, действительно ли вы намеревались оптимизировать первое, если бы заявление было так много? :( – Francois

+1

stack exchange имеет сайт codegolf. Я верю –

+0

Этот вопрос имеет тенденцию побеждать тех, кто пытается быть умным. Вы можете сделать его короче, но тогда это – ugoren

ответ

7

Если число делится на оба 3 и 5, то это делится на 15, так:

for each number 1 to 100: 
    if number % 15 == 0: 
     print number, "fizzbuzz" 
    else if number % 5 == 0: 
     print number, "buzz" 
    else if number % 3 == 0: 
     print number, "fizz" 
    else: 
     print number 

Кроме этого, вы, вероятно, не получите намного короче, по крайней мере, обычный язык, такой как C (и я предполагаю, что вы не хотите, чтобы обычные модификации стиля кода и гольфа делали ваш код нечитаемым).

Вы также можете получить все это в две строки, если вы упаковали всю функцию main на одну большую линию, но я надеюсь, что вы не будете после этого обмана.

Возможно, вы можете получить его быстрее (хотя вы должны проверить все требования производительности для себя) с чем-то вроде:

static const char *xyzzy[] = { 
    "",  "",  "fizz", "",  "buzz", 
    "fizz", "",  "",  "fizz", "buzz", 
    "",  "fizz", "",  "buzz", "fizzbuzz", 
    // Duplicate those last three lines to have seven copies (7x15=105). 
}; 
for (int i = 1; i <= 100; i++) 
    printf ("%d %s\n", i, xyzzy[i-1]); 

Как и в сторону, что массив символьных указателей, вероятно, будет менее пространственно дорогой, чем вы думаете, благодаря постоянному объединению - другими словами, вероятно, что будет только один каждой строки C.

Как я уже сказал, нужно ли тестировать быстрее. Кроме того, в ваших оригинальных спецификациях вызывается только кратчайший код, поэтому он может быть неактуальным.

+0

Спасибо. Это правда. Для первого теста я мог подумать об этом только в одном номере. Я буду учитывать это в будущих упражнениях. Благодарю. – leocod

11

Вы также можете сделать:

#include <stdio.h> 

int main(void) 
{ 
    int i; 
    for(i=1; i<=100; ++i) 
    { 
     if (i % 3 == 0) 
      printf("Fizz"); 
     if (i % 5 == 0) 
      printf("Buzz"); 
     if ((i % 3 != 0) && (i % 5 != 0)) 
      printf("number=%d", i); 
     printf("\n"); 
    } 

    return 0; 
} 

Несколько строк короче и намного легче читать.

+0

Спасибо. Он выглядит короче. – leocod

+0

Если вы всегда не указали номер, вы также можете лишить строку, выполнив printf («number =% d», i) вверху и удалив последнее, если. – martiert

+0

'if ((i% 3! = 0) && (i% 5! = 0))' фактически может быть просто записано как 'if (i% 3 && i% 5)'. 'i% 3' и' i% 5' в этом случае возвратят ненулевые числа, которые будут вычисляться как true. – fbonetti

2

Я бы сказал, что modulo стоит дорого, в то время как сравнение дешево, поэтому выполняйте только один модуль. Это даст что-то подобное.

int i; 
for(i = 0; i!=100; ++i) { 
    bool bModThree = !(i % 3); 
    bool bModFive = !(i % 5); 

    if(bModThree || bModFive) { 
     if(bModThree) { 
      printf("Fizz"); 
     } 
     if(bModFive) { 
      printf("Buzz"); 
     } 
    } else { 
     printf("%d", i); 
    } 

    printf("\n"); 
} 
+0

Вы не должны всегда печатать номер. – franklynd

+0

@franklynd Ах черт. Ты прав. Я обновил ответ с лучшим примером. – Kenneth

7

Я не уверен, когда вы начнете называть его нечитаемым, но это так.

#include <stdio.h> 

int main(void) 
{ 
    int i = 1; 
    for (; i<=100; ++i) { 
     printf("number= %d %s%s\n", i, i%3?"":"Fizz", i%5?"":"Buzz"); 
    } 
    return 0; 
} 
+0

Он работает хорошо, и он короче. Благодарю. – leocod

+0

Я уверен, что решение paxdiablo работает быстрее, и даже не намного дольше. –

+1

Ну, честно говоря, вопрос задавался короче, а не быстрее :-) Если вы заявили 'i' в' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' +1. – paxdiablo

-3

Запутанный форма ответа г Листера

main(int i){while(i++<100){printf("number= %d %s%s",i,i%3?"":"Fizz",i%5?"":"Buzz");}}

+2

Это не обфускация (удаление разрывов строк вряд ли обфускация), это неправильно. – Davidmh

1

я бы написать что-то вроде этого

main(){ 
    if (i % 3 == 0){ 
    cout<<"Fizz"; 
    } 
    if (i % 5 == 0){ 
    cout<<"Buzz"; 
    } 
    // So if both are true, it will print “FizzBuzz” and augment the two strings 
    } 
+2

Вы не печатаете номер. – franklynd

+2

Этот вопрос касался программирования на C, а не программирования на С ++, поэтому это решение не будет работать. – user530873

0
#include <stdio.h> 

char const * template[] = { 
    "%i", 
    "Buzz", 
    "Fizz", 
    "FizzBuzz" 
}; 
const int __donotuseme3[] = { 2, 0, 0 }; 
const int __donotuseme5[] = { 1, 0, 0, 0, 0 }; 
#define TEMPLATE(x) (template[__donotuseme3[(x) % 3] | __donotuseme5[(x) % 5]]) 

int 
main(void) { 
    int i; 
    for (i = 1; i <= 100; i++) { 
    printf(TEMPLATE(i), i); 
    putchar('\n'); 
    } 
    return 0; 
} 
0

Это один избегает некоторые повторения кода, но требует временного переменная char t

void FizzBuzz() { 
    char t = 0; 
    for (unsigned char i = 1; i <= 100; ++i, t = 2) { 
     (i % 3) ? --t : printf("Fizz"); 
     (i % 5) ? --t : printf("Buzz"); 
     if (!t) printf("%d", i); 
     printf("\n"); 
    } 
} 
0
void main() 
{ 
    int i = 0; 
    char h[4]; 

    while (++i <= 100) 
    { 
     sprintf(h, "%d", i); 
     printf("%s%s%s\n", i%3 ? "" : "fizz", i%5 ? "" : "buzz", (i%3 && i%5) ? h: ""); 
    } 
} 
+2

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и/или почему оно решает проблему, улучшит долгосрочную ценность ответа. –

0

Вы можете сделать это с помощью строки:

String s=""; 
if(num%3==0) 
    s+="fizz"; 
if(num%5==0) 
    s+="buzz"; 
if(s.length()==0) 
    s+=num+""; 
+0

Измените свой пост, чтобы текст не был отформатирован как код. –

+0

В обычном C нет типа «String». В C++ есть 'std :: string' (строчные буквы!), Но этот вопрос отмечен C. –

+0

Я просто сосредоточен на альго. Надеюсь, вы сможете это понять! –

0

Я бы с вспомогательной функцией :-)

#include <stdio.h> 

int fbindex(int n) { 
    int i = 0; 
    if (n % 3 == 0) i += 1; 
    if (n % 5 == 0) i += 2; 
    return i; 
} 

int main(void) {         
    const char *fb[] = {"%d\n", "Fizz\n", "Buzz\n", "FizzBuzz\n"}; 
    for (int i = 1; i <= 100; i++) printf(fb[fbindex(i)], i);     
}