How do I count thee? Let me count the ways?

The dead body problem, and the coffee with milk problem

      Here are two problems in life we all commonly face: What time did the victim die, and is it better to put milk in your coffee r...

Sunday, September 15, 2024

The dead body problem, and the coffee with milk problem

      Here are two problems in life we all commonly face: What time did the victim die, and is it better to put milk in your coffee right away or to wait?
      In any police show with a murder, one of the detectives will always ask this math question: "What time did the victim die?" And yes, it is a math question, whose solution dates back over 300 years to Isaac Newton. For algebra and calculus students, it is probably more interesting than a lot of word problems they see.

      Newton’s Law of Cooling states that the rate of change of the temperature of an object is proportional to the difference between its own temperature and the surrounding temperature.

         Let the temperature of the object be T(t) at time t.
         Let T0 denote the initial temperature of the object at time 0.
         Let Ts denote the temperature of the surrounding medium.

      Newton's Law of Cooling states    dT/dt = -k (T - Ts),    where k is a cooling constant and where the negative sign is for the case where the body is getting cooler. The solution of the differential equation is:

T(t) = Ts + (T0 - Ts) * e^(-k*t)

      Newton published his Law of Cooling in 1701. Modern physicists believe Newton's Law holds up well and approximates the result in some but not all situations. Large temperature differences between the object and its surroundings, or non-constant temperatures, will cause difficulties. I leave the details to the physicists.

Problem 1: The dead body problem

      Example: A dead body was 80 degrees Fahrenheit when it was discovered. Two hours later it had cooled to 75 degrees. The room is 60 degrees. What time did the body die?

Assume T0 at time of death = 98.6
Assume Ts the temperature of surrounding room = 60
Let k be the unknown cooling constant. k depends on the characteristics of the object and its environment and is often between 0.1 and 0.2.

T(t) = Ts + (T0 − Ts​) * e^(−kt)

First equation, at time of discovery:
Let t = t_0 be time of discovery.    80 = 60 + (98.6 - 60) * e^(-k*t_0)

Second equation, two hours later:
At t = t_0 + 2,    75 = 60 + (98.6 - 60) * e^(-k*(t_0 + 2))

Solve first equation for k:
80 = 60 + (98.6 - 60) * e^(-k*t_0)
20 = 38.6 * e^(-k*t_0)
e^(-k*t_0) = 20 / 38.6 = .518

Solve second equation for k:
75 = 60 + (98.6 - 60) * e^(-k*(t_0 + 2))
15 = 38.6 * e^(-k*(t_0 + 2))
e^(-k*(t_0 + 2)) = 15 / 38.6 = .389

Solve for k by taking the ratio of the two equations, noting t_0 drops out:
[e^(-k*(t_0 + 2))] / [e^(-k*t_0) ] = .389 /518
e^(-2k) = .751
-2k = LN(.751)
k = - LN(.751) / 2
k = .143

Solve for time since death from first equation
80 = 60 + (98.6 - 60) * e^(-.143*t_0)
20 = 38.6 * e^(-.143*t_0)
e^(-.143*t_0) = 20 / 38.6 = .518
-.143*t_0 = LN(.518)
t_0 = - LN(.518) / .143
t_o = 4.8 hours

The body had been cooling for 4.8 hours before it was discovered.

Problem 2: The coffee with milk problem

      Here is a different application of Newton's Law of Cooling.

      Example: Who drinks the hotter coffee after five minutes: The person who puts milk in right away and then waits five minutes, or the person who waits five minutes and then puts in milk?

Assume initial temperature of coffee, T0 = 200 F
Assume temperature of the room, Ts = 72 F
Assume initial temperature of the milk, Tm = 40 F
Assume the mixture is 80% coffee and 20% milk
Assume cooling constant k = 0.1.

Case 1: Add cold milk immediately

mixture T(0) = .80*200 + .20*40 = 168
mixture T(5) = 72 + (168 − 72) * e^(−0.1*5) = 130.23

