2013-08-08 3 views
1

Первый снимок в Euler #3 в F #, и я хотел бы вернуть более логичное значение, чем это изменяемое значение.F # Возвращение булева

// A number is prime if can only divide by itself and 1. Can only be odd. 
let isPrime x = 
    if (x%2L = 0L) then 
     false 
    else 
     let mutable result = true 
     for i in 3L..x/2L do 
      if (x%i = 0L) then 
       result <- false 
     result 

let a = isPrime(17L) 

// True 
printfn "%b" a 

Отель L's являются такими, как я принуждая функцию, чтобы вернуть bigints (там должен быть лучший способ тоже, но один шаг за один раз) ....

Редактировать Gradbot-х решение

let isPrime x = 
    // A prime number can't be even 
    if (x%2L = 0L) then 
     false 
    else 
     // Check for divisors (other than 1 and itself) up to half the value of the number eg for 15 will check up to 7 
     let maxI = x/2L 

     let rec notDivisible i = 
      // If we're reached more than the value to check then we are prime 
      if i > maxI then 
       true 
      // Found a divisor so false 
      elif x % i = 0L then 
       false 
      // Add 2 to the 'loop' and call again 
      else 
       notDivisible (i + 2L) 

     // Start at 3 
     notDivisible 3L 
+0

Gradbot - Мне понравился ваш ответ .. но потом оно было удалено –

ответ

3

вы можете заменить пункт еще с FORALL:

Seq.forall (fun i -> x % i <> 0L) { 3L .. x/2L } 

, а затем еще больше сократить его до одного выражения:

x % 2L <> 0L && Seq.forall (fun i -> x % i <> 0L) { 3L .. x/2L } 

хотя я не вижу никаких оснований для лечения 2 по-разному, вы можете просто сделать:

let isPrime x = 
    { 2L .. x/2L } |> Seq.forall (fun i -> x % i <> 0L) 
+0

Одно потенциальное преимущество обработки 2 отдельно - вы можете повторить два раза ('3L .. 2L .. x/2L') на втором шаге, который быстрее на ощупь. – latkin

+0

Я имел в виду с учетом остальной части кода. Алгоритмически все еще есть много способов улучшить это –

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