- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我遇到了 Mark Dominus' blog post描述解决 "SEND+MORE=MONEY" puzzle在 Python 中使用函数式编程技术(特别是 Monads)。
此处总结了死链接情况下的难题:
S E N D | Find each character's *unique* numerical value, such that
+ M O R E | the addition on the left is valid. There are no leading zeros.
-----------
= M O N E Y
我一直在寻找机会学习一些纯函数式编程,特别是 Elixir,这似乎是一个非常合适的项目。
我可以在 Elixir 中实现 Mark Dominus 的 Python 代码的外观相似版本:
defmodule Smm do
def make_set(ls), do: Enum.into(ls, HashSet.new)
def to_number([]), do: :error
def to_number(ls), do: Enum.join(ls) |> Integer.parse |> elem(0)
def remove(hs, ls), do: Set.difference(hs, Enum.into(ls, HashSet.new))
def let(x, func), do: func.(x)
def guard(predicate, func) when predicate, do: func.()
def guard(predicate, func), do: []
end
digits = Smm.make_set(0..9)
Enum.map( Smm.remove(digits, [0]), fn s ->
Enum.map( Smm.remove(digits, [s]), fn e ->
Enum.map( Smm.remove(digits, [s,e]), fn n ->
Enum.map( Smm.remove(digits, [s,e,n]), fn d ->
Smm.let(Smm.to_number([s,e,n,d]), fn w_send ->
Enum.map( Smm.remove(digits, [0,s,e,n,d]), fn m ->
Enum.map( Smm.remove(digits, [s,e,n,d,m]), fn o ->
Enum.map( Smm.remove(digits, [s,e,n,d,m,o]), fn r ->
Smm.let(Smm.to_number([m,o,r,e]), fn w_more ->
Enum.map( Smm.remove(digits, [s,e,n,d,m,o,r]), fn y ->
Smm.let(Smm.to_number([m,o,n,e,y]), fn w_money ->
Smm.guard(w_send + w_more == w_money, fn ->
[w_send, w_more, w_money] |> Enum.map( &(IO.puts(&1)) )
end)end)end)end)end)end)end)end)end)end)end)end) # (╯°□°)╯︵ ┻━┻
但有些事情告诉我必须有一种方法来解决疯狂嵌套的匿名函数和随后的表格翻转;这就是纯函数式语言存在的原因,对吧?
看看 Mark Dominus 的 previous blog post in which he solves the puzzle with Haskell ,我看到他正在使用含糖版本的 Haskell 的“绑定(bind)”运算符 >>=
来消除翻 table 的冲动......但我没有 learned me a Haskell ,所以我对这篇博文中提供的代码没有很强的把握。
我相当确定我在 Elixir 实现中缺少的是使用管道运算符 |>
,这对我来说实际上是这门语言的一大吸引力(对 Unix 非常熟悉管道,我自己)。我曾尝试在管道中工作并结合多种风格的 Enum.{map,reduce}
,但我总是回到原点。
有人可以提供任何建议吗?理想情况下,我正在为 Elixir 中的这个难题寻找更惯用的函数式编程解决方案。
最佳答案
您可以在这里查看:What is the "|>" symbol's purpose in Elixir? |>
运算符的概述。但基本思想是 a |> f(b, c)
与 f(a, b, c)
相同。当你做类似 a |> f(b) |> g(c)
的事情时,这非常有用,根据上面的规则,它与 g(f(a, b) 相同, c)
,但读起来更漂亮。
话虽如此,|>
运算符(称为管道)不是单子(monad)绑定(bind) (>>=
),并且不允许您“展平”深层嵌套循环就像 >>=
一样。对于在 Elixir 中看起来更好的任务替代方法,您可以:
停止使用这种循环方法,例如使用递归函数预先生成数字到字母的分配,如下所示:
defmodule Smm do
# some more things
def assignments(0, _), do: [[]]
def assignments(n, digits \\ Enum.into(0..9, HashSet.new)) do
digits
|> Stream.flat_map(fn (d) ->
for rest <- assignments(n - 1, Set.delete(digits, d)) do
[d | rest]
end
end)
end
end
for [s, e, n, d, m, o, r, y] <- Smm.assignments(8) do
w_send = Smm.to_number([s, e, n, d])
w_more = Smm.to_number([m, o, r, e])
w_money = Smm.to_number([m, o, n, e, y])
if s > 0 && m > 0 && (w_send + w_more == w_money) do
IO.inspect([w_send, w_more, w_money])
end
end
关于python - 在 Elixir 中寻求 "send+more=money"的惯用、优雅的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31823272/
在 ruby 脚本中,我可以简单地执行以下操作: require 'some-gem' SomeGem.do_something! 如何在 elixir exs 脚本中做类似的事情而不创建一个全新
我正在尝试与 Elixir 中的字符串位进行比较 - 如果它们相等,则 if block 触发或 else block 应该触发。 def show(conn, %{"id" => id}) do
我需要转换这个字符串 "/{foo}/{bar}.{format}" 在 "/#{a["foo"]}/#{a["bar"]}.#{a["format"]}" 因为我有一个包含这些属性的列表。例如 a[
我想在我的 Phoenix 应用程序中注册 2 个根主管,有什么理由不这样做吗? 例子如下 defmodule MyApp.Application do use Application imp
在一个 Elixir 项目中 mix.exs文件,我们像这样包含依赖项 defp deps(_) do [ {:phoenix, "~> 0.6.1"}, {:ecto,
我定义了一个与 guide-started 相关的环境变量,我的 mix.exs 是 defmodule Basic.Mixfile do use Mix.Project def projec
我正在使用 elixir lang getting started 学习 Elixir 编程,而我堆满了 record brace syntax . 这是示例: defrecord FileInfo,
我在谷歌上搜索了很多,但找不到任何关于这个主题的东西——要么 Elixir 的语言太年轻,要么我用错误的术语搜索。 我正在学习 Jose Valim 的 Elixir Portal 教程 (https
Elixir 是否支持类似于 Clojure 的命名匿名函数? 例如,我想做这样的事情: fib_fun = fn fib n -> if n fun = fn (n, _) when
我刚开始学习 Elixir,但有几种 OOP 语言的编程背景,主要是 Ruby。我找到了如何在模块内定义结构的示例: defmodule Example.User do defstruct nam
我定义了一个 Foo像这样的模块: defmodule Foo do def hello(x = %{name: name}) do IO.inspect [x, name] end
有人可以提出一个建议,如何一次用一批x迭代列表BUT吗? 例如: 如果功能存在: ["1","2","3","4","5","6","7","8","9","10"].step(5)|> IO.put
我正在开发 ubuntu 14.04 LTS。我按照 offical website 中给出的说明安装了 elixir在控制台中运行以下行,一切正常 Add Erlang Solutions repo
嗨,Elixir 程序员。 我有大约 2.500 首音乐轨道的列表,我想按不同的参数对其进行排序,例如轨道的标题。 排序应该不区分大小写。 下面的代码有效,但需要大约 100 毫秒到 130 毫秒来对
Elixir 有语言规范文档吗?如果是,它在哪里? Elixir 网站有 library documentation ,我在 guards 上找到了一些文档和 operators ,但我没有找到语言规
阅读有关 Elixir 不变性以及它如何尽可能避免内存复制的文章,这似乎是唯一可能的解释,但我还没有在任何地方看到它的明确说明。例如,当将一个新元素附加到列表时,它被描述为该操作恰好需要 n 个步骤,
我想知道是否有一种方法可以捕获绝对光标位置 在 Elixir 的命令行中。 我知道我必须使用以下 ansi 转义序列\033[6n, 并在执行后: echo -en "\033[6n" 打印出我正在寻
在 Elixir 文档中,他们一直使用带有斜线的奇怪符号,例如: is_boolean/1 IO.puts/1 String.length/1 is_function/2 ++/2 我只是猜测,但我认
我已经开始阅读有关 Elixir 编程语言的信息。 我明白那个: 它是功能性的 它是动态的,但支持@spec 它基于 Erlang VM 我的问题是:它是否有某种 GC? 最佳答案 是的,Erlang
我写了这个测试用例: assert_raise ArgumentError, myFn(a,b) 但它并没有达到我期望的效果。 myFn引发ArgumentError(do: raise Argume
我是一名优秀的程序员,十分优秀!