# pixelistik Blog

## Digital clock challenge - Anwers (Part 1)

written on 2023-01-04

I've worked on the Digital clock challenge, evaluating the initial and basic questions:

• is it theoretically possible to tell the time, just by looking at the level of light sent out by the clock?
• how long would you need to stare at the wall? 2 minutes? 20 minutes? Even hours?

These questions boil down to one: is a sequence of different brightness levels (changing each minute) so unique that it can be traced back to a specific time on the clock? Surely, looking a 1 minute only is not enough. The number of illuminated clock segments only goes from 8 to 26 - but there are 24 * 60 = 1440 minutes in a day.

So, let's write a program that

• generates the segment count for the sequence of all 1440 minutes in a day
• check how long we need to make a subset of this sequence in order to uniquely identify this subset in the full set

### The Python script that gives us the answer

Here's what I ended up with in Python:

```#!/usr/bin/env python
import logging
from datetime import time, timedelta, datetime, date

def digit_to_segment_count(digit):
"""
Take a single digit and return the number of "on" segments for it.
"""
SEGMENTS = [
6,  # 0
2,  # 1
5,  # 2
5,  # 3
4,  # 4
5,  # 5
6,  # 6
3,  # 7
7,  # 8
6,  # 9
]
return SEGMENTS[digit]

def time_to_segment_count(time):
"""
Return the total number of "on" segments of a (simple) time with 4 digits.

>>> time_to_segment_count(time.fromisoformat("00:00"))
24
>>> time_to_segment_count(time.fromisoformat("11:11"))
8
"""
sum = 0
sum += digit_to_segment_count(int(str(time)))
sum += digit_to_segment_count(int(str(time)))
sum += digit_to_segment_count(int(str(time)))
sum += digit_to_segment_count(int(str(time)))
return sum

def all_times():
"""
Generate all existing times from 00:00 to 23:59 and return their segment count.

>>> times = all_times()
>>> len(times) == 24 * 60
True
>>> times == 6 + 6 + 6 + 6 # 00:00 segment count
True
>>> times[-1] == 5 + 5 + 5 + 6 # 23:59 segment count
True
"""
all_times = []

current_time = time.fromisoformat("00:00")

for i in range(0, 24 * 60):
all_times.append(time_to_segment_count(current_time))
current_time = (
datetime.combine(date.today(), current_time) + timedelta(minutes=1)
).time()

return all_times

def get_windows(data, window_size):
"""
Given a list of n elements, generate n tuples with a given length.

>>> data = [0, 1, 2, 3, 4]
>>> get_windows(data, 1)
[(0,), (1,), (2,), (3,), (4,)]
>>> get_windows(data, 2)
[(0, 1), (1, 2), (2, 3), (3, 4), (4,)]
"""
windows = []
for i, _ in enumerate(data):
start = i
end = i + window_size
windows.append(tuple(data[start:end]))

return windows

def has_unique_elements(data):
"""
Check if a given list has only unique elements.

This is used to check if a given sequence of brightness levels designates
a specific time unambiguously.

>>> has_unique_elements([0, 1, 2])
True
>>> has_unique_elements([1, 0, 1])
False
>>> has_unique_elements([(0,1), (1,2), (2,3)])
True
>>> has_unique_elements([(0,1), (1,2), (0,1)])
False
"""
duplicate_count = len(data) - len(set(data))
logging.info("%i duplicates found" % duplicate_count)
return duplicate_count == 0

if __name__ == "__main__":
import doctest

logging.basicConfig(level=logging.ERROR, format="%(message)s")

doctest.testmod()

logging.getLogger().setLevel(logging.INFO)

# Generate segment count for all minutes of the day
all_times = all_times()

logging.info("Highest number of segments: %i" % max(all_times))
logging.info("Lowest number of segments: %i" % min(all_times))

# Increase length of observed minutes window, until we get an
# unambiguously identified time
for i in range(500):
logging.info("Testing if window size of %i minutes is unique." % i)
windows = get_windows(all_times, i)
if has_unique_elements(windows):
logging.info("Windows of size %i provide unique combinations." % i)
break
```

### The result: it will work

So, let's run it:

``````Highest number of segments: 26
Lowest number of segments: 8
Testing if window size of 0 minutes is unique.
1439 duplicates found
Testing if window size of 1 minutes is unique.
1421 duplicates found
Testing if window size of 2 minutes is unique.
1330 duplicates found
Testing if window size of 3 minutes is unique.
1216 duplicates found
Testing if window size of 4 minutes is unique.
1147 duplicates found
Testing if window size of 5 minutes is unique.
1096 duplicates found
``````

[...]

``````Testing if window size of 119 minutes is unique.
4 duplicates found
Testing if window size of 120 minutes is unique.
2 duplicates found
Testing if window size of 121 minutes is unique.
0 duplicates found
Windows of size 121 provide unique combinations.
``````

If we observe the digital clock brightness levels (as count of illuminated segments) for 121 minutes, this sequence of values is unique within the 24h of the day and thus enables us to tell the current time.

#### Small known issue: midnight

I could not yet be bothered to take a special case into account: if the observed time wraps around over midnight.