When Jack was born, his parents listed down 1000 distinct times from 0 to 1000000, in hours since birth, and they also gathered 1000 timers.
When each specified hour on the list of times passed, Jack started a timer. Each timer starts at 0 and counts up 1 hour for every hour that passes. However, many of the timers are defective, and remain at 0 no matter how many hours pass.
For the purposes of this question, "current time" refers to the number of hours since Jack's birth. Jack wants to find the current time. Unfortunately, he forgot to associate each timer with a time. Given the initial list of 1000 times his parents created and the 1000 times on the timers, find the last three digits of the current time.
Sample input (with only 4 times)
2
3
5
9
0
1
0
4
Input explanation
The list of times is [ 2 , 3 , 5 , 9 ] . The list of timer times is [ 0 , 1 , 0 , 4 ] .
Answer and explanation
The current time is 6 . The 1 must be associated with the 5 , and the 4 with the 2 . One timer showing 0 hasn't been started yet, and the other timer showing 0 is associated with 3 , but is defective. Any other current time would not match up with the times on the timers.
Note that the actual input has 1000 times and 1000 timer times.
Details and assumptions
You may find the required numbers here . The first 1000 lines is the list of times, in numerical order, and the next 1000 lines are the times on the timers, in no particular order.
You may assume the current time is uniquely determined by the time on the timers.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
Minor typo: It should be:
For all 2 ≤ i ≤ k c i = c 1 + b 1 − b i
The current time will be the sum of timer corresponding to its written time. The current time can't be found explicitly. So, we take one of the many values of timer and add it with all the values of written times. One of these sums will be the current time. Then we take another element and add it will all the values of written times. We, compare this list of sums with previous list and see if any sum is common. We do this till we find one sum which is common with all such list and that would be the current time.
I have done the above thing down below using the Python lang. It's not very clear and done in very unprofessional way but still, here it is:
data = open('tricky_timers.txt', 'r') # Opening the file
allLines = [num.rstrip() for num in data] # making a list of given numbers
allLines = map(int, allLines) # convert each str to int in list of numbers
times = [] # this will store the random times from 0 to 1000
for i in range(1000):
times.append(allLines[i])
validTimers = [] # this will store the value of timers which aren't defective
for i in range(1000, 2000):
if allLines[i] != 0:
validTimers.append(allLines[i])
# temp1 to temp4 will store sum of first four element of validTimers with all times
temp1 = []
temp2 = []
temp3 = []
temp4 = []
for a in times:
temp1.append(a + validTimers[0])
for a in times:
temp2.append(a + validTimers[1])
for a in times:
temp3.append(a + validTimers[2])
for a in times:
temp4.append(a + validTimers[3])
commonSum = [] # this will store the elements which are common in all temp's
for i in temp1:
if i in temp2 and i in temp3 and i in temp4:
commonSum.append(i)
print commonSum
While your algorithm does seem to find the answer in this particular situation. It is still not correct. Take an instance when,
times = [1,2,3,5,7,9,11,13]
timers = [7,0,5,3,1,0,10,0]
It will give an answer of 8, but the real answer is 12. Maybe, the example is not right, but you get the idea, right? Or am I missing something here?
The way I approach this problem
Log in to reply
times = [1,2,3,5,7,9,11,13]
timers = [7,0,5,3,1,0,10,0]
So, valid times would be [7, 5, 3, 1, 10].
temp1 = 7 + all elements of times = [8, 9, 10, 12, 14, 16, 18, 20]
temp2 = 5 + all elements of times = [6, 7, 8, 10, 12, 14, 16, 18]
temp3 = 3 + all elements of times = [4, 5, 6, 8, 10, 12, 14, 16]
temp4 = 1 + all elements of times = [2, 3, 4, 6, 8, 10, 12, 14]
temp5 = 10 + all elements of times = [11, 12, 13, 15, 17, 19, 21, 23]
Only, 12 is common among all the sums. 12 is the common element in all the temps, so the algorithm works here too. You are missing something I guess.
Log in to reply
But there was no temp5 in the solution posted. You can dynamically create more arrays. But that would be terrible. Imagine the amount of memory it would consume if there were a million numbers there.
Log in to reply
@Uneeb Agha – Umm yeah, that's a drawback I agree.
EDIT: The current time will be the sum of timer with its corresponding written time. The current time can't be found explicitly. So, we take one of the many values of timer and add it with all the values of written times separately.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Collections;
public class TrickyTimers { static int parentTimes[], timers[]; public static void main(String args[]) throws IOException { InputStreamReader read = new InputStreamReader(System.in); BufferedReader in = new BufferedReader(read); parentTimes = new int[1000];
for(int i=0;i<1000;i++) {
parentTimes[i] = Integer.parseInt(in.readLine());
}
int tmp[] = new int[1000];
int count = 0;
for(int i=0;i<1000;i++) {
int a = Integer.parseInt(in.readLine());
if(a!=0) count++;
tmp[i] = a;
}
timers = new int[count];
int j=0;
for(int i=0;i<1000;i++) {
if(tmp[i]!=0) {
timers[j++] = tmp[i];
}
}
Arrays.sort(timers);
//System.out.println(timers[0] + " " + timers[count-1]);
for (int i = 0; i < timers.length / 2; i++) {
int temp = timers[i];
timers[i] = timers[timers.length - 1 - i];
timers[timers.length - 1 - i] = temp;
}
//System.out.println(timers[0] + " " + timers[count-1]);
for(int k=0;k<1000;k++) {
int total = timers[0] + parentTimes[k];
int i;
for(i=1,j=k+1;;) {
if(i == count) {
System.out.println(total);
break;
}
if(i>count || j >=1000) break;
int sum = timers[i] + parentTimes[j];
if(sum == total) {
i++;
j++;
}
else if(sum > total) {
break;
}
else {
j++;
}
}
}
}
}
Nice Problem!Obviously the sum of any time listed by Jacks Parents and any timer time must add up to the current time.This is of course unless the timer is defective. So I just ignored all 0 timer times and found unique sums that sum up to the current time and checked if they fit.
I first check all possible times using the sum of the timers and list of times.I then associate each possible time with the timer times that can sum up to it.I do this by putting the timer times for that possible answer in a list. If at the end,this list is exactly the same as the given timer times then that possible time is our answer.The algorithm is O ( t i m e r × t i m e s )
Code in python:
with open('tricky_timers.txt','r') as tt:
All = map(int,tt.read().split('\n'))
Times , Timers = All[0:len(All)/2] , All[len(All)/2::]
Lookup = sorted(list(set(Timers)))[1::]
Dict = dict()
for time in Times:
for timer in Timers:
if timer == 0:continue
Possible_Time = time + timer
try:
Dict[Possible_Time].append(timer)
Dict[Possible_Time].sort()
except KeyError:
Dict[Possible_Time] = [timer]
for i in Dict:
if Dict[i] == Lookup:
print i
For the sake of shortness, I'm skipping the gory details of handling the input data. Let's assume we have a list
timers
which stores the
2
0
0
0
integers provided in the question. We split it into two parts:
original
and
dummy
, where
original
stores the first
1
0
0
0
integers and
dummy
stores the last
1
0
0
0
integers.
original= timers[:1000]
dummy= timers[-1000:]
We make another list,
another
, which stores the non-zero values of
dummy
.
another = [i for i in dummy if i != 0]
Here comes the crucial step. Note that the largest element of
original
which doesn't get assigned to a faulty timer must be associated with the smallest element of
another
. However, since we don't know which element gets assigned to a faulty timer, we keep on checking with the largest element of
original
. To be precise, we define
L= max(original)
,
K= min(another)
, and
n= K+L
. A system will be valid if and only if
∀
x
∈
another
,
n
−
x
∈
original
. We now declare a loop, which runs
1
0
0
0
times. Each time it runs, it checks whether the system is valid assuming the largest element of
original
is paired with the smallest element of
another
. The Boolean
val
is
True
if the system is valid, and
False
otherwise. The list
listofvalues
stores the values of
val
at each step. Once a check is complete, the largest element of
original
gets appended to the list
listofnumbers
, and then removed from
original
, and the loop runs again.
K= min(another)
listofvalues= []
listofnumbers= []
for k in range(1000):
L= max(original)
n= K+L
val= True
for x in range(len(another)):
if n-another[x] not in original:
val= False
listofvalues.append(val)
listofnumbers.append(L)
original.remove(L)
k+=1
Now, note that the time will be unique iff there is exactly one
True
stored in
listofvalues
. We iterate over this list to find out how many
True
values it has. If it has exactly
1
True
, we iterate over
listofnumbers
to find out the corresponding time on the original timers, and add it to the minimum value stored in
another
.
if listofvalues.count(True)==1:
for i in range(len(listofvalues)):
if listofvalues[i]==True:
print listofnumbers[i]+K
else:
print "https://i.imgur.com/QFyLFRR.jpg"
This prints 7 9 0 4 8 0 , whose last three digits are 4 8 0 .
The following algorithm check the matching conditions counting on the sorted lists of times and timers (reversed order):
#include <iostream>
#include <stdlib.h>
void quickSort(int *v, int first, int last) {
int start[2], end[2], pivot, i;
int temp;
if (first < last) {
start[1] = first;
end[0] = last;
pivot = v[(first + last) / 2];
while (start[1] <= end[0]) {
while (v[start[1]] > pivot)
start[1]++;
while (pivot > v[end[0]])
end[0]--;
if (start[1] <= end[0]) {
temp = v[start[1]];
v[start[1]] = v[end[0]];
v[end[0]] = temp;
start[1]++;
end[0]--;
}
}
start[0] = first;
end[1] = last;
quickSort(v, start[0], end[0]);
quickSort(v, start[1], end[1]);
}
}
int main(int argc, char** argv) {
int times[1000];
int timers[1000];
char s[20]; int i=0;
FILE* f = fopen("input.txt", "r");
while(fgets(s, sizeof(s)-1, f)){
if (i<1000){
times[i] = atoi(s);
} else {
timers[i%1000] = atoi(s);
}
i++;
}
fclose(f);
quickSort(timers, 0, 999);
i=0;
int tot, j=0, k, p;
while(i<1000){
tot = times[i] + timers[j];
printf("\ncurrent total=%d composed by times[%d]=%d and timers[%d]=%d", tot, i, times[i], j, timers[j]);
k=i+1; p=j+1;
while(timers[p] != 0 && p<1000){
while(k<1000 && (times[k] + timers[p] <= tot)) k++;
if (times[k-1] + timers[p] == tot){
printf("\ntimes[%d]=%d + timers[%d]=%d = %d", k-1, times[k-1], p, timers[p], tot);
p++;
} else {
printf("\ntimes[%d]=%d + timers[%d]=%d = %d <> %d ", k-1, times[k-1], p, timers[p], times[k-1] + timers[p], tot) ;
break;
}
}
if (timers[p]==0) {
printf("\nsolution found.");
break;
}
i++;j=0;
}
printf("\ntotal=%d", tot);
return 0;
}
The output:
current total=783378 composed by times[0]=1367 and timers[0]=782011
times[6]=7441 + timers[1]=775131 = 782572 <> 783378
current total=784842 composed by times[1]=2831 and timers[0]=782011
times[7]=8469 + timers[1]=775131 = 783600 <> 784842
current total=786143 composed by times[2]=4132 and timers[0]=782011
times[10]=10970 + timers[1]=775131 = 786101 <> 786143
current total=787368 composed by times[3]=5357 and timers[0]=782011
times[10]=10970 + timers[1]=775131 = 786101 <> 787368
current total=787876 composed by times[4]=5865 and timers[0]=782011
times[11]=12604 + timers[1]=775131 = 787735 <> 787876
current total=788000 composed by times[5]=5989 and timers[0]=782011
times[11]=12604 + timers[1]=775131 = 787735 <> 788000
current total=789452 composed by times[6]=7441 and timers[0]=782011
times[13]=13671 + timers[1]=775131 = 788802 <> 789452
current total=790480 composed by times[7]=8469 and timers[0]=782011
times[16]=15349 + timers[1]=775131 = 790480
times[23]=20607 + timers[2]=769873 = 790480
times[31]=28711 + timers[3]=761769 = 790480
times[40]=40472 + timers[4]=750008 = 790480
times[46]=53255 + timers[5]=737225 = 790480
times[58]=65250 + timers[6]=725230 = 790480
times[78]=85723 + timers[7]=704757 = 790480
times[93]=99580 + timers[8]=690900 = 790480
times[112]=118557 + timers[9]=671923 = 790480
times[129]=134684 + timers[10]=655796 = 790480
times[136]=139021 + timers[11]=651459 = 790480
times[150]=154298 + timers[12]=636182 = 790480
times[168]=174492 + timers[13]=615988 = 790480
times[183]=186825 + timers[14]=603655 = 790480
times[194]=200591 + timers[15]=589889 = 790480
times[206]=218622 + timers[16]=571858 = 790480
times[216]=224459 + timers[17]=566021 = 790480
times[236]=244402 + timers[18]=546078 = 790480
times[251]=264868 + timers[19]=525612 = 790480
times[257]=269763 + timers[20]=520717 = 790480
times[268]=276302 + timers[21]=514178 = 790480
times[287]=294996 + timers[22]=495484 = 790480
times[301]=309580 + timers[23]=480900 = 790480
times[311]=315626 + timers[24]=474854 = 790480
times[316]=321841 + timers[25]=468639 = 790480
times[328]=332087 + timers[26]=458393 = 790480
solution found.
total=790480
BTW, forgot to mention that 790480 hours since birthday means Jack is now ~ 90 years old :) !!!
Problem Loading...
Note Loading...
Set Loading...
We basically just need the information of the non-zero timers. Since 0 timers that are defective are indistinguishable from 0 timers that have not been yet activated, then they can't give any information about the current hour.
Let A = { a 1 , a 2 , . . . , a 1 0 0 0 } the set of activation times, and B = { b 1 , b 2 , . . . , b k } the set of non-zero timers, and C = { c 1 , c 2 , . . . , c k } , the activation times that each timer b i is matched to. Obviously C ⊂ A . WLOG, B is ordered in the following way: b 1 ≥ b 2 ≥ . . . ≥ b k
Now, since every clock counts the time at the same speed, and Activation time + Timer’s time = Current Time , we must have that b 1 + c 1 = b 2 + c 2 = . . . = b k + c k .
With those equalities we can see that for all 2 ≤ i ≤ k c k = c 1 + b 1 − b k
Since, c 1 is one of the activation times, we can choose some element of A and assume it is c 1 , and then construct the rest of C with the chosen c 1 and the above equality. We can then check if C ⊂ A , to see if it's a valid choice of c 1 . The first time that happens, we found a correct match, and we can just output b 1 + c 1 as the current time, since we can assume the current time can be uniquely determined.
Of course, we can check the subset and construct C at the same time as a minor optimization.
Here is my Python 3 code: