在Elixir中,一旦找到第33个因子,为什么我寻找主要因子的算法就变得奇怪了,我该如何解决?

问题描述 投票:0回答:1

我有以下模块来找到主要因素:

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 prime-factoring
1个回答
0
投票

当将整数列表插值到字符串中时,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将字符列表视为整数列表。

© www.soinside.com 2019 - 2024. All rights reserved.