Solution to Project Euler problem 5 (LCM of 1 to 20)
Let's start with the loop inside findPrimeFactors. You have the right idea, but it's complicated because you're flattening two loops into one: looping over the primes, and looping over the factors for your target number.

So let's do those one at a time. First, let's create a function that finds the next prime factor:

let rec findNextFactor candidates n = 
    match candidates with
    | x::xs when n%x=0I -&gt; x
    | x::xs -&gt; findNextFactor xs n
    | _ -&gt; failwith "No factor found"


The first line matches when a factor is found, the second when no factor is found, and the third when the collection is empty. Note how matching on the collection makes it very easy to recursively loop through it by matching against x:xs. This helps avoid your issue of looping by index.

Now that we know how to find the next prime factor, it's easy to find all of them:

let rec loop acc n =
    match findNextFactor primes n with
    | n -&gt; n:acc
    | p -&gt; findPrimeFactors p:acc n/p


We're not passing primes in here as we're not iterating it here. The primes referred to is the outer one which always contains all the primes up to 20. By splitting out the loop, we only need to deal with these two simple cases.

Just glue those together and you get your findPrimeFactors implementation.



For findPrimeFactorsPowers, you're again increasing the complexity by completely changing your data type, from a list of factors, to a map of factors to the count of those factors. This isn't actually that hard. For a single number n it might look like:

let findPrimeFactorsPowers n =
    findPrimeFactors n
    |&gt; Seq.groupBy i -&gt; i
    |&gt; Seq.map i -&gt; (i.Key, i.Count)


I'm honestly not quite sure what your version is doing, so I can't compare very closely.

But actually, there's something even simpler we can do. Really all we want to do is merge two lists in a special way: for each value, the number of times that value appears in the merged list should equal the maximum number of times it appears in each individual list.

By taking advantage of the fact that our lists are sorted, we can do that very easily:

let rec merge a b acc =
match a,b with
| x::xs, y::ys when x = y -&gt; merge xs ys (x::acc)
| x::xs, y::ys when x &lt; y -&gt; merge xs b (x::acc)
| x::xs, y::ys -&gt; merge a ys (y::acc)
| _, [] -&gt; List.append (List.rev acc) a 
| [], _ -&gt; List.append (List.rev acc) b


We loop over the lists, take the head of each one. If they're equal, remove both heads and add it to the accumulator, otherwise take just the lowest and add that. Finally the last lines let us terminate once a list is empty.

This is the last piece we need. Now we just need to get the prime factor lists for each number under 20, and merge each one in turn into an empty list. Finally find the product of the numbers in the resultant list, and you have your answer.



For more general comments, there isn't much I can find to fault. There's a couple of times you declare a variable, then only use it once in the next line. Not doing that means you can get rid of the cumbersome name smallestNumberDivisableByAllNumbersBelown. 

Also, you should probably trim out some unnecessary comments. If you're just learning F#, the idea that the last expression of a function is what gets returned might cause enough cognitive friction for you that you want to leave yourself a comment, but those shouldn't be in part of a finished piece of code.

Generally, though, stylistically the code is good, including both naming and organization.