
…What?
Whenever I see a digital clock, I do a little math in my head. I try to take the numbers and, using only addition, subtraction, multiplication and division, get them to come out to twelve. I thought I’d try to get an exhaustive list of times that this trick applies to. Let’s figure it out!
import re
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
Get with the times
First we need to get a list of the times. I’m going to work with strings. Let’s go through some numbers and rule out invalid ones by places.
valid = []
for x in range(100, 1260):
num = ''
num += str(x)
if len(num) == 3:
if int(num[0]) <= 9 and int(num[1]) <= 5:
valid.append(num)
if len(num) == 4:
if int(num[0]) <= 1 and int(num[1]) <= 2 and int(num[2]) <= 5:
valid.append(num)
Cool. We can check that we have 720, which is half of all times since they all repeat once. Now we can go about making possible math expressions.
len(valid)
720
valid[:4]
['100', '101', '102', '103']
Prep the times
To do this, I’m going to put together strings of math expressions for all permutations of the numbers, then evaluate them and see which ones work. Certainly brute force, but it’ll work. First, I make a dictionary of all permutations of the numbers for each time.
# moded from https://www.geeksforgeeks.org/python-permutation-given-string-using-inbuilt-function/
from itertools import permutations
def allPermutations(str):
perm_array = []
# Get all permutations of string 'ABC'
permList = permutations(str)
# print all permutations
for perm in list(permList):
result = ''.join(perm)
perm_array.append(result)
return list(set(perm_array))
time_dict = {}
for time in valid:
time_dict[time] = allPermutations(time)
time_dict['957']
['795', '957', '579', '597', '759', '975']
Now, I go and add in all possible combinations of operators (+, -, *, /
) in between the numbers. I also add in parens since eval
follows PEMDAS and we want to avoid that in many cases.
equations = {}
for time, perms in time_dict.items():
eq = ''
ops = '+-*/'
if len(time) == 3:
equations[time] = []
for perm in perms:
for a in ops:
for b in ops:
eq = f"{perm[0]}{a}{perm[1]}{b}{perm[2]}"
eq = re.sub(r'([0-9])', r'\1)', eq)
eq = '(((' + eq
equations[time].append(eq)
if len(time) == 4:
equations[time] = []
for perm in perms:
for a in ops:
for b in ops:
for c in ops:
eq = f"{perm[0]}{a}{perm[1]}{b}{perm[2]}{c}{perm[3]}"
eq = re.sub(r'([0-9])', r'\1)', eq)
eq = '((((' + eq
equations[time].append(eq)
equations['100'][:10]
['(((0)+0)+1)',
'(((0)+0)-1)',
'(((0)+0)*1)',
'(((0)+0)/1)',
'(((0)-0)+1)',
'(((0)-0)-1)',
'(((0)-0)*1)',
'(((0)-0)/1)',
'(((0)*0)+1)',
'(((0)*0)-1)']
Look at the time
Cool. Now that we have a bunch of expressions, let’s evaluate them and see what we get.
they_work = {}
for time, eq_list in equations.items():
for eq in eq_list:
try:
result = eval(eq)
except ZeroDivisionError:
continue
if result == 12 and time not in they_work.keys():
they_work[time] = eq
they_work
{'116': '(((1)+1)*6)',
'124': '(((2)+1)*4)',
'125': '(((5)+1)*2)',
'126': '(((6)*1)*2)',
'127': '(((7)-1)*2)',
'129': '(((9)+1)+2)',
'133': '(((1)+3)*3)',
'134': '(((1)*4)*3)',
'135': '(((5)-1)*3)',
'136': '(((3)-1)*6)',
'138': '(((1)+3)+8)',
'139': '(((3)+9)*1)',
'142': '(((2)+1)*4)',
'143': '(((1)*4)*3)',
'144': '(((4)-1)*4)',
'147': '(((7)+4)+1)',
'148': '(((8)+4)*1)',
'149': '(((9)+4)-1)',
'152': '(((5)+1)*2)',
'153': '(((5)-1)*3)',
'156': '(((6)+1)+5)',
'157': '(((1)*7)+5)',
'158': '(((5)-1)+8)',
'206': '(((2)+0)*6)',
'214': '(((2)+1)*4)',
'215': '(((5)+1)*2)',
'216': '(((6)*1)*2)',
'217': '(((7)-1)*2)',
'219': '(((9)+1)+2)',
'223': '(((3)*2)*2)',
'224': '(((2)+4)*2)',
'225': '(((5)*2)+2)',
'227': '(((7)*2)-2)',
'228': '(((2)+2)+8)',
'232': '(((3)*2)*2)',
'233': '(((3)+3)*2)',
'236': '(((2)*3)+6)',
'237': '(((2)+3)+7)',
'238': '(((3)/2)*8)',
'239': '(((9)-3)*2)',
'241': '(((2)+1)*4)',
'242': '(((2)+4)*2)',
'244': '(((4)*2)+4)',
'245': '(((5)-2)*4)',
'246': '(((4)+6)+2)',
'248': '(((2)*8)-4)',
'251': '(((5)+1)*2)',
'252': '(((5)*2)+2)',
'254': '(((5)-2)*4)',
'255': '(((2)+5)+5)',
'259': '(((5)-2)+9)',
'304': '(((0)+4)*3)',
'309': '(((0)+3)+9)',
'313': '(((1)+3)*3)',
'314': '(((1)*4)*3)',
'315': '(((5)-1)*3)',
'316': '(((3)-1)*6)',
'318': '(((1)+3)+8)',
'319': '(((3)+9)*1)',
'322': '(((2)+2)*3)',
'323': '(((3)+3)*2)',
'326': '(((2)*3)+6)',
'327': '(((2)+3)+7)',
'328': '(((3)/2)*8)',
'329': '(((9)-3)*2)',
'331': '(((1)+3)*3)',
'332': '(((3)+3)*2)',
'333': '(((3)*3)+3)',
'335': '(((5)*3)-3)',
'336': '(((3)+6)+3)',
'337': '(((7)-3)*3)',
'340': '(((0)+4)*3)',
'341': '(((1)*4)*3)',
'345': '(((5)+3)+4)',
'346': '(((6)-3)*4)',
'348': '(((8)-4)*3)',
'349': '(((9)/3)*4)',
'351': '(((5)-1)*3)',
'353': '(((5)*3)-3)',
'354': '(((5)+3)+4)',
'356': '(((5)-3)*6)',
'359': '(((9)-5)*3)',
'403': '(((0)+4)*3)',
'408': '(((8)+4)+0)',
'412': '(((2)+1)*4)',
'413': '(((1)*4)*3)',
'414': '(((4)-1)*4)',
'417': '(((7)+4)+1)',
'418': '(((8)+4)*1)',
'419': '(((9)+4)-1)',
'421': '(((2)+1)*4)',
'422': '(((2)+4)*2)',
'424': '(((4)*2)+4)',
'425': '(((5)-2)*4)',
'426': '(((2)+6)+4)',
'428': '(((2)*8)-4)',
'430': '(((0)+4)*3)',
'431': '(((1)*4)*3)',
'435': '(((5)+3)+4)',
'436': '(((6)-3)*4)',
'438': '(((8)-4)*3)',
'439': '(((9)/3)*4)',
'441': '(((4)-1)*4)',
'442': '(((2)*4)+4)',
'444': '(((4)+4)+4)',
'447': '(((7)-4)*4)',
'452': '(((5)-2)*4)',
'453': '(((5)+3)+4)',
'458': '(((8)-5)*4)',
'507': '(((5)+7)+0)',
'512': '(((5)+1)*2)',
'513': '(((5)-1)*3)',
'516': '(((5)+1)+6)',
'517': '(((1)*7)+5)',
'518': '(((5)-1)+8)',
'521': '(((5)+1)*2)',
'522': '(((5)*2)+2)',
'524': '(((5)-2)*4)',
'525': '(((2)+5)+5)',
'529': '(((5)-2)+9)',
'531': '(((5)-1)*3)',
'533': '(((5)*3)-3)',
'534': '(((5)+3)+4)',
'536': '(((5)-3)*6)',
'539': '(((9)-5)*3)',
'542': '(((5)-2)*4)',
'543': '(((5)+3)+4)',
'548': '(((8)-5)*4)',
'552': '(((2)+5)+5)',
'602': '(((2)+0)*6)',
'606': '(((6)+6)+0)',
'611': '(((1)+1)*6)',
'612': '(((6)*1)*2)',
'613': '(((3)-1)*6)',
'615': '(((6)+1)+5)',
'616': '(((1)*6)+6)',
'617': '(((6)+7)-1)',
'620': '(((2)+0)*6)',
'621': '(((6)*1)*2)',
'623': '(((2)*3)+6)',
'624': '(((4)+6)+2)',
'628': '(((6)+8)-2)',
'629': '(((9)*2)-6)',
'631': '(((3)-1)*6)',
'632': '(((2)*3)+6)',
'633': '(((3)+6)+3)',
'634': '(((6)-3)*4)',
'635': '(((5)-3)*6)',
'636': '(((3)*6)-6)',
'639': '(((9)-3)+6)',
'642': '(((2)+6)+4)',
'643': '(((6)-3)*4)',
'646': '(((6)-4)*6)',
'648': '(((6)*8)/4)',
'649': '(((9)-6)*4)',
'651': '(((6)+1)+5)',
'653': '(((5)-3)*6)',
'657': '(((7)-5)*6)',
'705': '(((0)+5)+7)',
'712': '(((7)-1)*2)',
'714': '(((7)+4)+1)',
'715': '(((1)*7)+5)',
'716': '(((6)+7)-1)',
'721': '(((7)-1)*2)',
'722': '(((2)*7)-2)',
'723': '(((2)+3)+7)',
'727': '(((7)+7)-2)',
'732': '(((2)+3)+7)',
'733': '(((7)-3)*3)',
'738': '(((7)-3)+8)',
'739': '(((7)*3)-9)',
'741': '(((7)+4)+1)',
'744': '(((7)-4)*4)',
'749': '(((9)-4)+7)',
'750': '(((0)+5)+7)',
'751': '(((1)*7)+5)',
'756': '(((7)-5)*6)',
'804': '(((8)+4)+0)',
'813': '(((1)+3)+8)',
'814': '(((8)+4)*1)',
'815': '(((5)-1)+8)',
'822': '(((8)+2)+2)',
'823': '(((3)/2)*8)',
'824': '(((2)*8)-4)',
'826': '(((6)+8)-2)',
'828': '(((8)/2)+8)',
'831': '(((1)+3)+8)',
'832': '(((3)/2)*8)',
'834': '(((8)-4)*3)',
'837': '(((7)-3)+8)',
'840': '(((8)+4)+0)',
'841': '(((8)+4)*1)',
'842': '(((2)*8)-4)',
'843': '(((8)-4)*3)',
'845': '(((8)-5)*4)',
'846': '(((6)*8)/4)',
'848': '(((8)-4)+8)',
'851': '(((5)-1)+8)',
'854': '(((8)-5)*4)',
'859': '(((9)+8)-5)',
'903': '(((0)+3)+9)',
'912': '(((9)+1)+2)',
'913': '(((3)+9)*1)',
'914': '(((9)+4)-1)',
'921': '(((9)+1)+2)',
'923': '(((9)-3)*2)',
'925': '(((5)-2)+9)',
'926': '(((9)*2)-6)',
'930': '(((0)+3)+9)',
'931': '(((3)+9)*1)',
'932': '(((9)-3)*2)',
'934': '(((9)/3)*4)',
'935': '(((9)-5)*3)',
'936': '(((9)-3)+6)',
'937': '(((7)*3)-9)',
'939': '(((9)/3)+9)',
'941': '(((9)+4)-1)',
'943': '(((9)/3)*4)',
'946': '(((9)-6)*4)',
'947': '(((9)-4)+7)',
'952': '(((5)-2)+9)',
'953': '(((9)-5)*3)',
'958': '(((9)+8)-5)',
'1016': '((((1)+1)+0)*6)',
'1024': '((((1)+2)+0)*4)',
'1025': '((((5)+0)+1)*2)',
'1026': '((((1)*2)*6)+0)',
'1027': '((((7)+0)-1)*2)',
'1029': '((((1)+9)+0)+2)',
'1033': '((((3)+1)+0)*3)',
'1034': '((((1)*3)*4)+0)',
'1035': '((((5)+0)-1)*3)',
'1036': '((((3)-1)+0)*6)',
'1038': '((((1)+8)+0)+3)',
'1039': '((((0)+9)*1)+3)',
'1042': '((((1)+2)+0)*4)',
'1043': '((((1)*3)*4)+0)',
'1044': '((((4)-1)+0)*4)',
'1047': '((((0)+1)+4)+7)',
'1048': '((((8)*1)+4)+0)',
'1049': '((((4)+0)+9)-1)',
'1052': '((((5)+0)+1)*2)',
'1053': '((((5)+0)-1)*3)',
'1056': '((((6)+0)+5)+1)',
'1057': '((((7)+0)+5)*1)',
'1058': '((((8)+0)+5)-1)',
'1106': '((((1)+1)+0)*6)',
'1114': '((((1)+1)+1)*4)',
'1116': '((((1)+1)*6)*1)',
'1119': '((((9)+1)+1)+1)',
'1123': '((((2)+1)+1)*3)',
'1124': '((((4)+1)+1)*2)',
'1125': '((((2)*5)+1)+1)',
'1126': '((((2)*1)*6)*1)',
'1127': '((((7)-1)*2)*1)',
'1128': '((((2)+1)+1)+8)',
'1129': '((((1)+2)*1)+9)',
'1132': '((((2)+1)+1)*3)',
'1133': '((((1)*1)+3)*3)',
'1134': '((((3)*1)*4)*1)',
'1135': '((((5)-1)*3)*1)',
'1136': '((((1)*3)-1)*6)',
'1137': '((((3)+1)+1)+7)',
'1138': '((((3)+1)+8)*1)',
'1139': '((((9)+3)+1)-1)',
'1141': '((((1)+1)+1)*4)',
'1142': '((((4)+1)+1)*2)',
'1143': '((((3)*1)*4)*1)',
'1144': '((((4)-1)*4)*1)',
'1145': '((((5)-1)-1)*4)',
'1146': '((((1)+4)+1)+6)',
'1147': '((((1)+7)+4)*1)',
'1148': '((((1)+8)+4)-1)',
'1149': '((((4)+9)-1)*1)',
'1152': '((((2)*5)+1)+1)',
'1153': '((((5)-1)*3)*1)',
'1154': '((((5)-1)-1)*4)',
'1155': '((((5)+1)+5)+1)',
'1156': '((((1)+6)+5)*1)',
'1157': '((((7)+1)+5)-1)',
'1158': '((((5)-1)+8)*1)',
'1159': '((((5)-1)+9)-1)',
'1204': '((((1)+2)+0)*4)',
'1205': '((((5)+0)+1)*2)',
'1206': '((((1)*2)*6)+0)',
'1207': '((((7)+0)-1)*2)',
'1209': '((((1)+9)+0)+2)',
'1213': '((((2)+1)+1)*3)',
'1214': '((((4)+1)+1)*2)',
'1215': '((((2)*5)+1)+1)',
'1216': '((((2)*1)*6)*1)',
'1217': '((((7)-1)*2)*1)',
'1218': '((((2)+1)+1)+8)',
'1219': '((((1)+2)*1)+9)',
'1222': '((((1)+2)*2)*2)',
'1223': '((((2)+2)*3)*1)',
'1224': '((((1)+4)*2)+2)',
'1225': '((((2)+5)-1)*2)',
'1226': '((((2)/2)+1)*6)',
'1227': '((((1)+2)+7)+2)',
'1228': '((((2)+1)*8)/2)',
'1229': '((((2)+9)-1)+2)',
'1231': '((((1)+1)*3)*2)',
'1232': '((((2)+2)*3)*1)',
'1233': '((((3)-1)*3)*2)',
'1234': '((((3)+1)*2)+4)',
'1235': '((((2)*5)+3)-1)',
'1236': '((((6)+3)+2)+1)',
'1237': '((((1)*3)+2)+7)',
'1238': '((((2)+3)-1)+8)',
'1239': '((((9)-1)*3)/2)',
'1240': '((((1)+2)+0)*4)',
'1241': '((((4)+1)+1)*2)',
'1242': '((((1)+4)*2)+2)',
'1243': '((((3)+1)*2)+4)',
'1244': '((((2)*4)+4)*1)',
'1245': '((((5)+1)+4)+2)',
'1246': '((((1)*6)+2)+4)',
'1247': '((((4)+2)+7)-1)',
'1248': '((((8)*1)*2)-4)',
'1249': '((((4)-2)+9)+1)',
'1250': '((((5)+0)+1)*2)',
'1251': '((((2)*5)+1)+1)',
'1252': '((((2)+5)-1)*2)',
'1253': '((((2)*5)+3)-1)',
'1254': '((((5)+1)+4)+2)',
'1255': '((((1)*5)+2)+5)',
'1256': '((((5)+2)+6)-1)',
'1257': '((((2)-1)*7)+5)',
'1258': '((((8)+1)-2)+5)',
'1259': '((((2)*9)-5)-1)'}
print(f"So this trick works {len(they_work.keys()) / len(valid) * 100:.2f}% of the time")
So this trick works 45.97% of the time
Well…there ya go
There are a bunch that are easy to spot. Was interesting to see ones where division is used.
[x for x in they_work.values() if '/' in x]
['(((3)/2)*8)',
'(((3)/2)*8)',
'(((9)/3)*4)',
'(((9)/3)*4)',
'(((6)*8)/4)',
'(((3)/2)*8)',
'(((8)/2)+8)',
'(((3)/2)*8)',
'(((6)*8)/4)',
'(((9)/3)*4)',
'(((9)/3)+9)',
'(((9)/3)*4)',
'((((2)/2)+1)*6)',
'((((2)+1)*8)/2)',
'((((9)-1)*3)/2)']
Maybe you’ll give it a try next time you spot a digital clock…
DataFrame of the results
df = pd.DataFrame(valid)
df.rename(columns={0: 'raw'}, inplace=True)
df['raw_temp'] = df['raw'].apply(lambda x: '0' + x if len(x) == 3 else x)
df['time'] = df['raw_temp'].apply(lambda x: pd.to_datetime(x, format='%H%M'))
df.head()
raw | raw_temp | time | twelve | |
---|---|---|---|---|
0 | 100 | 0100 | 1900-01-01 01:00:00 | False |
1 | 101 | 0101 | 1900-01-01 01:01:00 | False |
2 | 102 | 0102 | 1900-01-01 01:02:00 | False |
3 | 103 | 0103 | 1900-01-01 01:03:00 | False |
4 | 104 | 0104 | 1900-01-01 01:04:00 | False |
valid_times = list(they_work.keys())
df['twelve'] = df['raw'].isin(valid_times)
df.head()
raw | raw_temp | time | twelve | |
---|---|---|---|---|
0 | 100 | 0100 | 1900-01-01 01:00:00 | False |
1 | 101 | 0101 | 1900-01-01 01:01:00 | False |
2 | 102 | 0102 | 1900-01-01 01:02:00 | False |
3 | 103 | 0103 | 1900-01-01 01:03:00 | False |
4 | 104 | 0104 | 1900-01-01 01:04:00 | False |
Image Credit
Twelve by Zach Bogart from the Noun Project