This is my 1st F# program so I'm open to any and all criticism on my syntax and the way I approached the problem.
Challenge
Project Euler 16: Power Digit Sum
2^15 = 32768 and the sum of its digits is 3 +たす 2 +たす 7 +たす 6 +たす 8 =わ 26. What is the sum of the digits of the number 2^1000?
open System
open System.Numerics
let digitPower (n:bigint) p = pown n p
let digitToPowerSum (n:bigint) p =
(digitPower n p) |>
string |>
(fun s -> s.ToCharArray()) |>
Array.map (fun x -> Int32.Parse (x.ToString())) |>
Array.sum
[<EntryPoint>]
let main argv =
let n = new bigint(2)
let p = 1000
let value = digitPower n p
let sum = digitToPowerSum n p
Console.WriteLine(String.Format("{0}^{1} = {2:n}", n, p, value))
Console.WriteLine()
Console.WriteLine(String.Format("Its digit sum is {0}", sum))
Console.ReadKey() |> ignore
0
I'm primarily concerned with
1 Answer 1
It's quite common to convert a number to a string to get the digits, and most of the times, it ought to work, but it's a hack, instead of modelling what should happen.
Here's another way to do it, which deliberately separates integers into its digits.
let rec digits i =
let tens = i / 10I
if tens = 0I
then [i]
else
let ones = i % 10I
(digits tens) @ [ones]
The rest is easy:
let euler16 x y = pown x y |> digits |> List.sum
Some examples from F# Interactive:
> euler16 2I 15;;
val it : System.Numerics.BigInteger = 26 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
> euler16 2I 1000;;
val it : System.Numerics.BigInteger = 1366 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
-
\$\begingroup\$ Could you explain the
10I
and0I
? I assume their some sort of byte representation? \$\endgroup\$Shelby115– Shelby1152015年11月06日 16:21:03 +00:00Commented Nov 6, 2015 at 16:21 -
1\$\begingroup\$ Oh nevermind, it's a bigint literal \$\endgroup\$Shelby115– Shelby1152015年11月06日 16:21:42 +00:00Commented Nov 6, 2015 at 16:21