patternMinor
Divide number by factors
Viewed 0 times
dividenumberfactors
Problem
I'm learning F#.
The code below gets a number e.g. 100 and list of factors and should divide that number by the factors without any rest. (There is an actual code I've got in C#, but this is F# port).
I especially didn't liked equalsDifference function.. any better solution?
and usage:
ok, as you suggested map is better:
```
let equalsDifference minUnit (difference: decimal) (l: decimal list) =
let listSize = List.length l
let mutable acc = difference
let resp = l |> List.map (fun element -> (
if acc <> 0m then
if difference = minUnit then
acc <- acc + minUnit
element - minUnit
else
The code below gets a number e.g. 100 and list of factors and should divide that number by the factors without any rest. (There is an actual code I've got in C#, but this is F# port).
I especially didn't liked equalsDifference function.. any better solution?
namespace RozbijaczApp
module Rozbijacz =
let precision = 2
let minUnit = 1m / (pown 10m precision)
let round x = System.Math.Round(decimal x, precision, System.MidpointRounding.AwayFromZero)
let mainMapper factor factorSum x =
round (x * factor / factorSum)
let equalsDifference minUnit (difference: decimal) (l: decimal list) =
let listSize = List.length l
let mutable acc = difference
[for i in [0..listSize-1] do
let element = l |> List.item i
if acc <> 0m then
if difference = minUnit then
acc List.sum
let result = factors |> List.map (fun x -> mainMapper number factorsSum x)
let controlSum = result |> List.sum
let difference = number - controlSum
printfn "Difference %O" difference
// add or substract diffenernce by minUnit for results
let fixResult = equalsDifference minUnit difference result
let finalControlSum = fixResult |> List.sum
let finalDifference = number - finalControlSum
printfn "Final difference %O should by zero"finalDifference
fixResultand usage:
let factors = [0.2m;0.3m;0.4m]
let results = Rozbijacz.divider 100m factors
printfn "Result: %A" resultsok, as you suggested map is better:
```
let equalsDifference minUnit (difference: decimal) (l: decimal list) =
let listSize = List.length l
let mutable acc = difference
let resp = l |> List.map (fun element -> (
if acc <> 0m then
if difference = minUnit then
acc <- acc + minUnit
element - minUnit
else
Solution
Instead of using mutable variables, it is possible to apply the fold:
let equalsDifference minUnit difference l =
l
|> List.fold
(fun (acc,xs) element ->
if acc <> 0m then
if difference = minUnit then
acc + minUnit, (element - minUnit)::xs
else
acc, element::xs
else
acc - minUnit, (element + minUnit)::xs
else
acc, element::xs)
(difference, [])
|> snd
|> List.revCode Snippets
let equalsDifference minUnit difference l =
l
|> List.fold
(fun (acc,xs) element ->
if acc <> 0m then
if difference < 0m then
if element >= minUnit then
acc + minUnit, (element - minUnit)::xs
else
acc, element::xs
else
acc - minUnit, (element + minUnit)::xs
else
acc, element::xs)
(difference, [])
|> snd
|> List.revContext
StackExchange Code Review Q#133472, answer score: 2
Revisions (0)
No revisions yet.