36
\$\begingroup\$

Given a snippet of fizz buzz output with all numbers removed, fill in the correct numbers with the lowest possible values such that the fizz buzz snippet is correct. For the purposes of this challenge, fizz and buzz have their usual values of 3 and 5, respectively.

If the input is an invalid sequence of fizz, buzz and empty lines, then instead output just zzubzzif (with or without newlines).

Input and output may be newline separated lines, or whatever array-of-strings format is convenient to your language.

You may ignore or do whatever you like with capitalisation.

You will need to choose to handle one or more of these: fizzbuzz, fizz buzz, buzz fizz, etc, but you must choose at least one of these formats.

You may assume that all input is some sequence of fizz, buzz and empty lines.

Examples

Input:

fizz

Output:
2
fizz
4
Input:
buzz
fizz

Output:
buzz
fizz
7
Input:


fizzbuzz


Output:
13
14
fizzbuzz
16
17
Input:

Output:
1
Input:
fizz
fizz

Output:
zzubzzif
Input:



Output:
zzubzzif
\$\endgroup\$
17
\$\begingroup\$

Java, 205 bytes

s->{o:for(int i=0,j,h=s.length;++i<16;){for(j=h;j-->0;)if(s[j].contains("fizz")^(i+j)%3<1||s[j].contains("buzz")^(i+j)%5<1)continue o;String z=i+"";for(j=1;j<h;)z+="\n"+(i+j++);return z;}return"zzubzzif";}

Takes a String[] as input and returns a String.

Expanded, runnable code:

public class C {

    static final java.util.function.Function<String[], String> f = s -> {
        o:
        for (int i = 0, j, h = s.length; ++i < 16;) {
            for (j = h; j --> 0;) {
                if (s[j].contains("fizz") ^ (i + j) % 3 < 1 ||
                    s[j].contains("buzz") ^ (i + j) % 5 < 1) {
                    continue o;
                }
            }
            String z = i + "";
            for (j = 1; j < h;) {
                z += "\n" + (i + j++);
            }
            return z;
        }
        return "zzubzzif";
    };

    public static void main(String[] args) {
        System.out.print(f.apply(new String[]{"fizz", "", "buzz"}));
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ s/fizz/f, s/buzz/b \$\endgroup\$ – djechlin Oct 16 '15 at 21:57
10
\$\begingroup\$

C#, 212 bytes

I did the unthinkable. I used a goto statement to break out of a loop!

string[]R(string[]a){for(int i,l=a.Length,n=0;n++<15;){for(i=l;i-->0;)if(((n+i)%3<1?"fizz":"")+((n+i)%5<1?"buzz":"")!=a[i])goto z;for(i=l;i-->0;)a[i]=a[i]==""?""+(n+i):a[i];return a;z:;}return new[]{"zzubzzif"};}

This takes advantage of the fact that the sequence must start within the first 15 elements.

Indentation and new lines for readability:

string[]R(string[]a){
    for(int i,l=a.Length,n=0;n++<15;){
        for(i=l;i-->0;)
            if(((n+i)%3<1?"fizz":"")+((n+i)%5<1?"buzz":"")!=a[i])
                goto z;
        for(i=l;i-->0;)
            a[i]=a[i]==""?""+(n+i):a[i];
        return a;
    z:;
    }
    return new[]{"zzubzzif"};
}
\$\endgroup\$
  • \$\begingroup\$ does C# not have a break keyword? \$\endgroup\$ – cat Dec 16 '15 at 22:15
  • 2
    \$\begingroup\$ @cat, it does, but the goto jumps out of the inner loop and over the rest of the outer loop's logic. \$\endgroup\$ – Hand-E-Food Dec 16 '15 at 23:59
  • \$\begingroup\$ First time I heard about goto on C#! Didn't even know C# had it! \$\endgroup\$ – sergiol Jun 25 '17 at 20:55
4
\$\begingroup\$

CJam, 72 bytes

"zzubzzif":MaqN/:Q,_F+{)_[Z5]f%:!MW%4/.*s\e|}%ew{:sQ1$A,sff&:s.e|=}=N*o;

The program will exit with an error if it has to print zzubzzif.

Using the Java interpreter, STDERR can be closed to suppress an eventual error message. If you try the program in the CJam interpreter, ignore all output after the first line.

How it works

"zzubzzif" e# Push that string.
:Ma        e# Save it in M and wrap in in an array.
qN/:Q      e# Split the input into lines and save in Q.
,_F+       e# Count the lines and add 15 to a copy of the result.
{          e# For each integer I between 0 and lines+14:
  )_       e#   Increment I and push a copy.
  [Z5]     e#   Push [3 5].
  f%       e#   Map % to push [(I+1)%3 (I+1)%5].
  :!       e#   Apply logical NOT to each remainder.
  MW%4/    e#   Push ["fizz" "buzz"].
  .*       e#   Vectorized string repetition.
  s\       e#   Flatten the result and swap it with I+1.
  e|       e#   Logical OR; if `s' pushed an empty string, replace it with I+1.    
}%         e#
ew         e# Push the overlapping slices of length "lines".
{          e# Find; for each slice:
  :s       e#   Cast its elements to string (e.g., 1 -> "1").
  Q1$      e#   Push the input and a copy of the slice.
  A,s      e#   Push "0123456789".
  ff&      e#   Intersect the slice's strings' characters with that string.
  :s       e#   Cast the results to string. This replaces "fizz", "buzz"
           e#   and "fizzbuzz" with empty strings.
  .e|      e#   Vectorized logical OR; replace empty lines of the input
           e#   with the corresponding elements of the slice.
  =        e#   Check the original slice and the modified input for equality.
}=         e# Push the first match or nothing.
           e# We now have ["zzubzzif"] and possibly a solution on the stack.
N*         e# Join the topmost stack item, separating by linefeeds.         
o          e# Print the result.
;          e# Discard the remaining stack item, if any.
\$\endgroup\$
1
\$\begingroup\$

Perl, 140 bytes

$f=fizz;$b=buzz;@a=<>;@x=map{s!\d!!gr.$/}@s=map{$_%15?$_%3?$_%5?$_:$b:$f:$f.$b}(++$c..$c+$#a)while$c<15&&"@x"ne"@a";print$c<15?"@s":zzubzzif

Explanation

  1. @a is the array of input lines
  2. Inside the while loop,
  3. @s has the generated fizz-buzz sequence
  4. @x is the same as @s but with numbers replaced with empty strings and a new line appened to every element (to match with @a)
  5. $c is a counter from 1 to 15
  6. The loop runs till @x becomes the same as the input @a
  7. Outside the loop, the output is @s or zzufzzib based on whether $c was in its limits or not
\$\endgroup\$
1
\$\begingroup\$

Python, 176 Bytes

Could probably do a lot better, but first attempt at Golf. Tips appreciated :)

Shrunk

def f(a):l=len(a);g=lambda n:'fizz'*(n%3<1)+'buzz'*(n%5<1);r=range;return next(([g(x)or x for x in r(i%15,i%15+l)]for i in r(1,16)if all(g(i+x)==a[x]for x in r(l))),g(0)[::-1])

Original

def f(a):
  l = len(a)
  g = lambda n: 'fizz'*(n%3<1)+'buzz'*(n%5<1)
  r = range
  return next(
    (
      [g(x) or x for x in r(i % 15,i % 15 + l)]
      for i in r(1,16)
      if all(
        g(i + x) == a[x] for x in r(l)
      )
    ),
    g(0)[::-1]
  )
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! Standard formatting guidelines are to preface your answer with a header, so readers know the language and leaderboard snippets can properly parse your answer. For example, #Java, 205 Bytes as the first line of your answer. \$\endgroup\$ – AdmBorkBork Oct 16 '15 at 2:21
  • 1
    \$\begingroup\$ Try replacing the lambda with the following: 'fizz'*(n%3<1)+'buzz'*(n%5<1) You can remove the f and b assignments then. (f+b)[::-1] can then be a call to a known 'fizzbuzz' e.g. g(15)[::-1]. \$\endgroup\$ – Todd Oct 16 '15 at 8:35
  • \$\begingroup\$ Thanks for the suggestion! Down to 183! I think g(0) also works to save another byte :) \$\endgroup\$ – arcyqwerty Oct 16 '15 at 15:01
  • 1
    \$\begingroup\$ python 2 allows to remove some spaces before keywords when there is no ambiguity : for example ..] for may be written ..]for. Applying this trick, you get 177 chars \$\endgroup\$ – dieter Oct 16 '15 at 15:33
  • \$\begingroup\$ Could you include the input you assumed when you wrote the code next time. e.g. list of the form ['','fizz',''] There are also a few more to remove if you compare the input list vs a list comp rather than using all() if a==[g(i + x) for x in r(l)] \$\endgroup\$ – Todd Oct 17 '15 at 7:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.