Skip to content

Instantly share code, notes, and snippets.

@hauleth
Last active April 8, 2024 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hauleth/b921ee5f0b206d9e5cbf897d9e520265 to your computer and use it in GitHub Desktop.
Save hauleth/b921ee5f0b206d9e5cbf897d9e520265 to your computer and use it in GitHub Desktop.
-module(fizzbuzz).
-export([main/0]).
main() ->
Types = [
{3, "Fizz"},
{5, "Buzz"}
],
io:put_chars(run(100, Types)).
-type types() :: [{pos_integer(), iodata()}].
-spec run(To :: integer(), Types :: types()) -> iodata().
run(To, Types) ->
RevTypes = lists:reverse(Types),
[build(N, RevTypes) || N <- lists:seq(1, To)].
build(N, Types) -> build(N, Types, []).
build(N, [], []) -> [integer_to_binary(N), $\n];
build(_, [], Acc) -> [Acc, $\n];
build(N, [{D, Val} | Rest], Acc) when N rem D =:= 0 ->
build(N, Rest, [Val | Acc]);
build(N, [_ | Rest], Acc) ->
build(N, Rest, Acc).
defmodule FizzBuzz do
def build_list(range, types),
do: Enum.map(range, &entry(&1, types))
# TODO: Foo
# XXX: FOO
defp entry(n, types) do
for {d, val} <- types,
rem(n, d) == 0,
reduce: n do
acc when is_integer(acc) -> val
acc -> [acc, val]
end
|> to_string()
end
end
types = [
{3, "Fizz"},
{5, "Buzz"}
]
1..100
|> FizzBuzz.build_list(types)
|> Enum.intersperse(?\n)
|> IO.puts()
from itertools import islice
def fizzbuzz(types):
n = 0
while True:
n += 1
output = [s for (i, s) in types if n % i == 0]
yield ''.join(output) or str(n)
types = [
(3, 'Fizz'),
(5, 'Buzz')
]
for s in islice(fizzbuzz(types), 100):
print(s)
use std::borrow::Cow;
use std::fmt;
#[derive(Debug, Clone)]
enum Output<'a> {
Num(u64),
Str(Cow<'a, str>),
}
impl<'a> fmt::Display for Output<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use Output::*;
match *self {
Num(n) => write!(f, "{}", n),
Str(ref s) => write!(f, "{}", s),
}
}
}
impl<'a> From<&'a str> for Output<'a> {
fn from(s: &'a str) -> Self {
Output::Str(s.into())
}
}
impl<'a> From<u64> for Output<'a> {
fn from(n: u64) -> Self {
Output::Num(n)
}
}
impl<'a> std::ops::Add<&'a str> for Output<'a> {
type Output = Self;
fn add(self, rhs: &'a str) -> Self {
use Output::*;
match self {
Num(_) => Str(rhs.into()),
Str(lhs) => Str(lhs + rhs),
}
}
}
struct FizzBuzz<I> {
types: I,
n: u64,
}
impl<'a, 'b, I> FizzBuzz<I>
where
I: Iterator<Item = &'a (u64, &'b str)>,
'b: 'a
{
pub fn new<T>(types: T) -> Self
where
T: IntoIterator<Item = I::Item, IntoIter = I>,
{
FizzBuzz {
n: 0,
types: types.into_iter(),
}
}
}
impl<'a, 'b, I> Iterator for FizzBuzz<I>
where
I: Iterator<Item = &'a (u64, &'b str)> + Clone,
'b: 'a
{
type Item = Output<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.n += 1;
Some(
self.types
.clone()
.filter(|(d, _)| self.n % d == 0)
.fold(Output::Num(self.n), |acc, &(_, s)| acc + s),
)
}
}
fn main() {
let types = [(3, "Fizz"), (5, "Buzz")];
for n in FizzBuzz::new(&types).take(100) {
println!("{}", n)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment