Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active April 24, 2025 15:34
Show Gist options
  • Save tompng/342ce6ea1832a426f3b3cee6905edda5 to your computer and use it in GitHub Desktop.
Save tompng/342ce6ea1832a426f3b3cee6905edda5 to your computer and use it in GitHub Desktop.
Readable FizzBuzz
module ReadableFizzBuzz
module Chain
end
end
include ReadableFizzBuzz
Chain::Itself = Chain
module Chain::Itself
module Void
A = B = C = D = E = F = G = H = I = J = K = L = M = Void
N = O = P = Q = R = S = T = U = V = W = X = Y = Z = Void
module Set
end
module Put
end
module WriteBack
end
module Not
include Void
end
end
module Off
include Void
end
module Nil
A = B = C = D = E = F = G = H = I = J = K = L = M = Off
N = O = P = Q = R = S = T = U = V = W = X = Y = Z = Off
end
module Next
include Nil
end
module Current
include Nil
Not = Off
Set = Put = Next
WriteBack = Current
end
True = If = Current
On = Next
module On
INT = 1
FIZZ = 'Fizz'
BUZZ = 'Buzz'
PREFIX = '0b'
FORMAT = "%d%s%s\n"
NEXT = __FILE__
end
module Off
INT = 0
FIZZ = BUZZ = nil
PREFIX = '0b1'
FORMAT = "%2$s%3$s\n"
NEXT = '/dev/null'
Not = True
end
module Initial
C = D = True
end
module ReadableFizzBuzz::Chain::Current
include Initial
end
If::C::Set::E = If::E::Set::F = If::F::Set::C = On
If::D::Set::G = If::G::Set::H = If::H::Set::I = If::I::Set::J = If::J::Set::D = On
If::F::Not::J::Not::Set::B = On
If::K::Not::Set::K = On
If::K::WriteBack::L = True
If::L::Not::M::Set::M = On
If::L::M::Not::Put::M = On
If::L::M::WriteBack::N = True
If::N::Not::O::Set::O = On
If::N::O::Not::Put::O = On
If::N::O::WriteBack::P = True
If::P::Not::Q::Set::Q = On
If::P::Q::Not::Put::Q = On
If::P::Q::WriteBack::R = True
If::R::Not::S::Set::S = On
If::R::S::Not::Put::S = On
If::R::S::WriteBack::T = True
If::T::Not::U::Set::U = On
If::T::U::Not::Put::U = On
If::T::U::WriteBack::V = True
If::V::Not::W::Set::W = On
If::V::W::Not::Put::W = On
If::V::W::WriteBack::X = True
If::X::Not::Y::Set::Y = On
If::X::Y::Not::Put::Y = On
If::X::Y::WriteBack::Z = True
If::Z::Not::Set::A = On
end
module Chain::Chain
Current = Chain::Next
end
include Chain
module Chain::Current
NUMBER = A::PREFIX, Y::INT, W::INT, U::INT, S::INT, Q::INT, O::INT, M::INT, K::INT
printf B::FORMAT, NUMBER.join, C::FIZZ, D::BUZZ
load A::NEXT
end
module Next
VALUE = '1'
FIZZ = 'Fizz'
BUZZ = 'Buzz'
FORMAT = "%s%s\n"
PATH = __FILE__
end
module Never
A = B = C = D = E = F = G = H = I = J = K = L = M = Never
N = O = P = Q = R = S = T = U = V = W = X = Y = Z = Never
If = Never
FORMAT = ''
end
module NullWrite
include Never
end
module Current
If = WriteBack = Current
Unless = Never
WriteIf = Next
WriteUnless = NullWrite
end
module Never
WriteBack = WriteIf = WriteUnless = NullWrite
end
module Empty
module Undefined
WriteBack = WriteIf = NullWrite
PATH = '/dev/null'
If = Never
WriteUnless = Next
VALUE = '0'
FIZZ = BUZZ = nil
FORMAT = "%s%s%d\n"
end
A = B = C = D = E = F = G = H = I = J = K = L = M = Undefined
N = O = P = Q = R = S = T = U = V = W = X = Y = Z = Undefined
end
include Empty
WriteBack = Current
Next::K = True = Next
K::WriteUnless::E = K::WriteUnless::G = L::WriteUnless::L = True
B::WriteIf::E = E::WriteIf::F = F::WriteIf::B = F::WriteIf::A = J::WriteIf::A = True
C::WriteIf::G = G::WriteIf::H = H::WriteIf::I = I::WriteIf::J = J::WriteIf::C = True
L::WriteBack::T = WriteBack
module T::Unless
M::WriteIf::M = True
end
module T::If
M::WriteUnless::M = True
M::WriteBack::U = WriteBack
end
module U::Unless
N::WriteIf::N = True
end
module U::If
N::WriteUnless::N = True
N::WriteBack::V = WriteBack
end
module V::Unless
O::WriteIf::O = True
end
module V::If
O::WriteUnless::O = True
O::WriteBack::W = WriteBack
end
module W::Unless
P::WriteIf::P = True
end
module W::If
P::WriteUnless::P = True
P::WriteBack::X = WriteBack
end
module X::Unless
Q::WriteIf::Q = True
end
module X::If
Q::WriteUnless::Q = True
Q::WriteBack::Y = WriteBack
end
module Y::Unless
R::WriteIf::R = True
end
module Y::If
R::WriteUnless::R = True
R::WriteBack::Z = WriteBack
end
module Z::Unless
S::WriteIf::S = True
end
module Z::If
S::WriteUnless::S = True
S::WriteIf::A = Never
end
S::WriteUnless::D = Z::WriteUnless::D = True
module Current
prepend Empty
end
module Next
module Next
end
end
include Next
Current = Next
Next = Next::Next
NUMBER = '0b', S::VALUE, R::VALUE, Q::VALUE, P::VALUE, O::VALUE, N::VALUE, M::VALUE, L::VALUE
printf A::FORMAT, B::FIZZ, C::BUZZ, NUMBER.join
load D::PATH

