2012-05-16 10 views
7

Per coloro che non conoscono, FizzBuzz è il seguente problema:FizzBuzz senza operatore AND

Scrivere un programma che stampa i numeri da 1 a 100. Ma per multipli di tre di stampa "Fizz", invece del numero e per i multipli di cinque caratteri "Buzz". Per i numeri che sono multipli di entrambi i numeri tre e cinque stampano "FizzBuzz".

soluzione Ogni FizzBuzz trovo è o qualche soluzione esoterica folle fatta per il gusto di essere originale, o la vostra base else if-chain:

for(int i = 1; i <= 100; i++) { 

if(i % 3 == 0 && i % 5 == 0) { 
    System.out.println("FizzBuzz"); 
} else if (i % 3 == 0) { 
    System.out.println("Fizz"); 
} else if (i % 5 == 0) { 
    System.out.println("Buzz"); 
} else { 
    System.out.println(i); 
} 
} 

Sto cercando una soluzione semplice che si propone di estrarre la dichiarazione "FizzBuzz". Ho questo in mente:

for(int i = 1; i <= 100; i++) { 

if (i % 3 == 0) 
    System.out.print("Fizz"); 
if (i % 5 == 0) 
    System.out.println("Buzz") 
else 
    System.out.println(i); 
} 

Ma questo non funziona. Immagino che sarebbe in grado di stampare FizzBuzz inserendo ifs, Fizz e Buzz, ma se il numero è, ad esempio, 3, stamperebbe Fizz3. Come posso evitare questo?

+0

Perché dovrebbe essere "else if" invece della seconda istruzione "if";) –

+0

@ThomasJungblut No, perché quindi il caso FizzBuzz non funzionerà necessariamente. –

+0

@ThomasJungblut, No, vuole mettere insieme il Fizz e il Buzz, quindi lascia intenzionalmente il primo se. – Igor

risposta

9

Quello che stai cercando di fare è

if (a) 
    ... 
if (b) 
    ... 
else // if neigther a nor b 
    ... 

Questo è semplicemente non possibile. Un else può appartenere solo a un singolo if. Devi andare con la variante leggermente più lunga.

Per evitare di fare valutazioni ridondanti del operatore modulo, si potrebbero formulare corpo del ciclo come

boolean fizz = i % 3 == 0; 
boolean buzz = i % 5 == 0; 

if (fizz) 
    System.out.print("Fizz"); 
if (buzz) 
    System.out.print("Buzz"); 
if (!(fizz || buzz)) 
    System.out.print(i); 

System.out.println(); 

Un altro sarebbe

String result = ""; 

if (i % 3 == 0) result = "Fizz"; 
if (i % 5 == 0) result += "Buzz"; 
if (result == "") result += i; 

System.out.println(result); 
+1

Ah, ma questo ha un '&&' in esso. ;-) –

+0

Modificato secondo la regola del demorgan ... è questo inganno? :-) btw, questo probabilmente appartiene a http://codegolf.stackexchange.com/ – aioobe

+1

Beh, stavo solo scherzando. Solo il titolo menziona specificamente l'operatore AND. Penso che il vero obiettivo sia in qualche modo avere solo due istruzioni if ​​più il numero case, che la tua soluzione incorpora. Inoltre, hai un +1. –

2

Se il vostro unico obiettivo è quello di evitare l'uso di &&, si potrebbe utilizzare una doppia negazione e le leggi di De Morgan:

for(int i = 1; i <= 100; i++) { 

    if(!(i % 3 != 0 || i % 5 != 0)) { 
     System.out.println("FizzBuzz"); 
    } else if (i % 3 == 0) { 
     System.out.println("Fizz"); 
    } else if (i % 5 == 0) { 
     System.out.println("Buzz"); 
    } else { 
     System.out.println(i); 
    } 
} 

È possibile evitare && sfruttando il fatto che i % 3 == 0 e i % 5 == 0 implica i % 15 == 0, come da RFC1337's answer.

Un'altra soluzione è quella di utilizzare un switch sul resto (mod 15, che è 5 volte 3):

for(int i = 1; i <= 100; i++) { 
    final int mod = i % 15; 
    switch (mod) { 
     case 0: 
     case 3: 
     case 6: 
     case 9: 
     case 12: 
      System.out.print("Fizz"); 
      if (mod != 0) break; 
     case 5: 
     case 10: 
      System.out.print("Buzz"); 
      break; 
     default: 
      System.out.print(i); 
    } 

    System.out.println(); 
} 
+0

memorizza appena i% 15 in alto invece di calcolare il modulo due volte. – ranman

+0

Buon punto @ranman, modificato. –

+0

Esiste una penalizzazione delle prestazioni nel dichiarare una variabile finale più e più volte? Mi sembra di ricordare di essermi imbattuto in quegli anni e anni fa, ma ora non riesco a trovare alcun riferimento. – ranman

3

Il tuo primo if è tutto solo.

Così, il tuo codice raggiunge la prima istruzione, che è SOLO un'istruzione if, e quindi passa alla successiva, che è un'istruzione if/else.

RosettaCode ha un buon esempio senza utilizzare gli operatori AND.

int i; 
    for (i = 0; i <= 100; i++) { 
      if ((i % 15) == 0) 
        cout << "FizzBuzz" << endl; 
      else if ((i % 3) == 0) 
        cout << "Fizz" << endl; 
      else if ((i % 5) == 0) 
        cout << "Buzz" << endl; 
      else 
        cout << i << endl; 
    } 
+0

Penso che l'intenzione fosse di riutilizzare il 'Fizz' quando si scrive' FizzBuzz'. – aioobe

+1

@aioobe Sì, e penso che questo potrebbe essere facilmente adattato con un po 'più di nidificazione di condizionali. Stavo per suggerire un caso interruttore, ma [Platinum Azure] (http://stackoverflow.com/a/10620230/1397668) già fornito un esempio per questo. – RFC1337

0

Basta aggiungere una variabile di bandiera e utilizzare System.out.print:

package com.stackoverflow; 

public class FizzBuzz { 
    public static void main(String[] args) { 
     for (int i = 1; i <= 100; i++) { 
      boolean printed = false; 
      if (i % 3 == 0) { 
       printed = true; 
       System.out.print("Fizz"); 
      } 
      if (i % 5 == 0) { 
       printed = true; 
       System.out.print("Buzz"); 
      } 

      if (printed) { 
       System.out.println(); 
      } else { 
       System.out.println(i); 
      } 
     } 
    } 
} 
0

Ciò non estrarre il if, ma non utilizzare l'operatore & & (e), si potrebbe capovolgere gli operatori binari .

//FizzBuzz Case 
if(!(a % 3 != 0 || a % 5 != 0)){ //flips 
    result[index] = "FizzBuzz"; 
    index++; 
    } 
0

Pazzo seppur soluzione non correlati fatto in python3

#!/usr/bin/python3 

for i in range(1,100): 
    msg = "Fizz" * bool(i%3==0) 
    msg += "Buzz" * bool(i%5==0) 
    if not msg: 
     msg = i 
print(msg) 
0

Non utilizzare un'istruzione if a tutti.

import java.util.*; 
import java.lang.*; 
import java.io.*; 
class FizzBuzz 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     String[] words = {"", "Fizz", "Buzz"}; 
     String[] nwords = {"", ""}; 

     for(int i = 1; i < 101; ++i) 
     { 
      int fp = (i % 3 == 0) ? 1 : 0; 
      int bp = ((i % 5 == 0) ? 1 : 0) * 2; 
      int np = ((fp > 0 || bp > 0) ? 1: 0); 

      nwords[0] = Integer.toString(i); 

      System.out.print(words[fp]); 
      System.out.print(words[bp]); 
      System.out.println(nwords[np]); 
     } 
    } 
} 

Vedere su ideone.

+0

non valido coz (i% 3 == 0)? 1: 0 è un'affermazione if, infatti – maxormo

1

Questa è la mia soluzione. Certo, è un po 'contorto (come nella rotatoria), ma credo che sia adatto alle tue esigenze.

int main() 
{ 
    char fizzpass=0; 

    unsigned short index=0; 

    for(index=1;index<=100;index++) 
    { 
     if(0 == (index%3)) 
     { 
      printf("Fizz"); 
      fizzpass = 1; 
     } 

     if(0 == (index%5)) 
     { 
      if(1 == fizzpass) 
      {     
       fizzpass = 0; 
      } 

      printf("Buzz\n"); 
      continue; 
     } 

     if(1 == fizzpass) 
     { 
      fizzpass = 0; 
      printf("\n"); 
      continue; 
     } 

     printf("%d\n",index); 
    } 

    return 0; 
} 

Saluti.

Problemi correlati