Case 2: Wait 5 minutes, then add room temperature milk

coffee T(5) = 72 + (200 - 72)*e^(-0.1*5) = 149.64
milk T(5) = 72 + (40 - 72)*e^(-0.1*5) = 52.59
mixture T(5) = .80*149.64 + .20*52.59 = 130.23

The conclusion is that cases 1 and 2 give the same temperature! However, there is also a case 3.

Case 3: Wait 5 minutes, then add cold milk

coffee T(5) = 72 + (200 - 72)*e^(-0.1*5) = 149.64
mixture T(5) = .80*149.64 + .20*40 = 127.71

For simplicity, I ignored a few things that probably have a minor effect on the final temperature: I assume the mixing process is instantaneous. I assume the cup does not absorb heat from the coffee. I assume stirring the mixture does accelerate heat transfer. Perhaps there are others. I can not measure the effect of these.

Thank you, Isaac Newton (who as a Brit, perhaps drank tea?).

End

Sunday, September 8, 2024

Mind reader game, and Unicode symbols

Mind reader game, and Unicode symbols, by Jerry Tuttle

Perhaps you've seen this Mind Reader game? Think of a two-digit positive whole number, such as 54. Subtract each of the two digits from your number, such as 54 - 5 - 4 = 45, and call 45 the RESULT. Examine the table of symbols below and find the SYMBOL that corresponds with your RESULT. Concentrate on the SYMBOL, and remember it. Then scroll down below, and I will read your mind to predict your SYMBOL.

Before I get to my prediction, let's talk about Unicode symbols.

Unicode symbols

Unicode is a standard international system that assigns a unique Unicode number to each letter, digit, or symbol. This permits thousands of symbols to be written across different platforms, programs, and languages. An example of a Unicode number is "U+" followed by a hex number, such as U+1F499.

The table of symbols in the Mind Reader game is based on plotting a variety of Unicode symbols by printing their Unicode numbers.

A Unicode symbol is printed in R with its Unicode number, but beginning with a backslash to escape the U, and omitting the plus sign. For example, here is how to print a heart symbol.

print("\U1F499")
"💙"

Example with Hebrew letters

Let's spell out the Hebrew word shalom , letter by letter, with each letter's Unicode number, and then use the R paste command to paste the letters together.

    shin <- "\U05E9"     # "ש"
    kamatz <- "\U05B7"     # vowel as two perpendicular lines "ַ"
    lamed <- "\U05DC"     # "ל"
    vav <- "\U05D5"     # "ו"
    final_mem <- "\U05DD"     # "ם"
    shin_with_kamatz <- "\U05E9\U05B7"     # "שַ"
    paste(shin_with_kamatz, lamed, vav, final_mem, sep = "")

"שַלום"

Note that the letters are entered in the paste statement in order of first Hebrew letter, second Hebrew letter, etc., but they are printed in Hebrew right-to-left. Also, a better choice than vav is cholam, which is vav with a dot above it, "\U05BA", but this doesn't print for me.

My prediction

Here is my prediction of your symbol:

Want to play again? Think of another two-digit positive whole number, such as 54. Subtract each of the two digits from your number, such as 54 - 5 - 4 = 45, and call 45 the RESULT. Examine the table of symbols below and find the SYMBOL that corresponds with your RESULT. Concentrate on the SYMBOL, and remember it. Then scroll down below, and I will read your mind to predict your SYMBOL.

Plotting with Unicode characters

Tired of plotting points with those boring 25 pch symbols? You can use Unicode symbols, but you can't simply use pch = . Here for no good reason I use a heart and a thumbs up.

