HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

BestApproximationDiv2 problem in Haskell

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
problembestapproximationdiv2haskell

Problem

The task is to write a function findFraction maxDen number to find a short but good rational approximation to a decimal representation of a number — problem statement on TopCoder:


Given a fraction F = A/B, where 0

  • Let N be the number of digits after the decimal point in number. If number has trailing zeros, all of them are considered to be significant and are counted towards N.



  • If S is infinite or the number of digits after the decimal point in S is greater than N, only consider the first N decimals after the decimal point in S. Truncate the rest of the digits without performing any kind of rounding.



  • If the number of digits after the decimal point in S is less than N, append trailing zeroes to the right side until there are exactly N digits after the decimal point.



  • The quality of approximation is the number of digits in the longest common prefix of S and number. The longest common prefix of two numbers is the longest string which is a prefix of the decimal representations of both numbers with no extra leading zeroes. For example, "3.14" is the longest common prefix of 3.1428 and 3.1415.





[…] You are only allowed to use fractions where the denominator is less than or equal to maxDen. Find an approximation F = A/B of number such that 1 <= B <= maxDen, 0 <= A < B, and the quality of approximation is maximized. Return a String formatted "A/B has X exact digits" (quotes for clarity) where A/B is the approximation you have found and X is its quality. If there are several such approximations, choose the one with the smallest denominator among all of them. If there is still a tie, choose the one among those with the smallest numerator.

```
import Data.Char
import Data.List
import Data.Maybe

showResult :: (Int, Int, Int) -> String
showResult (a, b, x) = show a ++ "/" ++ show b ++ " has "
++ show x ++ " exact digits"

compareDigits :: [Int] -> [Int] -> Ordering
compareDigits xs [] = EQ
compareDigits (x:xs) (y:ys) =

Solution

Hmmm, not much ideas, only syntax:

showResult :: (Int, Int, Int) -> String
showResult (a, b, x) = concat [show a, "/", show b, " has ", show x, " exact digits"]

preciseDivision :: Int -> Int -> [Int]
preciseDivision a b = let (d,r) = divMod (10*a) b in d : preciseDivision r b 

...where toResult ds p b = fmap (\a -> (a, b, 1 + length ds)) $ bestNumerator ds p b

Code Snippets

showResult :: (Int, Int, Int) -> String
showResult (a, b, x) = concat [show a, "/", show b, " has ", show x, " exact digits"]


preciseDivision :: Int -> Int -> [Int]
preciseDivision a b = let (d,r) = divMod (10*a) b in d : preciseDivision r b 


...where toResult ds p b = fmap (\a -> (a, b, 1 + length ds)) $ bestNumerator ds p b

Context

StackExchange Code Review Q#3340, answer score: 5

Revisions (0)

No revisions yet.