A normal tally counter has 4 digits and counts 1 by 1 , hence there are 1 0 0 0 0 different numbers can be shown on it (in range 0 0 0 0 . . . 9 9 9 9 ).
Suppose you have an odd tally counter. Instead 1 by 1 , it counts x by x . In case of overflow, the counter only shows the last 4 digits of the number.
For example, if x = 1 0 0 1 the counter will show these numbers : 0 0 0 0 , 1 0 0 1 , 2 0 0 2 , . . . , 9 0 0 9 , 0 0 1 0 , 1 0 1 1 , . . .
Let F ( n ) be the function returning the number of different numbers can be shown on odd tally counter with x = n , find the last 3 digits of ∑ i = 1 9 9 9 9 F ( i ) .
As an explicit example : F ( 1 ) = 1 0 0 0 0
This problem is taken from TOKI Open Contest January 2013 (Problemsetter : Me)
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.
your solution is amazing! But i'm having a hard time proving F ( n ) = g c d ( n , 1 0 0 0 0 ) 1 0 0 0 0 , can you show me the proof ?
Log in to reply
I'm going to argue that F ( k ) = F ( g cd ( m , k ) ) where we have a clock that's capable of displaying numbers up to m without overflowing. (So in this problem, m = 1 0 4 ).
Now, suppose that m is prime (say 3 for the sake of brevity), then if x = m , the only sequence it can ever generate is the constant sequence 0 , but if we let x be any other number less than m , then after enough cycles, we're going to generate every number between 0 , ⋯ , m − 1 (proof: the sequence { k x m o d m ∣ k ∈ 1 , ⋯ , m − 1 } must be all disjoint because none of k x divides m , and furthermore they must all be less than m and positive; there are exactly m − 1 disjoint positive number less than m , so { k x m o d m ∣ k ∈ 1 , ⋯ , m − 1 } = { 1 , ⋯ , m − 1 } ).
Next, suppose m = p a q b where both p and q are primes, then using the same argument as above, we can see that if x ∣ m , then { k x m o d m ∣ k ∈ 0 , ⋯ , m − 1 } = { 0 , ⋯ , m − 1 } ). Now, suppose that x = γ × p c q d , c < a , d < b , then it can only generate the sequence 0 , γ p c q d , 2 γ p c q d , ⋯ , γ ( p a − c q b − d − 1 ) p c q d , 0 , ⋯ , so it's length is p c q d m . It doesn't take much to also see that p c q d = g cd ( p a q b , γ × p c q d ) , which is why F ( k ) = F ( g cd ( m , k ) ) .
Here is another proof: Because there are finitely many combinations for the last 4 digits, at least one number must repeat. Clearly, once one number repeats, all the numbers after that number repeat. The goal is now to find the first number where they repeat.
Suppose that there were two four-digit numbers (that may start with 0), a and b, that would produce the same next number, c. In other words, a+x ≡ b+x(mod 10000). We subtract x from both sides to get a ≡ b (mod 10000). However, this means that the last 4 digits of a and b are the same. Therefore, a = b because they are both 4 digits long.
Suppose that the first number were not 0000 but some other integer m. Then we take the term before m. Because this is unique, this is the term before m both times that it repeats. This contradicts the assumption that it was the first number that repeats. However, if we take the first term that repeats to be 0000, there is no contradiction because there is no term before 0000 because that is what we started with.
We now must solve x ∗ k ≡ 0 (mod 10000). In other words, we must find the minimum k such that 10000 | x ∗ k . In other words, we want to find the minimum k such that 1 0 0 0 0 ∗ d = x ∗ k for some integer d.
We rewrite x as c ∗ gcd(x, 10000). We now want to find the minimum k such that 10000 ∗ d=k ∗ c ∗ gcd(x, 10000). Because gcd(x, 10000) is a divisor of 10000, we can dividie both sides by gcd(x, 10000) and leave both sides as integers. We now have g c d ( x , 1 0 0 0 0 1 0 0 0 0 ∗ d = k ∗ c . If we divide both sides by c, we get g c d ( x , 1 0 0 0 0 1 0 0 0 0 ∗ c d = k . Therefore, d is a multiple of c. To minimize k, we let d = c. Therefore, g c d ( x , 1 0 0 0 0 1 0 0 0 0 ∗ k = .
Whoa!!Awesome!!!Great Job!!
F ( i ) is really just the number of possible values for [ k i ( m o d 1 0 0 0 0 ) ] for any integer k. Use the fact that the number of values possible for [ k a ( m o d n ) ] is simply ( g cd ( a , n ) n ) . Thus the question becomes ∑ i = 1 9 9 9 9 g cd ( i , 1 0 0 0 0 ) ) 1 0 0 0 0 .
Implemented in python:
from fractions import gcd
answer = sum([ (10000 / gcd(i, 10000)) for i in range(1,10000)])
print answer % 1000 # Prints last three digits => '90'
This may take a while to brute force, so it's worth observing that F ( k ) = F ( g cd ( 1 0 4 , k ) ) therefore, we can compute this problem in O ( n lo g ( n ) + σ ( n ) ) time (where σ ( n ) = Θ ( n lo g lo g n ) counts the divisors of n ) by precomputing the value of F ( d ) for all divisors of n and then summing over F ( g cd ( n , k ) ) (which is bottlenecked in just computing the GCD, which is Θ lo g ( min ( n , k ) = Θ lo g ( k ) , therefore the running time after preprocessing is O ( ∑ k n lo g ( k ) = lo g ( n ! ) ∼ n ( lo g ( n ) − 1 ) ) ).
Furthermore, it turns out that F ( d ) = n / d , which is pretty easy to do, and it makes it so that we don't need to precompute all of the divisors beforehand! Here's the algorithm:
gcd = lambda a,b: a if b is 0 else gcd(b,a%b)
sum([10000/gcd(10000,k) for k in range(1,10000)])
which gave the sum as 5 5 6 6 4 0 9 0
i like that implementation of gcd very much , also i admire people who use lambda and comprehensions :D
Log in to reply
Thanks Abdallah! I tend to like reducing all of my problems into some algebraic problem and go from there! You'll probably love functional programming: the entire paradigm builds upon the formal development of problems as an algebra
Solution in Python:
def F(k):
tally = []
for i in range(1000):
if (k*i)%10000 not in tally:
tally.append((k*i)%10000)
return len(tally)
res = 0
for i in range(1, 10000):
res += F(i)
Nice solution, :)
Indeed, there is also a solution with Number Theory approach to solve this problem (without coding!).
Moreover, this problem has more-evil-version in https://brilliant.org/community-problem/odd-tally-counter/ .
This one is more challenging, because it requires both of Number Theory and Computer Science technique. Good luck! :D
Log in to reply
There may still be some work to be done in the ranking system but it is interesting to note that this problem has a higher rating than the harder version.
Woop, typo : https://brilliant.org/community-problem/odd-long-tally-counter , enjoy!
Log in to reply
Could you erase the "!" in the end? I thought it was a factorial
Log in to reply
@Mario Ynocente Castro – I really want to, but I can't edit the problems myself at this time, :(
I have notified the staffs, and they will edit it, sorry for your inconvenience and a big thanks to clarify!
Trying hard to solve the more evil version of this problem. Could you give a hint on how to use number theory?
Log in to reply
Hint : You have to find the simpler formula of F ( n ) which its complexity is close to O ( 1 ) . Happy solving!
Log in to reply
@Ammar Fathin Sabili – lol, I did it.... I am so happy right now!
@Ammar Fathin Sabili – =MOD(14(4^k-1)+500(k-1)+20,1000) for tally counter with k digits
=090 for k=4
I used This code : """def four(x) : a = str(x) if len(a) > 4 : b = "" for i in range(4): b += a[i] b = int(b) return b else : return x
def od(x) : c = 0 b = [0] d = 0 for i in range(9999) : d += x d = four(d)
e = 0
for i in b :
if d == i :
e += 1
if e == 0 :
b.append(d)
f = len(b)
return f
n = 0 for i in range (1 ,10000) : n += od(i) print n""" tell me what is wrong
may i give u a little advice , not related to this particular problem , but consider each time you call the line " ( k*i) %10000 not in tally" all the list is searched to look for the item your looking for . the cost of searching in lists is O(n) . while if you simply changed tally from a list to a set you will gain a lot, because the cost of the search in sets is O (1) .
though this won't be noticeable in this small data set.
I used a dict instead of a list as being a hash table it helps to pick out the elements in constant time...
My solution is slightly longer than y'all's fancy gcd algorithms, BUT it may well be faster...
1 2 3 4 5 6 7 8 9 10 |
|
Output:
1 |
|
And then for the purely mathematical solution:
If the tally counter can count N values, with prime factor decomposition N = p 1 e 1 ⋅ p 2 e 2 ⋯ , then i = 1 ∑ N F ( i ) = k ∏ ( p k + 1 p k ( p k 2 e k − 1 ) + 1 ) . (Challenge for all of you: prove this!)
In this case, N = 1 0 0 0 0 = 2 4 ⋅ 5 4 , and the answer is i = 1 ∑ 9 9 9 9 F ( i ) = ( 2 + 1 2 ⋅ ( 2 2 ⋅ 4 − 1 ) + 1 ) ( 5 + 1 5 ⋅ ( 5 2 ⋅ 4 − 1 ) + 1 ) − 1 = 1 7 1 ⋅ 3 2 5 5 2 1 − 1 = 5 5 6 6 4 0 9 0 .
So 090 is wrong? but 90 is correct? how is 90 the last three digits? 90 is two digits. Both should be right, an otherwise 090 should be the only correct answer.
As simple as:
#include <iostream>
#include <conio.h>
using namespace std;
int main() {
int a=0;
int mc = 0;
for(int i = 1; i <= 9999; i++) {
int first = i;
a = i;
int count = 1;
while( a != 0 ) {
a += i;
a = a%10000;
count++;
count = count%1000;
}
mc += count;
mc %= 1000;
}
cout << mc;
getch();
}
Mathematica code:
Sum[Length[DeleteDuplicates[Table[FromDigits[Last[Substes[IntegerDigits[10000+n*x],{4}]]],{x,1,10000}]]],{n,1 9999}]
Solution is based on the following observations:
so the following program does the calculation:
#include <iostream>
int gcd(int a, int b){
if (b == 0) return a;
else return gcd(b, a % b);
}
int main(int argc, char** argv) {
int sum=0, i;
for(i=1;i<5000;i++){
sum += 2 * 10000 / gcd(i, 10000);
}
sum += 10000 / gcd(i, 10000); //for the middle 5000
printf("sum=%d", sum);
return 0;
}
The output is:
sum=55664090
and thus the answer is 0 9 0
In Ruby:
(1..9999).inject(0){|s,i|s+=10000/10000.gcd(i)}
First thing we need to notice is that the tally will eventually loop back to 0. Once this happens we know that we have exhausted the distinct possibilities for the tally. Thus we can simply continuously increment some variable by x until we reach 0, and the number of times we increment it is F(x). The rest is simple implementation:
public class Brilliant3{
public static int tally(int n){
int ret=1;
int blah=n;
while(blah!=0){
ret++;
blah+=n;
blah=blah%10000;}
return ret;}
public static void main(String[] args){
int ans=0;
for(int i=1; i<=9999; i++){
/*if(i<10){System.out.print(tally(i)+" ");}*/
ans+=tally(i);}
System.out.println(ans);
}
}
nicely named variables
int main() {
int i,remainder,counter,sum;
i=1;
sum=0;
while(i<10000)
{
counter=0;
remainder=1;
while(remainder!=0)
{
remainder=((counter+1)*i)%10000;
counter++;
}
sum+=counter;
i++;
}
printf("The sum is %d\n",sum);
return EXIT_SUCCESS;
}
The overflow means we are effectively taking the numbers ( mod 1 0 0 0 0 ) . Note that if we count up 1 0 0 0 0 times, we have effectively added a multiple of 1 0 0 0 0 to our counter, hence we only need to consider the results from adding x the first 9 9 9 9 times. Now, there are 9 9 9 9 values of i and 1 0 0 0 0 additions of x to test for each i , therefore there are less than one hundred million counter tallies in total, which is easy to brute force using modern computers.
Hence we can use this Python 3.3.0 code (parts of a line after a "#" are comments):
total = 0
for i in range(1, 9999+1):
shown = set()# Create a set of counter values for this value of i.
for k in range(0, 10000):
shown.add((k*i)%10000)#Use this as an alternative to repeatedly addding i.
total += len(shown)# len(shown) is F(i)
print(total%1000)# Only want the last three digits.
Running this code gives the answer of 9 0 .
for(addBy = 1 ; addBy <= 9999 ; addBy++ )
{
/* Clean the slate */
for(i=0;i<=9999 ;i++)
isFilled[i]= 0;
for (j=0 ;j<=9999 ;j++)
{
nextNumber = nextNumber + addBy ;
while(nextNumber >9999)
{
nextNumber = nextNumber -10000 ;
}
/* fill the slate */
isFilled[nextNumber] = 1;
}
/* count the number of filled numbers for one addBy */
for(k=0 ; k<=9999 ;k++)
{
if(isFilled[k]== 1 ) tallyCount ++;
}
printf("Sum for addBy=%d = %d \n" ,addBy, tallyCount);
totalTallyCount = totalTallyCount + tallyCount;
tallyCount = 0;
}
printf("Sum = %d" , totalTallyCount);
return 0;
}
Yes the answer is 090!
Problem Loading...
Note Loading...
Set Loading...
It can be shown that F ( n ) = g c d ( n , 1 0 0 0 0 ) 1 0 0 0 0 The gcd, or greatest common denominator can be implemented easily using the Euclidean algorithm. Simply sum F(i) from 1 to 9999, while remembering to modulo 1000 at every step.