library(ggplot2)
x <- seq(from=0,to=4, by=1)
y <- x^2
z <- exp(x)
df1 <- data.frame(x, y)
df2 <- data.frame(x, z)
heart <- "\U1F499"
thumbs_up <- "\U1F44D"
# Create a custom function to convert Unicode values to GeomPoint
custom_points <- function(data, mapping, ..., shape = heart) {
    ggplot2::geom_point(data = data, mapping = mapping, ..., shape = shape)
}
ggplot() +
    custom_points(data = df1, aes(x = x, y = y, color = "y = x^2"), shape = heart, size=5) +
    geom_line(data = df1, aes(x = x, y = y, color = "y = x^2")) +
    custom_points(data = df2, aes(x = x, y = z, color = "z = exp(x)"), shape = thumbs_up, size=5) +
    geom_line(data = df2, aes(x = x, y = z, color = "z = exp(x)")) +
    ggtitle("Plot with Unicode points") +
    labs(color = "Function") +
    theme(legend.position = c(0.15, 0.85),
      plot.title = element_text(color="black", size=14, face="bold"),
      legend.text = element_text(color="black", size=10, face="bold"))

My second prediction

Here is my second prediction:

Here is the code for the mind reader:

# start with arbitrary set of unicode symbols
description =
    c("a_bengali","a_gurmukhi","approximately_equal","biohazard","black_diamond",
    "black_heart","black_scissors","mercury",
    "mushroom","nya_gujarati",
    "section","snowflake",
    "snowman","teardrop_spoked_asterisk","thunderstorm",
    "umbrella_raindrops","white_cross","white_florette",
    "zhe_cyrillic", "airplane",
   "black_right_arrow","black_telephone","blue_heart",
    "two_xs","hot_beverage","green apple","pill",
    "trophy","thumbs_up")

unicode=
    c("\U0986","\U0A05","\U2248","\U2623","\U25C6","\U2665","\U2702","\U263F",
    "\U1F344","\U0A9E","\U00A7","\U2746",
    "\U26C4","\U273B","\U2608","\U2614","\U271E","\U2740",
    "\U04DC","\U2708","\U27A4","\U260E","\U1F499","\U1F9E0","\U2615","\U1F34F",
   "\U1F48A","\U1F3C6","\U1F44D")

df_uni <- data.frame(cbind(description, unicode))
n <- nrow(df_uni)
x <- seq(1,n,1)
s <- sample(x, 1)
diag <- unicode[s]
diag
x <- x[-x[s]]
y <- sample(x, 100, replace = TRUE)     # randomly choose 100 symbols

df <- data.frame(matrix(ncol = 20, nrow = 10))

for (i in seq(1, 19, by = 2)) {
    df[, i] <- seq(99, 9, -10) - (i - 1) / 2 # row i, odd columns
    df[, i + 1] <- y[((i - 1) / 2 * 10 + 1):((i - 1) / 2 * 10 + 10)] # row i, even columns
    df[, i + 1] <- unicode[df[, i + 1]]
}

for (i in 1:10) {
    df[i, 20 - 2*(i - 1)] <- diag
}

op <- par(bg = "thistle")
plot(x = c(0, 50*20), y = c(0, 50*10), type = "n", xlab = "", ylab = "", xaxt = 'n',
    yaxt = 'n', main = "Mind Reader # 1", cex=2, font=2)

# Loop through each cell of the dataframe to draw rectangles and add text
for (i in 1:20) {
    for (j in 1:10) {
      # Determine the color based on whether the column index is odd or even
      fill_color <- ifelse(i %% 2 == 1, "cornsilk", "lightblue")

      # Draw rectangle with the determined color
      rect(50*(i-1), 50*(10-j), 50*i, 50*(10-j+1), col = fill_color, border = "blue")

      # Add text in the center of the rectangle
      text(50*(i-1) + 25, 50*(10-j) + 25, df[j, i], col = "navyblue", cex = 1, font = 2)
      }
}

# Restore original graphics parameters
par(op)

Hint on prediction

The prediction relies on a little algebra. As a hint, your original two-digit whole number is of the form, 10*T + U. What happens when you subtract the digits?

End

<