Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Writing FizzBuzz with flip-flops
a=b=c=(1..100).each do |num|
print num, ?\r,
("Fizz" unless (a = !a) .. (a = !a)),
("Buzz" unless (b = !b) ... !((c = !c) .. (c = !c))),
?\n
end
@23inhouse

This comment has been minimized.

Show comment
Hide comment
@23inhouse

23inhouse Aug 2, 2012

Ok I'll say it. WTF?

Please explain.

Edit: Please explain https://gist.github.com/3230984/a13fc25d6b2f78524c865bbb622e4f3cd9e97b6a

Ok I'll say it. WTF?

Please explain.

Edit: Please explain https://gist.github.com/3230984/a13fc25d6b2f78524c865bbb622e4f3cd9e97b6a

@practicingruby

This comment has been minimized.

Show comment
Hide comment
@practicingruby

practicingruby Aug 2, 2012

p "TT" if (true..true)
p "TF" if (true..false)
p "FT" if (false..true)
p "FF" if (false..false)
p "TT" if (true..true)
p "TF" if (true..false)
p "FT" if (false..true)
p "FF" if (false..false)
@23inhouse

This comment has been minimized.

Show comment
Hide comment
@23inhouse

23inhouse Aug 2, 2012

I was actually a little bit scared to run it in irb.

Thank you.

I was actually a little bit scared to run it in irb.

Thank you.

@judofyr

This comment has been minimized.

Show comment
Hide comment
@judofyr

judofyr Aug 2, 2012

There's more to it though. Every flip-flop has an internal state (that starts out as false) that is persisted when there's a loop around the flip-flop.

For double dots it works like this:

if state == false
  return_value = start.call
else
  return_value = true
end
state = !stop.call

For triple dots:

if state == false
  return_value = start.call
else
  return_value = true
  state = !stop.call
end

(Where start/stop is the first and second part of the flip-flop).

When you use assignments and negation in the flip-flop you essentially have two state variables (the flip-flop's internal state + your variable) which triggers the return value in a certain pattern.

Owner

judofyr commented Aug 2, 2012

There's more to it though. Every flip-flop has an internal state (that starts out as false) that is persisted when there's a loop around the flip-flop.

For double dots it works like this:

if state == false
  return_value = start.call
else
  return_value = true
end
state = !stop.call

For triple dots:

if state == false
  return_value = start.call
else
  return_value = true
  state = !stop.call
end

(Where start/stop is the first and second part of the flip-flop).

When you use assignments and negation in the flip-flop you essentially have two state variables (the flip-flop's internal state + your variable) which triggers the return value in a certain pattern.

@practicingruby

This comment has been minimized.

Show comment
Hide comment
@practicingruby

practicingruby Aug 2, 2012

@judofyr: I was going to ask you to explain the rest of it, because I was clearly ducking that :-P

@judofyr: I was going to ask you to explain the rest of it, because I was clearly ducking that :-P

@23inhouse

This comment has been minimized.

Show comment
Hide comment
@23inhouse

23inhouse Aug 2, 2012

Thank you all.

Thank you all.

@judofyr

This comment has been minimized.

Show comment
Hide comment
@judofyr

judofyr Aug 2, 2012

I don't have a proof, but it seems to me that it's impossible to make it return false for every 6th iteration. I've solved it for 1, 2, 3, 4, 5, 7, 8, 9, 10, but not 6 :-(

Owner

judofyr commented Aug 2, 2012

I don't have a proof, but it seems to me that it's impossible to make it return false for every 6th iteration. I've solved it for 1, 2, 3, 4, 5, 7, 8, 9, 10, but not 6 :-(

@practicingruby

This comment has been minimized.

Show comment
Hide comment
@practicingruby

practicingruby Aug 2, 2012

@judofyr: Try building a truth table for them. That might help.

@judofyr: Try building a truth table for them. That might help.

@judofyr

This comment has been minimized.

Show comment
Hide comment
@judofyr

judofyr Aug 2, 2012

The problem is that it branches. In the 2-flip-flop if the state is false and we want the next values to be [true, false], then there are two possible inputs. There's also several ways to achieve the same input. One solution to the "dividable by 3" is the input: {start:true, stop:false}, {stop:true}, {start:false}. This can be solved either by having the same 2-cycle (true, false, true, false) in both start and stop ((s = !s) .. (s = !s)), but you can also use two different variables having a separate 2-cycle ((a = !a) .. (b = !b)).

Owner

judofyr commented Aug 2, 2012

The problem is that it branches. In the 2-flip-flop if the state is false and we want the next values to be [true, false], then there are two possible inputs. There's also several ways to achieve the same input. One solution to the "dividable by 3" is the input: {start:true, stop:false}, {stop:true}, {start:false}. This can be solved either by having the same 2-cycle (true, false, true, false) in both start and stop ((s = !s) .. (s = !s)), but you can also use two different variables having a separate 2-cycle ((a = !a) .. (b = !b)).

@judofyr

This comment has been minimized.

Show comment
Hide comment
@judofyr

judofyr Aug 2, 2012

Yay, after some improvements in my verifier-program, I now know there are solutions for everything from 1 to 17 \o/

Owner

judofyr commented Aug 2, 2012

Yay, after some improvements in my verifier-program, I now know there are solutions for everything from 1 to 17 \o/

@DouglasAllen

This comment has been minimized.

Show comment
Hide comment
@DouglasAllen

DouglasAllen Aug 11, 2012

Using flip-flops has to be benchmarked. I think that there is nothing wrong with using faster, more common methods. It doesn't make sense to iterate every value of the 1 to 100 range and then still have to eval each condition of a flip-flop.
Have you done a ven test ever? Just a thought. Map the state at every eval.

Using flip-flops has to be benchmarked. I think that there is nothing wrong with using faster, more common methods. It doesn't make sense to iterate every value of the 1 to 100 range and then still have to eval each condition of a flip-flop.
Have you done a ven test ever? Just a thought. Map the state at every eval.

@DouglasAllen

This comment has been minimized.

Show comment
Hide comment
@DouglasAllen

DouglasAllen Aug 11, 2012

I'm confused about the !
Is this a not or a bang?

I'm confused about the !
Is this a not or a bang?

@judofyr

This comment has been minimized.

Show comment
Hide comment
@judofyr

judofyr Oct 5, 2012

And here's a version of FizzBuzzBazz:

a=b=c=d=(e=1..100).each do |num|
  print num, ?\r,
    ("Fizz" unless (a = !a) .. (a = !a)),
    ("Buzz" unless (b = !b) ... !((c = !c) .. (c = !c))),
    ("Bazz" unless ((d = !d) .. (d = !d)) ... (e = !e)),
    ?\n
end
Owner

judofyr commented Oct 5, 2012

And here's a version of FizzBuzzBazz:

a=b=c=d=(e=1..100).each do |num|
  print num, ?\r,
    ("Fizz" unless (a = !a) .. (a = !a)),
    ("Buzz" unless (b = !b) ... !((c = !c) .. (c = !c))),
    ("Bazz" unless ((d = !d) .. (d = !d)) ... (e = !e)),
    ?\n
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment