
本文全部涉及在FizzBuzz中编码隐式条件。 这使您可以遍历代码行,这些代码以不同的语法提供相似的输出。
这是针对Elixir的完整初学者的。 但是,最后这将提供更多信息。
当您使用google时,您会发现以下有关FizzBuzz的短语。
FizzBuzz是一项非常简单的编程任务,用于软件开发人员的求职面试中,以确定求职者是否可以实际编写代码 。
Fizz嗡嗡声是一个小组文字游戏,儿童可以教他们有关分裂的知识。 玩家轮流进行递增计数,用“ fizz”一词替换任何可被三整除的数字,用“ buzz”一词替换可被五整除的任何数字,如果被FizzBuzz词一分为三和五可整除,则仅打印数字本身。
这就是FizzBuzz的全部内容。 哦..您终于知道了FizzBuzz是什么。 继续摇摆…
我们只是简单地打印范围内的数字,并使用游戏协议将其替换为单词Fizz,Buzz和FizzBuzz。

该写代码了……
泡沫部分
在这里,我用FizzBuzz
命名了模块,当然每个人都做同样的FizzBuzz
,并编写了play/2
函数。
首先,我们只是打印范围内的数字,然后看它是如何工作的。
defmodule FizzBuzz做
def播放(最小,最大)
Enum.each(min..max,fn(num)-> IO.puts num end)
结束
结束
播放/ 2
该函数采用两个数字作为输入范围内的技术最大值和最小值。 因此,我们可以通过../2
宏创建一个范围。
最小。最大
范围在内部以结构表示。 范围实现了Enumerable
协议,这意味着Enum
模块中的功能可用于处理范围。
您可以在i/1
的帮助下检查已实施的协议
我1..2

因此,我们借助Enum
模块中的each
函数来遍历整个范围并打印数字。

fn(num)-> IO.puts num end
在这里,我们使用匿名函数通过调用IO.puts
内部的IO.puts
来打印数字。
功能输入值的模式匹配
在这里,我们将编写另一个具有相同名称play
函数,但是这次只需要一个输入play/1
。 根据OOP,它称为方法重载。
这就是代码的外观。
defmodule FizzBuzz做
def播放(最小,最大)
Enum.each(min..max,fn(num)-> play(num)end)
当rem(num,3)== 0时结束def play(num)
IO.puts“嘶嘶声”
结束
变化:
我们创建了一个用于打印的函数,而不是在匿名函数内调用IO.puts
。 在play/1
的函数定义中, when
满足游戏条件when
,我们使用了Elixir 保护子句。
如果该数字可被三整除,则余数将为0
。 因此,我们使用rem/2
函数获取余数,并使用==
检查表达式的真值。 如果true
值为true
,它将运行函数定义,否则将不运行定义。
现在复制代码并将其粘贴到iex
。 它编译良好。
现在,将播放功能调用为
iex> FizzBuzz.play 1,20
您将看到运行时错误。 它编译良好,但是在运行时出现错误。
这就是错误的外观。

故障排除
我们的代码有什么问题?
范围1..20
的第一个值将是1
因为范围总是包含在内的。
函数调用的第一次迭代看起来像
枚举-fn(1)-> play(1)结束
此处, play
功能是使用值1
触发的,但是,保护子句表达式rem(1, 3)==0
会导致结果为false
因此,该功能子句与传递的值不匹配。
因此,我们需要编写另一个print
函数来负责打印不能被3整除的数字,这就是代码的外观。
defmodule FizzBuzz做def play(min,max)做
Enum.each(min..max,fn(num)-> play(num)end)
当rem(num,3)== 0时结束def play(num)
IO.puts“嘶嘶声”
结束def play(num)做
IO数量
结束
现在尝试通过复制粘贴上面的代码行到iex
进行尝试,然后将play函数称为FizzBuzz.play 1,20
。
您将看到被三次迭代整除的数字将打印Fizz
而不是打印数字。

像Fizz一样,我们必须添加另一个带有play/1
子句的play/1
函数,该函数带有保护子句以检查5的可除性。
让我们看看更新的代码
defmodule FizzBuzz做def play(min,max)做
Enum.each(min..max,fn(num)-> play(num)end)
当rem(num,3)== 0时结束def play(num)
IO.puts“嘶嘶声”
当rem(num,5)== 0时结束def play(num)
IO.puts“嗡嗡声”
结束def play(num)做
IO数量
结束

像Fizz和Buzz一样,我们可以考虑两个数字的LCM (最小公倍数),以3和5检验数字的可除性。 3和5的LCM为15。因此,如果数字可以被15整除,那么它可以被3和5整除。
让我们添加另一个功能。
defmodule FizzBuzz做def play(min,max)做
Enum.each(min..max,fn(num)-> play(num)end)
当rem(num,3)== 0时结束def play(num)
IO.puts“嘶嘶声”
当rem(num,5)== 0时结束def play(num)
IO.puts“嗡嗡声”
当rem(num,15)== 0时结束def play(num)
IO.puts“ FizzBuzz”
结束def play(num)做
IO数量
结束
现在,复制并粘贴以上代码行,然后运行play/2
函数。

令我们惊讶的是,它在迭代15时打印Fizz而不是FizzBuzz 。
我们的代码有什么问题?
故障排除
defmodule FizzBuzz dodef播放(最小,最大)
Enum.each(min..max,fn(num)-> play(num)end)
当rem(num,3)== 0时执行enddef play(num)
IO.puts“嘶嘶声”
当rem(num,5)== 0时执行enddef play(num)
IO.puts“嗡嗡声”
当rem(num,15)== 0时,enddef play(num)
IO.puts“ FizzBuzz”
enddef play(num)做
IO数量
结束
让我们以15次迭代来解释代码
每个枚举-#15play(15)
-
当rem(15,3)== 0时播放(15)
表达式rem(15, 3)==0
将得出true
。 因此,它只是打印Fizz
并跳至下一个迭代。
因此,我们需要重新排序功能。 具有保护子句rem(num, 15) == 0
的play/1
函数应位于所有其余函数之上。 因此,首先检查15的除数,然后再检查3,然后再检查5。
让我们更新代码。
defmodule FizzBuzz dodef播放(最小,最大)
Enum.each(min..max,fn(num)-> play(num)end)
当rem(num,15)== 0时,enddef play(num)
IO.puts“ FizzBuzz”
当rem(num,3)== 0时执行enddef play(num)
IO.puts“嘶嘶声”
当rem(num,5)== 0时执行enddef play(num)
IO.puts“嗡嗡声”
当rem(num,15)== 0时,enddef play(num)
IO.puts“ FizzBuzz”
enddef play(num)做
IO数量
结束
现在,在iex
复制并粘贴以上代码行,并运行FizzBuzz.play 1, 20
iex
函数。

欢呼! 我们完成了代码逻辑。
但是,文章标题指出,我们需要用七(7)行代码来做到这一点。
让我们改进代码。
我们还有什么可以改进的?
无需每次都复制粘贴到iex
,我们可以创建文件fizz_buzz.ex
并将代码粘贴到其中。

现在运行命令
iex fizz_buzz.ex
您必须位于文件所在的同一目录中。
否则,您必须以
IEX路径/到/文件/ fizz_buzz.ex
它将模块加载到新的iex
会话中。 您仍然可以检查模块是否已加载Code.ensure_loaded FizzBuzz

可以使用r FizzBuzz
重新编译文件fizz_buzz.ex
的更改。 在这里r
重新编译并重新加载给定的模块。
到目前为止,删除空的新行后,我们的代码由20行组成。
现在我们必须改进代码,使其看起来比以前更好。
替代品
在elixir中,我们可以将匿名函数fn(num)-> play(num) end
替换为&(play(&1))
所以更新线

至

保存文件并使用r fizz_buzz.ex
重新编译
我们可以通过传递函数名称并使其迭代遍历each
函数的范围来简化此过程
所以,更新行
枚举每个(min..max,&(play(&1)))
至
每个枚举(最小。最大,&play / 1)
现在,使用更新保存文件,然后重新编译并对其进行测试。 它仍然有效。
Elixir中的单行功能

如果您清楚地观察到代码逻辑,则我们的大多数函数定义都是一行。 因此,我们可以避免do .. end
块。 我们可以使用do:
单行样式更新函数定义。
#之前
当rem(num,15)== 0时def play(num)
IO.puts“ FizzBuzz”
在rem(num,3)== 0的情况下更新def play(num,3)之后执行end#,请执行:IO.puts“ FizzBuzz”


同样,我们将使用单线样式代码库更新其余的函数定义。
这是更新后的样子
defmodule FizzBuzz做
def播放(最小,最大),执行:枚举每个(最小。最大,&play / 1)
当rem(num,15)== 0时执行def play(num),请执行:IO.puts“ FizzBuzz”
def play(num)当rem(num,3)== 0时,执行:IO.puts“ Fizz”
当rem(num,5)== 0时执行def play(num),请执行:IO.puts“ Buzz”
def play(num),执行:IO.puts num
结束

繁荣! 我们分7行开发了代码逻辑。 你真棒…
本文最初发布于Ahamtech博客
快乐编码…
