Im trying to code a personal identificational number which should have 10 numbers. It looks like this 990830/4197.
First two numbers - year - 1999 he was born
Second two numbers - month - august
Third two numbers - day 3O.8
Last 4 numbers are generated that way so the whole number when you take it has to be devided by 11 and there cant remain any number. So for example;
99+8+30+4197= 4 334 /11 = 394.
Always the number should be % = 0.
I wanna ask for some key words that might help me when I wanna generate correct numbers.
Thanks
I am assuming here that the date part of the number you have already. Then you can use this code to calculate the "tail" efficiently:
from random import randint
date = 990830
s = sum(int(x) * 10**(i % 2) for i, x in enumerate(str(date), 1)) # note 1
tail = randint(90, 908) * 11 - (s % 11) # note 2
print('{}\{}'.format(date, tail))
which produces (several examples):
990830\5462
990830\5132
990830\8751
990830\6397
with all of them being perfectly divisible by 11.
This simply adds the numbers of the date as described (e.g., 99 + 08 + 30)
This calculates a random 4 digit number that when added to the above sum creates a number N for which N % 11 == 0.
Related
I need to find x from the below equation
h = pow(g,x,p)
I have the values of
h = 400 digit number
g = 400 digit number
p = 400 digit number
I need to find the value of x.
All the values are very big.
I have incomplete x with 10 missing digits in it and they are not continuous missing digits.Index of all the missing digits is different.
I am using 10 for loops
to replace that value every time to get H.It is taking too much time in python to do that.Is there anyway in which I can do it faster.
Don't call pow() ten billion times. Instead, use it to calculate the first value of h, and then calculate each successive value by multiplying the previous value by g (or g raised to the appropriate power of 10 in the case where the missing digits are not at the end of x).
Here's a worked example that finds 7 missing digits in just a few seconds. It should give an answer for ten missing digits in a few hours. But as others have noted, you will get better performance by porting this code to another language like C.
h = 27029080272084173153635398406622455117429159185281491773519587480106092289627
g = 26376362132555166607008315364046996472951702119314003469217622667073785183917
p = 81593331324697655999776287731387256090095437693547587289127550085992860325943
x = 31952256647378403805884540140134925446045889939629675712565170000000381638216
# The missing digits (3897858): ^^^^^^^
z = pow(g, x, p) # Initial value of h
d = pow(g, 10**9, p) # Multiplier to get next value of h
while z != h:
z = (z * d) % p
x += 10**9 # Increment x at position of last unknown digit
print(x)
EDIT:
If the missing digits are not consecutive, then you can still use a similar approach, but instead of incrementing x by the same amount each time, you'll need to keep tabs on which digits are changing at each step. For example given a number .0.....0...0.., where 0 represents a missing digit and . represents a known digit, you'll need to add 100 when incrementing the last unknown digit, 9999100 when the last unknown digit has reached 9, and 999990999100 when the last two unknown digits are both 9. It shouldn't be too hard to figure out the correct increments for any pattern of unknown digits.
.0.....0...0.. + 100
.0.....0...1.. + 100
.0.....0...2.. + 100
: : :
.0.....0...8.. + 100
.0.....0...9.. + 9999100
.0.....1...0.. + 100
.0.....1...1.. + 100
: : :
.0.....1...9.. + 9999100
.0.....2...0.. + 100
: : :
.0.....9...9.. + 999990999100
.1.....0...0.. + 100
: : :
This should run in a feasible amount of time with 10 unknown digits, but for a much faster solution, use the meet-in-the-middle approach suggested by James K Polk in the comments below.
Given two numbers a and b, we have to find the nth number which is divisible by a or b.
The format looks like below:
Input :
First line consists of an integer T, denoting the number of test cases.
Second line contains three integers a, b and N
Output :
For each test case, print the Nth
number in a new line.
Constraints :
1≤t≤105
1≤a,b≤104
1≤N≤10
Sample Input
1
2 3 10
Sample Output
15
Explanation
The numbers which are divisible by 2
or 3 are: 2,3,4,6,8,9,10,12,14,15 and the 10th number is 15
My code
test_case=input()
if int(test_case)<=100000 and int(test_case)>=1:
for p in range(int(test_case)):
count=1
j=1
inp=list(map(int,input().strip('').split()))
if inp[0]<=10000 and inp[0]>=1 and inp[1]<=10000 and inp[1]>=1 and inp[1]<=1000000000 and inp[1]>=1:
while(True ):
if count<=inp[2] :
k=j
if j%inp[0]==0 or j%inp[1] ==0:
count=count+1
j=j+1
else :
j=j+1
else:
break
print(k)
else:
break
Problem Statement:
For single test case input 2000 3000 100000 it is taking more than one second to complete.I want if i can get the results in less than 1 second. Is there a time efficient approach to this problem,may be if we can use some data structure and algorithms here??
For every two numbers there will be number k such that k=a*b. There will only be so many multiples of a and b under k. This set can be created like so:
s = set(a*1, b*1, ... a*(b-1), b*(a-1), a*b)
Say we take the values a=2, b=3 then s = (2,3,4,6). These are the possible values of c:
[1 - 4] => (2,3,4,6)
[5 - 8] => 6 + (2,3,4,6)
[9 - 12] => 6*2 + (2,3,4,6)
...
Notice that the values repeat with a predictable pattern. To get the row you can take the value of c and divide by length of the set s (call it n). The set index is the mod of c by n. Subtract 1 for 1 indexing used in the problem.
row = floor((c-1)/n)
column = `(c-1) % n`
result = (a*b)*row + s(column)
Python impl:
a = 2000
b = 3000
c = 100000
s = list(set([a*i for i in range(1, b+1)] + [b*i for i in range(1, a+1)]))
print((((c-1)//len(s)) * (a*b)) + s[(c - 1)%len(s)])
I'm not certain to grasp exactly what you're trying to accomplish. But if I get it right, isn't the answer simply b*(N/2)? since you are listing the multiples of both numbers the Nth will always be the second you list times N/2.
In your initial example that would be 3*10/2=15.
In the code example, it would be 3000*100000/2=150'000'000
Update:
Code to compute the desired values using set's and lists to speed up the calculation process. I'm still wondering what the recurrence for the odd indexes could be if anyone happens to stumble upon it...
a = 2000
b = 3000
c = 100000
a_list = [a*x for x in range(1, c)]
b_list = [b*x for x in range(1, c)]
nums = set(a_list)
nums.update(b_list)
nums = sorted(nums)
print(nums[c-1])
This code runs in 0.14s on my laptop. Which is significantly below the requested threshold. Nonetheless, this values will depend on the machine the code is run on.
I have been working on a past Google Codejam algorithm from 2010, but the time complexity is awful.
Here is the question from Google Codejam: https://code.google.com/codejam/contest/619102/dashboard
TLDR - Imagine two towers that have a number line running up the sides, we draw a line from one buildings number line (say from 10) to another point on the other buildings number line (say from 1). If we do this n times, how many times will those lines intersect?
I was wondering if anyone here is able to suggest a way in which I can speed up my algorithm? After 4 hours I really can't see one and I'm losing my miinnnnddd.
Here is my code as of right now.
An example input would be:
2 - (Number of cases)
3 - (Number of wires in case # 1)
1 10
5 5
7 7
Case #1: 2 - (2 intersections among lines 1,10 5,5 7,7)
2 - (Number of wires in case #2)
5 5
2 2
Case #2: 0 - (No lines intersect)
def solve(wire_ints, test_case):
answer_integer = 0
for iterI in range(number_wires):
for iterJ in range(iterI):
holder = [wire_ints[iterI], wire_ints[iterJ]]
holder.sort()
if holder[0][1] > holder[1][1]:
answer_integer = answer_integer + 1
return("Case #" + str(test_case) + ":" + " " + str(answer_integer))
for test_case in range(1, int(input()) + 1):
number_wires = int(input())
wire_ints = []
for count1 in range(number_wires):
left_port,right_port = map(int, input().split())
wire_ints.append((left_port,right_port))
answer_string = solve(wire_ints, test_case)
print(answer_string)
This algorithm does WORK for any input I give it, but as I said its very ugly and slow.
Help would be appreciated!
Since N is 1000 an algorithm with O(N^2) would be acceptable. So what you have to do is sort the wires by one of their end points.
//sorted by first number
1 10
5 5
7 7
Then you process each line from the beginning and check whether it has intersection with lines before it. If the second end point of a line before it is bigger than the second point of current line they have intersection. This requires two loops thus the O(N^2) complexity which suffice for N=1000. Also you can interpret this as an inversion count. you have to count the number of inversions of the second end points where the list is sorted by first end point.
10 5 7 -> number of inversions is 2, because of (10,5) and (10,7)
Also there is O(NlogN) approach to count the number of inversions which you don't need for this question.
This question already has answers here:
How to make rounded percentages add up to 100%
(23 answers)
Closed 8 years ago.
I know how to round a number in Python, this is not a simple technical issue.
My issue is that rounding will make a set of percentages not adding up to 100%, when, technically, they should.
For example:
a = 1
b = 14
I want to compute the percentage of a in (a + b) and b in (a + b).
The answer should be
a/(a + b) = 1/15
b/(a + b) = 14/15
When I try to round those numbers, I got
1/15 = 6.66
14/15 = 93.33
(I was doing the flooring), which makes those two number doesn't add up to 100%.
In this case, we should do ceiling for 1/15, which is 6.67, and flooring for 14/15, which is 93.33. And now they add up to 100%. The rule in this case should be "rounding to the nearest number"
However, if we have a more complicate case, say 3 numbers:
a = 1
b = 7
c = 7
flooring:
1/15 = 6.66
7/15 = 46.66
7/15 = 46.66
Doesn't add up to 100%.
ceiling:
1/15 = 6.67
7/15 = 46.67
7/15 = 46.67
doesn't add up to 100%.
Rounding (to nearest number) is same as ceiling. Still doesn't add up to 100%.
So my question is what should I do to make sure they all add up to 100% in any cases.
Thanks in advance.
UPDATE:
Thanks for the tips from comments. I have took the "Largest Remainder" solution from the duplicate Post answer.
The code are:
def round_to_100_percent(number_set, digit_after_decimal=2):
"""
This function take a list of number and return a list of percentage, which represents the portion of each number in sum of all numbers
Moreover, those percentages are adding up to 100%!!!
Notice: the algorithm we are using here is 'Largest Remainder'
The down-side is that the results won't be accurate, but they are never accurate anyway:)
"""
unround_numbers = [x / float(sum(number_set)) * 100 * 10 ** digit_after_decimal for x in number_set]
decimal_part_with_index = sorted([(index, unround_numbers[index] % 1) for index in range(len(unround_numbers))], key=lambda y: y[1], reverse=True)
remainder = 100 * 10 ** digit_after_decimal - sum([int(x) for x in unround_numbers])
index = 0
while remainder > 0:
unround_numbers[decimal_part_with_index[index][0]] += 1
remainder -= 1
index = (index + 1) % len(number_set)
return [int(x) / float(10 ** digit_after_decimal) for x in unround_numbers]
Tested, seems work fine.
As others have commented, if your numbers are nice and round as in your example, you can use the fractions module to retain the accuracy of the rational numbers:
In [2]: from fractions import Fraction
In [5]: a = Fraction(1)
In [6]: b = Fraction(14)
In [7]: a/(a+b)
Out[7]: Fraction(1, 15)
In [8]: a/(a+b) + (b/(a+b))
Out[8]: Fraction(1, 1)
This obviously doesn't look good if you have really odd fractions.
Welcome to IEEE Floats.
The floating point numbers returned from math operations in python are approximates. On some values, the sum of percentages will be greater than 100.
You have two solutions: use the fraction or decimal modules OR, simply not want them to add up to 100%.
This is the problem:
How many integers 0 ≤ n < 10^18 have the property that the sum of the digits of n equals the sum of digits of 137n?
This solution is grossly inefficient. What am I missing?
#!/usr/bin/env python
#coding: utf-8
import time
from timestrings import *
start = time.clock()
maxpower = 18
count = 0
for i in range(0, 10 ** maxpower - 1):
if i % 9 == 0:
result1 = list(str(i))
result2 = list(str(137 * i))
sum1 = 0
for j in result1:
sum1 += int(j)
sum2 = 0
for j in result2:
sum2 += int(j)
if sum1 == sum2:
print (i, sum1)
count += 1
finish = time.clock()
print ("Project Euler, Project 290")
print ()
print ("Answer:", count)
print ("Time:", stringifytime(finish - start))
First of all, you are to count, not to show the hits.
That is very important. All you have to do is to device an efficient way to count it. Like Jon Bentley wrote in Programming Pearls: "Any methond that considers all permutations of letters for a word is doomed to failure". In fact, I tried in python, as soon as "i" hit 10^9, the system already freezed. 1.5 G memory was consumed. Let alone 10^18. And this also tells us, cite Bentley again, "Defining the problem was about ninety percent of this battle."
And to solve this problem, I can't see a way without dynamic programming (dp). In fact, most of those ridiculously huge Euler problems all require some sort of dp. The theory of dp itself is rather academic and dry, but to implement the idea of dp to solve real problems is not, in fact, the practice is fun and colorful.
One solution to the problem is, we go from 0-9 then 10-99 then 100-999 and so on and extract the signatures of the numbers, summarize numbers with the same signature and deal with all of them as a piece, thus save space and time.
Observation:
3 * 137 = 411 and 13 * 137 = 1781. Let's break the the first result "411" down into two parts: the first two digits "41" and the last digit "1". The "1" is staying, but the "41" part is going to be "carried" to further calculations. Let's call "41" the carry, the first element of the signature. The "1" will stay as the rightest digit as we go on calculating 13 * 137, 23 * 137, 33 * 137 or 43 * 137. All these *3 numbers have a "3" as their rightest digit and the last digit of 137*n is always 1. That is, the difference between this "3" and "1" is +2, call this +2 the "diff" as the second element of the signature.
OK, if we are gonna find a two-digit number with 3 as its last digit, we have to find a digit "m" that satisfies
diff_of_digitsum (m, 137*m+carry) = -2 (1)
to neutralize our +2 diff accumulated earlier. If m could do that, then you know m * 10 + 3, on the paper you write: "m3", is a hit.
For example, in our case we tried digit 1. diff_of_digitsum (digit, 137*digit+carry) = diff_of_digitsum (1, 137*1+41) = -15. Which is not -2, so 13 is not a hit.
Let's see 99. 9 * 137 = 1233. The "diff" is 9 - 3 = +6. "Carry" is 123. In the second iteration when we try to add a digit 9 to 9 and make it 99, we have diff_of_digitsum (digit, 137*digit+carry) = diff_of_digitsum (9, 137*9+123) = diff_of_digitsum (9, 1356) = -6 and it neutralizes our surplus 6. So 99 is a hit!
In code, we just need 18 iteration. In the first round, we deal with the single digit numbers, 2nd round the 2-digit numbers, then 3-digit ... until we get to 18-digit numbers. Make a table before the iterations that with a structure like this:
table[(diff, carry)] = amount_of_numbers_with_the_same_diff_and_carry
Then the iteration begins, you need to keep updating the table as you go. Add new entries if you encounter a new signature, and always update amount_of_numbers_with_the_same_diff_and_carry. First round, the single digits, populate the table:
0: 0 * 137 = 0, diff: 0; carry: 0. table[(0, 0)] = 1
1: 1 * 137 = 137. diff: 1 - 7 = -6; carry: 13. table[(-6, 13)] = 1
2: 2 * 137 = 274. diff: 2 - 7 = -5; carry: 27. table[(-5, 27)] = 1
And so on.
Second iteration, the "10"th digit, we will go over the digit 0-9 as your "m" and use it in (1) to see if it can produce a result that neutralizes the "diff". If yes, it means this m is going to make all those amount_of_numbers_with_the_same_diff_and_carry into hits. Hence counting not showing. And then we can calculate the new diff and carry with this digit added, like in the example 9 has diff 6 and carry 123 but 99 has the diff 9 - 6 ( last digit from 1356) = 3 and carry 135, replace the old table using the new info.
Last comment, be careful the digit 0. It will appear a lot of times in the iteration and don't over count it because 0009 = 009 = 09 = 9. If you use c++, make sure the sum is in unsigned long long and that sort because it is big. Good luck.
You are trying to solve a Project Euler problem by brute force. That may work for the first few problems, but for most problems you need think of a more sophisticated approach.
Since it is IMHO not OK to give advice specific to this problem, take a look at the general advice in this answer.
This brute force Python solution of 7 digits ran for 19 seconds for me:
print sum(sum(map(int, str(n))) == sum(map(int, str(137 * n)))
for n in xrange(0, 10 ** 7, 9))
On the same machine, single core, same Python interpreter, same code, would take about 3170 years to compute for 18 digits (as the problem asked).
See dgg32's answer for an inspiration of a faster counting.