How I microwave food

September 20, 2024 (2y ago)

To optimize my microwave process and get back to coding as quickly as possible, I need to find the most efficient way to enter cooking times.

When I microwave, I don’t press 1, 0, and 0 to set a one-minute timer. Instead, I press 6 and 0. This way, I can save a third of the energy used every time I microwave food for some time of less than or equal to 1 minute and 39 seconds. But the calculation doesn’t end here. There must be a way to determine the best sequence for entering a time on the microwave keypad.

Now, to determine the best sequence we have to calculate the distance between each button. First, we can convert the microwave keypad into a coordinate system:

The button 1 is positioned at (-1, 3).

The button 2 is positioned at (0, 3).

The button 3 is positioned at (1, 3).

The button 4 is positioned at (-1, 2).

The button 5 is positioned at (0, 2).

The button 6 is positioned at (1, 2).

The button 7 is positioned at (-1, 1).

The button 8 is positioned at (0, 1).

The button 9 is positioned at (1, 1).

The button 0 is positioned at (0, 0).

Next, to calculate the minimum distance, we can use the Euclidean distance formula, which is the square root of the horizontal distance squared plus the vertical distance squared.

The total distance for a sequence would be calculated as the sum of individual distances. Since the keypad only has 10 buttons, there are only 100 possible button pairs, so all of their distances can be precomputed once into a lookup table. Scoring any sequence after that is just table lookups, with no square roots computed per keypress.

Next, when determining the optimized sequence for entering a specific time, there might be multiple ways to input the sequence. If the seconds component is less or equal to 39, there are potentially two options to represent the time:

  1. Entering the time as MMSS, where M represents the minutes and S represents the seconds.
  2. Adjusting the sequence so that the total seconds fit within a single minute, which can be written as (MM-1)(SS+60).

For example, when computing 2 minutes and 39 seconds, the valid sequences are “239” and “199”.

If we calculate the distance travelled:

  • "239" yields a result of 3.0 units.
  • "199" yields a result of approximately 2.8284 units.

This effectively saves about 5.72% of the original energy required.

Another example would include computing 5 minutes and 31 seconds, which has valid sequences “531” and “491”.

If we calculate the distance travelled:

  • "531" has a distance of around 3.4142 units.
  • "491" has a distance of around 5.0645 units.

That’s about 32.59% of the energy saved!

The algorithm has spoken!

# some python code I wrote in <5 minutes
# single digit inputs do not work, because why would you compute them anyways?
 
from itertools import pairwise
from math import dist
 
keypad_coords = {
    '1': (-1, 3), '2': (0, 3), '3': (1, 3),
    '4': (-1, 2), '5': (0, 2), '6': (1, 2),
    '7': (-1, 1), '8': (0, 1), '9': (1, 1),
    '0': (0, 0)
}
 
# only 10 buttons, so precompute all 100 pairwise distances once
DISTANCES = {
    (a, b): dist(pa, pb)
    for a, pa in keypad_coords.items()
    for b, pb in keypad_coords.items()
}
 
def total_distance(sequence):
    return sum(DISTANCES[pair] for pair in pairwise(sequence))
 
def optimized_sequence(minutes, seconds):
    seq1_minutes = minutes
    seq1_seconds = seconds
 
    seq1 = f"{seq1_minutes if seq1_minutes > 0 else ''}{seq1_seconds:02}"
 
    seq2 = None
    if minutes > 0 and seconds <= 39:
        seq2_minutes = minutes - 1
        seq2_seconds = seconds + 60
        # Option 2: (MM-1)(SS+60) format
        seq2 = f"{seq2_minutes if seq2_minutes > 0 else ''}{seq2_seconds:02}"
 
    dist1 = total_distance(seq1)
    dist2 = total_distance(seq2) if seq2 else float('inf')
 
    if dist1 <= dist2:
        return seq1, dist1, seq2, dist2
    else:
        return seq2, dist2, seq1, dist1
 
time_minutes = 1
time_seconds = 39
 
best_sequence, min_distance, worst_sequence, max_distance = optimized_sequence(time_minutes, time_seconds)
 
print(f"Best sequence for {time_minutes} minutes and {time_seconds} seconds: {best_sequence}")
print(f"Minimum distance: {min_distance:.4f}")
print(f"Worst sequence: {worst_sequence}")
print(f"Maximum distance: {max_distance:.4f}")
print(f"Percent saved: {((1 - min_distance / max_distance) * 100):.2f}%")