immutability - Why do I have the feeling my F# code could be more concise -


i'm experienced c# developer trying teach myself f#. spent day or 3 reading throught f# wikibook trying know syntax , f# fundamentals.

as exercise i'm trying go through project euler problems better feeling of syntax , working language.

i've solved problem 5. i'm not happy hoops had jump through data structure represents solution. i've used this blogpost algorithm solving problem.

i wondering if give me pointers how code improved? guess inherent immutability of f# values causing me have perform lot of steps exact data want...

this code:

let main argv = //calculates prime factors of number let findprimefactors x =     let primes = [|2i;3i;5i;7i;11i;13i;17i;19i|]     let rec loop acc counter = function         | x when x = 1i -> failwith "a prime definition greater 1"         | x when primes |> array.contains x -> x :: acc         | x when counter = primes.length -> failwith "my list of known primes not big enough"         | x when x%primes.[counter]=0i-> loop (primes.[counter]::acc) (counter) (x/primes.[counter])         | x -> loop acc (counter + 1) x      let primefactor = loop [] 0 x |> list.rev     primefactor  //calculates prime factors each of numbers between 2 , n //then, each of prime factorizations tries find highest power each occurring prime factor let findprimefactorspowers n =     //builds map of prime factor powers prime factorizations     let rec addcounterfactorpowers factorpowers = function         | counter when counter = n -> factorpowers         | (counter : int) -> addcounterfactorpowers ((findprimefactors (counter|>bigint) |> list.countby (fun x-> x)) @ factorpowers) (counter + 1)     let allfactorpowers = addcounterfactorpowers [] 2     //group powers per prime factor     let groupedfactorpowers = allfactorpowers |> list.groupby (fun (factor, power) -> factor)     //get highest power per prime factor     let maxfactorpowers = groupedfactorpowers |> list.map (fun (key, powers) -> (key, powers |> list.map (fun (factor, power) -> power) |> list.max))      //return result     maxfactorpowers          let n = 20;  let primefactorset = findprimefactorspowers n printfn "%a" primefactorset  let smallestnumberdivisablebyallnumbersbelown =  (primefactorset |> list.fold (fun state (factor, power) -> state * pown factor power) 1i) printfn "result %a" smallestnumberdivisablebyallnumbersbelown  system.console.readkey(true)|>ignore 0 // return integer exit code 

there many direct simplifications can apply code, don't think that's best approach.

this way solve problem in f#:

let rec trydivide n m =     if m = 1 true     else         if n % m = 0 trydivide n (m-1)         else false  let rec findit m =     if trydivide m     else findit (i+1) m  findit 1 20 

it's bit slower yours because doesn't use hardcoded primes, they're calculated on fly, still takes less 2 secs on computer right answer.

note i'm not using list-like data structure , no need rely on big integers in specific problem.

update

here's better approach based on kvb's proposed solution:

let rec gcd x y = if y = 0 abs x else gcd y (x % y)  let lcm b =      match (a, b)     | (_, 0) | (0, _) ->  0     | (x, y) -> abs ((x / (gcd x y)) * y)  seq.fold lcm 1 {2..20} 

Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

css - Can I use the :after pseudo-element on an input field? -