Project Euler: Power Digit Sum

r
project euler
puzzle
Find the sum of the digits
Author

Stephen Feagin

Published

September 4, 2023

Project Euler problem 16: Power Digit Sum. The brief reads:

\(2^{15} = 32768\) and the sum of its digits are \(3 + 2 + 7 + 6 + 8 = 26\) What is the sum of the digits of the number \(2^{1000}\)?

Solution

R

An important hiccup for solving this in R is R’s built in scientific notation representation. For a number as large as 2^1000, we need to disable scientific notation so that we actually get all of the digits. You do this by setting the scipen option, which applies a “penalty” to displaying scientific notation before a prescribed number of digits. You can also do this with the scientific argument of the format() function. We need to convert the integer to a character anyway, so using format() is fine for our purposes. We need to split the integer into its component digits, convert those back into numeric type, and then add them together. Note that for strsplit() we have to add [[1]] to get the result we want. This is because strsplit() can act on a vector of character strings, and returns a list of vectors of the component characters. In our case, the vector is length 1 but it still returns a list of length 1, so we need to specify that we want the first item in the list, rather than the whole list.

num <- format(2^1000, scientific = FALSE)
digits_char <- strsplit(num, "")[[1]]
digits_num <- as.numeric(digits_char)
sum(digits_num)
[1] 1366

Python

We again have to suppress scientific notation, but in python we use the .nf notation for format strings.

import math
num_char = format(math.pow(2, 1000), ".0f")
digits_num = [int(x) for x in num_char]
sum(digits_num)
1366

Go

As I’ve mentioned before, Go has very little magic so you have to be very explicit and verbose in your code. In our case, that means iterating through slices and acting on each item individually rather than using vectorization (as in R) or list comprehension (as in python).

import (
    "fmt"
    "math"
    "strconv"
    "strings"
)

func main() {
    // number as string
    num := math.Pow(2, 1000)
    numChar := fmt.Sprintf("%.0f", num)
    digitsChar := strings.Split(numChar, "")
    digitsInt := make([]int, len(digitsChar))
    for i := 0; i < len(digitsChar); i++ {
        digitsInt[i], _ = strconv.Atoi(digitsChar[i])
    }
    total := 0
    for i := 0; i < len(digitsInt); i++ {
        total += digitsInt[i]
    }
    fmt.Println(total)
}

See all of my Project Euler solutions on GitHub.