2015-05-31 4 views
0

Я в основном пытаюсь вычислить факторы BigInteger, которые являются первичными, у меня есть две простые функции факторизации, они оба выглядят так, как будто они должны приводить к одному и тому же результату в том, как я использовал их здесь внизу, но это не так здесь, может кто-нибудь объяснить, что происходит?вычисление простых коэффициентов с использованием одного и того же кода дает разные результаты?

let lookupTable = new HashSet<int>(primes) 

let isPrime x = lookupTable.Contains x 

let factors (n:bigint) = 
    Seq.filter (fun x -> n % x = 0I) [1I..n] 

let factors' (n:bigint) = 
    Seq.filter (fun x -> n % x = 0I) [1I..bigint(sqrt(float(n)))] 


600851475143I 
|> fun n -> bigint(sqrt(float(n))) 
|> factors 
|> Seq.map int 
|> Seq.filter isPrime 
|> Seq.max // produces 137 

600851475143I 
|> factors' 
|> Seq.map int 
|> Seq.filter isPrime 
|> Seq.max // produces 6857 (the right answer) 
+1

Первая программа факторизует 'sqrt (n)', а не 'n'. Я голосую, чтобы закрыть этот вопрос по причине «типографской ошибки». – bytebuster

+0

I actaully сказал: «Они должны произвести тот же результат ***, как я их использовал *** здесь внизу», и я имел в виду кусок кода после определения функции –

+0

. Ваше намерение не изменяет характер фактического ошибка; @bytebuster полностью прав в этом случае. – ildjarn

ответ

4

Ваши функции не эквивалентны. В первой функции список кандидатов переходит в n, а функция фильтра также использует n для расчета остатка. Вторая функция, однако, также использует n для расчета остатка, но вместо этого список кандидатов переходит на sqrt(n).

Чтобы сделать вторую функцию, эквивалентную, вам нужно переформулировать так:

let factors' (n:bigint) = 
    let k = bigint(sqrt(float(n))) 
    Seq.filter (fun x -> k % x = 0I) [1I..k] 

Update, чтобы прояснить этот вопрос несколько:
В приведенном выше коде, обратите внимание, как k используется в двух местах : создать исходный список кандидатов и рассчитать остаток в функции фильтра? Это именно то изменение, которое я внес в ваш код: мой код использует k в обоих местах, но ваш код использует k в одном месте, но n в другом.

Это как исходная функция будет выглядеть с k:

let factors' (n:bigint) = 
    let k = bigint(sqrt(float(n))) 
    Seq.filter (fun x -> n % x = 0I) [1I..k] 

Обратите внимание, как он использует k в одном месте, но n в другой.

+0

Спасибо за ответ, но я не говорил об эквивалентности функций. Вы видите, что когда я использовал первую функцию (тот, чьи кандидаты идут на n), я передал квадратный корень из 600851475143, а во втором (тот, чьи кандидаты попадают в sqrt (n)), я прошел только 600851475143 –

+1

Вот в чем смысл: в первой функции вы используете это значение 'sqrt'-ed для функции фильтра _both_ и исходного списка, но во второй функции значение' sqrt'-ed используется только для исходного списка, но не для функции фильтра. Функции не идентичны, даже если вы контролируете разные аргументы, переданные им. –

+0

Теперь я получаю, спасибо большое !!! –

Смежные вопросы