Zzub Zzif (reverse Fizz Buzz)

36

2

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

Digital Trauma

Posted 2015-10-15T19:48:01.400

Reputation: 64 644

Related. – Martin Ender – 2015-10-17T19:56:02.370

Answers

17

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

Ypnypn

Posted 2015-10-15T19:48:01.400

Reputation: 10 485

1s/fizz/f, s/buzz/b – djechlin – 2015-10-16T21:57:38.193

10

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

Hand-E-Food

Posted 2015-10-15T19:48:01.400

Reputation: 7 912

does C# not have a break keyword? – cat – 2015-12-16T22:15:39.597

2@cat, it does, but the goto jumps out of the inner loop and over the rest of the outer loop's logic. – Hand-E-Food – 2015-12-16T23:59:25.957

First time I heard about goto on C#! Didn't even know C# had it! – sergiol – 2017-06-25T20:55:04.387

4

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.

Dennis

Posted 2015-10-15T19:48:01.400

Reputation: 196 637

1

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

arcyqwerty

Posted 2015-10-15T19:48:01.400

Reputation: 111

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. – AdmBorkBork – 2015-10-16T02:21:04.390

1Try 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 – 2015-10-16T08:35:44.697

Thanks for the suggestion! Down to 183! I think g(0) also works to save another byte :) – arcyqwerty – 2015-10-16T15:01:35.153

1python 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 – dieter – 2015-10-16T15:33:57.800

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 – 2015-10-17T07:53:53.680

1

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

svsd

Posted 2015-10-15T19:48:01.400

Reputation: 556