Counting digits appearing in page numbers
The other day in a training session, the facilitators warmed people up into intellectual work with this group exercise:
Count the number of times the digit “1” appears in the page numbers of a 90 page book.
Then, count the number of times it appears in the page numbers of a 2,000 page book.
(Actual numbers vary slightly from those used so I don’t just give away the answers).
The first task is easy enough; you can pretty much count them in your head (something like “1, 2, 3-4, plus 8 equals 12, plus 7 equals 19” - if you follow me). The second task is obviously harder and the aim was to illustrate the need to break down more complicated problems into a structure for a solution.
But the alternative message that occurred to me of course is that “this is why we invented computers isn’t it?”. Here’s the one-liner in R that answers the second question, about the 2,000 page book:
length(stringr::str_extract_all(paste(1:2000, collapse = &quot;&quot;), pattern = &quot;1&quot;, simplify = TRUE))Basically, starting from the middle, this tells the computer:
make a vector of all the numbers from 1 to 2,000
collapse them all into a single big character string
extract all the digits “1” from that string into a new vector which each element is just the extracted “1”
count the length of that vector
The answer is 1,600.
What about if we wanted to generalise this though - for more page numbers, and different digits? After the training session was over, I had a go at this. For the sake of efficiency and speed, I treated this as a slightly different problem and I solved it with the help of the count_digits function defined below which extracts the number of times a digit appears in a given page number; and then we use cumulative sums to get the eventual result for books of different lengths with minimal duplication of calculations.
Here’s the code to do this, and its application to a book of 2,500 pages, for all digits.
# more considered approach
library(tidyverse)
library(scales)
library(testthat)
library(stringr)
library(gridExtra)
count_digits %
right_join(refs, by = &quot;digit&quot;) %__%
gather(variable, value, -digit) %__%
ggplot(aes(x = as.ordered(digit), y = value, fill = variable)) +
geom_col(position = &quot;dodge&quot;) +
coord_flip() +
scale_fill_manual(&quot;&quot;, values = c(&quot;grey85&quot;, &quot;darkblue&quot;),
guide = guide_legend(reverse = TRUE)) +
ggtitle(main_title,
desc) +
labs(x = left_lab, y = bottom_lab) +
theme(legend.position = legend.position)
return(p) }
#---------------with simulated distributions---------------------
n