Remarks

Just run it with no argument:

ruby entry.rb

I confirmed the following implementations/platforms:

  • ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +MN +PRISM [arm64-darwin22]
  • ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [aarch64-linux-musl]

Description

Readability is important even for a simple fizz buzz program.

These are the major ingredients of a spaghetti that makes program tasty and valuable but unreadable.

  • Many class definitions
  • Many method definitions
  • Many method calls
  • Many variables
  • Conditional branches

These are what is acceptable for a readable program.

  • Many modules: Using only a single module in a program is not good.
  • Many constants: Better than magic numbers.
  • Module#include: Mixins are what module is for.
  • Many file loads: Usually better than loading a large file only once.
  • Minimal method calls: Needed for printing output.

This program is doing something slightly difficult in the last few lines: print output and load ruby program. In contrast, the rest part of this program is extremely simple and easy. Module definition, constant definition and module inclusion. That's all.

Internals

Called methods

  • Module#include
  • Array#join
  • Kernel#printf
  • Kernel#load

Deeply nested module chain to avoid constant reassignment

10.times do
  module Root
    module Chain
      module X; end
      module Y; end
      module Z; end
    end
  end
  include Root

  module Chain::Chain
    # Not a constant reassignment because Chain::Chain is always a new module
    X = Chain::Y
    Y = Chain::Z
    Z = Chain::X
  end
  include Chain
  p x: X, chain: Chain
end

Constant allocation

Constant Purpose
A Loop condition
B Format (!Fizz && !Buzz)
C, E, F Fizz rotation
D, G, H, I, J Buzz rotation
K, M, O, Q, S, U, W, Y Iteration bits
L, N, P, R, T, V, X, Z Temporary carry bits

Instruction sequence with constant lookup magic

# B = 1 if A
If::A::Set::B = On

# B = 1 if !A
If::A::Not::Set::B = On

# C = 1 if !A && B
If::A::Not::B::Set::C = On

# C = 1 if !A && !B
If::A::Not::B::Not::Set::C = On

Loop with load __FILE__

# A::NEXT is __FILE__ or '/dev/null'
load A::NEXT

Limitation

Needs /dev/null

target = ARGV[0]
case target
in 'modules.rb'
range = (1..255)
opt = '-W0 '
in 'constant.rb'
range = (1..256)
else
puts "Usage: ruby test.rb <target_file>"
exit
end
code = File.read(target)
puts "total: #{code.bytesize}, nonspace: #{code.split.join.bytesize}"
opt = '-W0 ' if target == 'modules.rb'
io = open("| ruby #{opt} -e \"STDOUT.sync=true;load '#{target}'\"")
expected = range.map {
"#{it % 15==0 ? 'FizzBuzz' : it % 3==0 ? 'Fizz' : it % 5==0 ? 'Buzz' : it}\n"
}
error = false
while (line = io.gets)
expected_line = expected.shift
if expected_line == line
puts "\e[32m#{line.chomp}\e[m\n"
else
error = true
puts "\e[31m#{line.chomp}\e[m (expected: #{expected_line.inspect})\n"
end
end
unless expected.empty?
error = true
puts "expected: #{expected.first}..."
end
if error
puts "\e[31mFail\e[m"
else
puts "\e[32mPass\e[m"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment