I came across this problem by accident and gave it a go. I think my solution works as it has passed all the unit tests I wrote. Given I just started learning F# a couple of weeks I would love to have some feedback on the code regarding both its accuracy and its quality.
To be clear about the problem, given an integer number, check whether the number has at least 3 same digits in it e.g. 1222, 12222, 222, 123123123 are both counted as yes.
module Miscellaneous =
let (|ThreeSame|_|) = function
| (l : int list) when l.Length > 20 -> Some()
| x :: y :: z :: _ when x = y && y = z -> Some()
| _ -> None
///<summary>
/// Given any integer convert its digits into a list
///</summary>
///<param name="number">The integer</param>
///<returns>
///A int list
///</returns>
let convertNumberToList (number: bigint) =
let numberString = string number
numberString.ToCharArray()
|> Array.map (string >> int) //use composition to replace (fun x -> int (string x))
|> Array.toList
type NumberCheck() =
///<summary>
/// A helper function to check whether a list of numbers contains three or more
/// same numbers
///</summary>
///<param name="l">The list to be checked</param>
///<param name="sorted">The flag to indicate whether the given list is sorted or not</param>
///<returns>
/// True if there are at least 3 same numbers; False otherwise
///</returns>
static member private TripleNumberHelper(l : int list, ?sorted) =
if l.Length < 3 then false
else
if defaultArg sorted false then
match l with
| Miscellaneous.ThreeSame -> true
| _ -> NumberCheck.TripleNumberHelper(l.Tail, true)
else
let sortedList = l |> List.sort
match sortedList with
| Miscellaneous.ThreeSame -> true
| _ -> NumberCheck.TripleNumberHelper(sortedList.Tail, true)
///<summary>
/// Test whether a number has 3 or more same digits in it
///</summary>
///<param name="number">The number to be checked</param>
///<returns>
///Ture of False
///</returns>
static member TripleNumber(number : bigint) =
let l = Miscellaneous.convertNumberToList number
NumberCheck.TripleNumberHelper(l)
groupBy
is a much better way of doing it. I have given it a try and please have a look at my implementation and any feedback is appreciated. \$\endgroup\$groupBy
is also better as it'sO(n)
whereas the original way needs sorting hence isO(nlogn)
? \$\endgroup\$