Zzub Zzif (reverse Fizz Buzz)

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

• Related. Oct 17, 2015 at 19:56

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

• s/fizz/f, s/buzz/b Oct 16, 2015 at 21:57

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


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

• does C# not have a break keyword?
– cat
Dec 16, 2015 at 22:15
• @cat, it does, but the goto jumps out of the inner loop and over the rest of the outer loop's logic. Dec 16, 2015 at 23:59
• First time I heard about goto on C#! Didn't even know C# had it! Jun 25, 2017 at 20:55

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.


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

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

• 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. Oct 16, 2015 at 2:21
• 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].
– Todd
Oct 16, 2015 at 8:35
• Thanks for the suggestion! Down to 183! I think g(0) also works to save another byte :) Oct 16, 2015 at 15:01
• 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 Oct 16, 2015 at 15:33
• 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)]
– Todd
Oct 17, 2015 at 7:53

JavaScript (Node.js), 127 bytes

f=(n,j=1)=>j<99?(M=n.map((e,i)=>e?e:j+i)).some((e,i)=>e!=((J=j+i)%3?J%5?J:'buzz':'fizz'+(J%5?'':'buzz')))?f(n,j+1):M:'zzubzzif'


Try it online!

I came across this challenge by accident after clicking on one of the answerers' profiles. Expects an array of lowercase strings.

How?

FizzBuzz loops every 15 lines, which means that we can reasonably expect that by the time the start counter reaches 99, we will have looped through fizzbuzz a few times, hence allowing us to stop the recursion and instead output "zzubzzif".

If the counter is still less than 99, then we first fill in the falsy lines (empty strings) with their numbers, and check if it makes a valid FizzBuzz snippet using some. If one doesn't fit in, then recall the function with j+1. Otherwise return M.

Python 2, 173 bytes

import re
def f(u,i=0,s=""):
exec"s+=i%3/2*'Fizz'+i%5/4*'Buzz'or-~i+' ';i+=1;"*100;s=s.replace("'","");return re.findall(' '.join(['\d+'if not x else x for x in u]),s)[0]
`

Try it online!