我有以下模块来找到主要因素:
defmodule PrimeFactors do
def factors_for(number)
when number < 2,
do: []
def factors_for(number),
do: factors_for(number, _next_attempt = 2, _accumulator = [])
def factors_for(number, next_attempt, accumulator)
when next_attempt > number,
do:
accumulator
|> Enum.reverse()
def factors_for(number, next_attempt, accumulator) do
IO.inspect(label: "######## [next_attempt | accumulator] #{[next_attempt | accumulator]}: ")
if rem(number, next_attempt) === 0,
do: factors_for(div(number, next_attempt), next_attempt, [next_attempt | accumulator]),
else: factors_for(number, next_prime(next_attempt), accumulator)
end
defp next_prime(2),
do: 3
defp next_prime(n),
do: n + 2
|> IO.inspect(label: "######## NEXT ")
end
对于大多数数字,它按预期工作:
例如,PrimeFactors.factors_for(10200)
的输出以:结尾
######## NEXT: : 17
[
label: <<35, 35, 35, 35, 35, 35, 35, 35, 32, 91, 110, 101, 120, 116, 95, 97,
116, 116, 101, 109, 112, 116, 32, 124, 32, 97, 99, 99, 117, 109, 117, 108,
97, 116, 111, 114, 93, 32, 32, 17, 5, 5, 3, 2, 2, 2, 58, 32>>
]
[2, 2, 2, 3, 5, 5, 17]
但是有一些数字,输出变得很时髦。
例如,如果我执行PrimeFactors.factors_for(10201)
,我们注意到当它达到next_attempt 33时,输出是非常意外的:
######## NEXT: : 29
[
label: <<35, 35, 35, 35, 35, 35, 35, 35, 32, 91, 110, 101, 120, 116, 95, 97,
116, 116, 101, 109, 112, 116, 32, 124, 32, 97, 99, 99, 117, 109, 117, 108,
97, 116, 111, 114, 93, 32, 32, 29, 58, 32>>
]
######## NEXT: : 31
[
label: <<35, 35, 35, 35, 35, 35, 35, 35, 32, 91, 110, 101, 120, 116, 95, 97,
116, 116, 101, 109, 112, 116, 32, 124, 32, 97, 99, 99, 117, 109, 117, 108,
97, 116, 111, 114, 93, 32, 32, 31, 58, 32>>
]
######## NEXT: : 33
[label: "######## [next_attempt | accumulator] !: "]
######## NEXT: : 35
[label: "######## [next_attempt | accumulator] #: "]
...
######## NEXT: : 99
[label: "######## [next_attempt | accumulator] c: "]
######## NEXT: : 101
[label: "######## [next_attempt | accumulator] e: "]
[label: "######## [next_attempt | accumulator] ee: "]
'ee'
类似地,PrimeFactors.factors_for(12221)
的值不正确:
######## NEXT: : 29
[
label: <<35, 35, 35, 35, 35, 35, 35, 35, 32, 91, 110, 101, 120, 116, 95, 97,
116, 116, 101, 109, 112, 116, 32, 124, 32, 97, 99, 99, 117, 109, 117, 108,
97, 116, 111, 114, 93, 32, 32, 29, 11, 11, 58, 32>>
]
######## NEXT: : 31
[
label: <<35, 35, 35, 35, 35, 35, 35, 35, 32, 91, 110, 101, 120, 116, 95, 97,
116, 116, 101, 109, 112, 116, 32, 124, 32, 97, 99, 99, 117, 109, 117, 108,
97, 116, 111, 114, 93, 32, 32, 31, 11, 11, 58, 32>>
]
######## NEXT: : 33
[label: "######## [next_attempt | accumulator] !\v\v: "]
######## NEXT: : 35
[label: "######## [next_attempt | accumulator] #\v\v: "]
...
[label: "######## [next_attempt | accumulator] a\v\v: "]
######## NEXT: : 99
[label: "######## [next_attempt | accumulator] c\v\v: "]
######## NEXT: : 101
[label: "######## [next_attempt | accumulator] e\v\v: "]
'\v\ve'
((我不知道它是否相关,但是在exercism.com的Diffie Hellman挑战下,当我尝试提高到33的幂时,我也注意到了一些奇怪的行为……这似乎使我的应用陷入了无尽的局面。循环...)
当将整数列表插值到字符串中时,Elixir假定该列表是“ IO数据”,因此该列表中的整数被视为字符代码。
要解决此问题,您需要替换此行
IO.inspect(label: "######## [next_attempt | accumulator] #{[next_attempt | accumulator]}: ")
进入此行
IO.inspect([next_attempt | accumulator], label: "######## [next_attempt | accumulator]", charlists: :as_lists)
选项charlists: :as_lists
强制IO.inspect
将字符列表视为整数列表。