Algorithm counting - python

I am a bit confused in this condition: lets say we have a number from 1 to 9 its numerical code from the beginning 1 to the 9. If the number already reach number 9, then it is loop again from 1 to 9 again, and it begin again from number 1. Each number from that range continue appear with a random number continue like this example:
1111122222333334444445555556666667777777888888999999111111222222333333444445555566677778899....
then the problem is I need an algorithm or a code to detect if number 4 appear I want count it as 1, but I want to eliminate the continue appear from the number 4 other (I didnt want to count the continuing of number 4). sorry if its not a clearly explaination. It maybe better explain from the example. the example:
if the data is
1111222334445556667788999111222333444455566677788899
so the counting program must be 2 because number 4 appear twice (I mark the first appear of number 4), and the continuing for that number not be count. oh yes all of that number (1-9) it always continue appear with a random number continue.
Thank you for your help :-)

If the number appear at least once you could count the "edges" ie
n = numstr.count("34")
(Obviously need to test starting number in sequence as special case (i.e. if looking at number of "91"s)
EDIT. Following significant revision mentioned in comments, you would have to do something along the lines of this:
a = [66,69,69,77,78,80,84,84,91,91,96,96,100,100,109,116,116,124,124,137,137,140,66,66,66,78,78,80,80,80,84]
c = {a[0]:1}
for i in range(1, len(a)):
if a[i] != a[i-1]:
if a[i] in c:
c[a[i]] += 1
else:
c[a[i]] = 1

Lets assume that you have the numbers as a string.
Let the string be str be comprising of all these numbers.
I'll propose a code in c.
int count=0,flag=0;
for(int i=0;i<strlen(str);i++){
if(flag==0){
if(str[i]=='4'){
count=count+1;
flag=1;
continue;
}
}
if(flag==1 && str[i]=='4')
continue;
flag=0;
}
printf("%d\n",count);
Count is the answer to your problem.

Related

Creating a function that returns prime numbers under a given maximum?

Instructions are to write a function that returns all prime numbers below a certain max number. The function is_factor was already given, I wrote everything else.
When I run the code I don't get an error message or anything, it's just blank. I'm assuming there's something I'm missing but I don't know what that is.
def is_factor(d, n):
""" True if `d` is a divisor of `n` """
return n % d == 0
def return_primes(max):
result = []
i = 0
while i < max:
if is_factor == True:
return result
i += 1
You should test each i against all divisors smaller than math.sqrt(i). Use the inner loop for that. any collects the results. Don't return result right away, for you should fill it first.
def return_primes(max):
result = []
for i in range(2, max):
if not any(is_factor(j, i) for j in range(2, int(math.sqrt(i)) + 1)):
result.append(i)
return result
print(return_primes(10))
As a side note, use for and range rather than while to make less mistakes and make your code more clear.
The reason that your code is returning blank when you run it, is because you are comparing a function type to the value of True, rather than calling it.
print(is_factor)
<function is_factor at 0x7f8c80275dc0>
In other words, you are doing a comparison between the object itself rather than invoking the function.
Instead, if you wanted to call the function and check the return value from it, you would have to use parenthesis like so:
if(is_factor(a, b) == True):
or even better
if(is_factor(a, b)):
which will inherently check whether or not the function returns True without you needing to specify it.
Additionally, you are not returning anything in your code if the condition does not trigger. I recommend that you include a default return statement at the end of your code, not only within the condition itself.
Now, in terms of the solution to your overall problem and question;
"How can I write a program to calculate the prime numbers below a certain max value?"
To start, a prime number is defined by "any number greater than 1 that has only two factors, 1 and itself."
https://www.splashlearn.com/math-vocabulary/algebra/prime-number
This means that you should not include 1 in the loop, otherwise every single number is divisible by 1 and this can mess up the list you are trying to create.
My recommendation is to start counting from 2 instead, then you can add 1 as a prime number at the end of the function.
Before going over the general answer and algorithm, there are some issues in your code I'd like to address:
It is recommended to use a different name for your variable other than max, because max() is a function in python that is commonly used.
Dividing by 0 is invalid and can break the math within your program. It is a good idea to check the number you are dividing by to ensure it is not zero to make sure you do not run into math issues. Alternatively, if you start your count from 2 upwards, you won't have this issue.
Currently you are not appending anything into your results array, which means no results will be returned.
My recommendation is to add the prime number into the results array once it is found.
Right now, you return the results array as soon as you have calculated the first result. This is a problem because you are trying to capture all of the prime numbers below a specific number, and hence you need more than one result.
You can fix this by returning the results array at the end of the function, not in between, and making sure to append each of the prime numbers as you discover them.
You need to check every single number between 2 and the max number to see if it is prime. Your current code only checks the max number itself and not the numbers in between.
Now I will explain my recommended answer and the algorithm behind it;
def is_factor(d, n):
print("Checking if " + str(n) + " is divisible by " + str(d))
print(n % d == 0)
return n % d == 0
def return_primes(max_num):
result = []
for q in range(2, max_num+1):
count_number_of_trues = 0
for i in range(2, q):
if(i != q):
if(is_factor(i, q)):
print("I " + str(i) + " is a factor of Q " + str(q))
count_number_of_trues += 1
if(q not in result and count_number_of_trues == 0):
result.append(q)
result.append(1)
return sorted(result)
print(return_primes(10))
The central algorithm is that you want to start counting from 2 all the way up to your max number. This is represented by the first loop.
Then, for each of these numbers, you should check every single number from 2 up to that number to see if a divisor exists.
Then, you should count the number of times that the second number is a factor of the first number, and if you get 0 times at the end, then you know it must be a prime number.
Example:
Q=10
"Is I a factor of Q?"
I:
9 - False
8 - False
7 - False
6 - False
5 - True
4 - False
3 - False
2 - True
So for the number 10, we can see that there are 2 factors, 5 and 2 (technically 3 if you include 1, but that is saved for later).
Thus, because 10 has 2 factors [excluding 1] it cannot be prime.
Now let's use 7 as the next example.
Example:
Q=7
"Is I a factor of Q?"
I:
6 - False
5 - False
4 - False
3 - False
2 - False
Notice how every number before 7 all the way down to 2 is NOT a factor, hence 7 is prime.
So all you need to do is loop through every number from 2 to your max number, then within another loop, loop through every number from 2 up to that current number.
Then count the total number of factors, and if the count is equal to 0, then you know the number must be prime.
Some additional recommendations:
although while loops will do the same thing as for loops, for loops are often more convenient to use in python because they initialize the counts for you and can save you some lines of code. Also, for loops will take care of the incrementing process for you so there is no risk of forgetting.
I recommend sorting the list when you return it, it looks nicer that way.
Before adding the prime factor into your results list, check to see if it is already in the list so you don't run into a scenario where multiples of the same number is added (like [2,2,2] for example)
Please note that there are many different ways to implement this, and my example is but one of many possible answers.

Python optimizing loops for checking number of anagrams

i am trying to solve a question that provides a string as input and gives the number of anagrams possible as output. this can be solved using dictionaries but i could only think in terms of for loops and string indices.
count = 0
for i in range(1,len(s)):
for j in range(0,len(s)):
for k in range(j+1,len(s)):
if(k+i>len(s)):
continue
# print(list(s[j:j+i]),list(s[k:k+i]),j,j+i,k,k+i)
if(sorted(list(s[j:j+i]))==sorted(list(s[k:k+i]))):
count +=1
return count
i have coded this far and tried for optimization with k+i. can someone tell me other techniques to optimize the code without losing the logic. the code keeps getting terminated due to time-out for larger strings.should i replace sorted function with something else.
The number of anagrams if each letter was unique would be n! with n as the length of the string (e.g. law has 3!=6). If there a given letter is repeated, say, twice (e.g. wall), then you have twice as many answers as you should (since things like w-(second l)-(first l)-a are actually indistinguishable from things like w-(first l)-(second l)-a). It turns out that if a letter is repeated k times (k is 2 for the letter "l" in wall), n! overcounts by a factor of k!. This is true for each repeated letter.
So to get the number of anagrams, you can do:
letter_counts = get_letter_counts(s) #returns something like [1, 1, 2] when given wall, since there is one w, one a, two ls
n_anagrams = factorial(len(s))
#account for overcounts
for letter_count in letter_counts:
n_anagrams /= factorial(letter_count)
return n_anagrams
Implementing factorial and get_letter_counts left as an excercise for the reader :-) . Note: Be careful to consider that repeated letters can show up more than once, and not always next to each other. Ex: "aardvark" should return a count of 3 for the "a"s, 2 for the "r"s, and 1 for everything else.

Lucky Numbers Python Program Incorrect Python Output

Practice Problems /
Lucky String
All submissions to this problem are public. View all submissions.
Lucky numbers are those numbers which contain only "4" and/or "5". For example 4, 5, 44, 54,55,444 are lucky numbers while 457, 987 ,154 are not.
Lucky number sequence is one in which all lucky numbers exist in increasing order for example 4,5,44,45,54,55,444,445,454,455...
Now we concatenate all the lucky numbers (in ascending order) to make a lucky string "4544455455444445454455..."
Given n, your task is to find the nth digit of the lucky string. If the digit is 4 then you >have to print "Hacker" else you have to print "Earth".
Input:
first line contain number of test cases T , next T line contain a single integer n.
Output:
For each test case print Hacker if n-th digit of lucky string is 4 else print Earth if n-th digit of lucky string is 5.
Constraints:
1 <= t <= 10^5
1 <= n <= 10^15
Following is the python code :
test_cases = int(input())
final = []
def check(stra,num):
if stra[num-1]==4:
final.append("Hacker")
else:
final.append("Earth")
def GenStr(num):
stra = "4"
i = int(5)
while(len(stra)<num+2):
X = str(i)
flag = True
for j in range(len(str(i))):
if(X[j]==4 or X[j]==5):
pass
else:
flag = False
if flag==True:
stra+=X
i+=1
print(stra)
return stra
for i in range(test_cases):
num = int(input())
# generate string
stra = GenStr(num)
print("stra "+stra)
# check the stat
check(stra,num)
print("\n".join(final))
What is wrong in this code, please do not mind if it is a silly mistake I am just a beginner in python programming
Comments on your Code
There are several things in your code which don't quite make sense, and need to be addressed:
int(input()) says to ask the user nothing, try to convert any string they type before pressing enter to an integer, and crash otherwise.
The pattern for i in range(len(x)) is almost always wrong in Python. Strings are iterable (they are lists of characters), which is why you can use the list-style index operator (as you do with x[j]), so just iterate over them: for j in str(i).
The pattern if x==True: is always wrong in Python. We prefer if x:.
i = int(5). There is no need to convert an integer literal to an integer. i = 5 is the correct assignment statement.
Try to use better variable names. It's very difficult to follow your code and your reasoning because it is littered with meaningless identifiers like stra (string a??), X, num, etc.
How to Approach the Assignment
I will be honest: I don't fully understand the assignment as presented. It's not clear what a "test case" is or how the input will be formatted (or, for that matter, where the input is coming from). That said, a few thoughts on how to approach this:
Finding numbers that contain only 4 or 5 means treating them as strings. This could be as easy as testing len(str(x).replace('4', '').replace('5', '')), and there are better ways than that.
Listing 'lucky numbers' in increasing order can be accomplished with the built-in sorted function.
Concatenating that list would be ''.join(sorted(lucky_numbers)) or similar.
Taking the nth digit of that list could then be done with string indexing as before.
The immediately incorrect thing is the following. stra is 4. flag always becomes False. Thus stra never grows, and while(len(stra)<num+2): is an infinite loop.
The approach itself will not fully solve the problem, since you can't construct a string of length 1015, it would take too much time and just won't fit into memory.
As #Gassa points out, brute-forcing this is just not going to work; you would need a million gigabytes of RAM, and it would take far too long.
So what would an analytic solution look like?
If you replace "4" with "0" and "5" with "1", you will see that the lucky number sequence becomes 0, 1, 00, 01, 10, 11, 000, 001, 010, 011, 100, 101, 110, 111, .... This should look familiar: it is every 1-digit binary number in ascending order, followed by every 2-digit binary number in ascending order, followed by every 3-digit binary number in ascending order, etc.
So if you do something like
n = 491 # the digit we are seeking (for example)
d = 1 # number of binary digits
p = 2 # 2**d == number of items encoded
while n > d*p: # sought digit is past the end of the next binary expansion?
n -= d*p # reduce offset by appropriate number of digits
d += 1
p *= 2
then n = 233, d = 6 means we are looking for the 233rd character in the 6-bit expansion.
But we can improve on that:
k, n = n // d, n % d
which gives n = 5, k = 38, d = 6 means we are looking at the 5th character of the 38th 6-bit value.
Note: all offsets here are 0-based; if you expect 1-based offsets, you will have to adjust your math accordingly!
The 38th 6-bit value is just 38 converted to a 6-bit binary value; you could muck about with strings to extract the character you want, but it's probably easier to remember that integers are stored as binary internally so we can get what we want with a bit of math:
digit = (k >> (d - n - 1)) & 1 # => 0
so the character in the original string would be a "4".

Bulls & cows (mastermind) in Python. Should be relatively easy

I'm new to python and I need to write a "Bulls and Cows" game (a.k.a Mastermind)
and it goes like this:
You get 2 inputs at first; 1 for the length of the secret (can be 4-6), and 2nd for the base (can be 6-10).
You can ASSUME that both the secret and the guess will have the given length (you don't need to make sure of that)
Later on, you have another 2 inputs. 1 for the secret (a chain of numbers seperated by space) and the 2nd for the base (a chain of numbers seperated by space).
if the secret has a number that equals or exceeds the base, the program will output ERROR and exit.
An example to clarify:
5 (First input, length should be 5)
8 (The base. It means that no number is allowed to be 8 or beyond. You are only allowed to use 0,1,2,3,4,5,6,7)
1 2 7 2 5 (this is the secret)
7 2 2 1 1 (this is the guess)
OUTPUT:
1 BULLS 3 COWS
Another example:
6
9
0 0 0 0 0 6
8 22 2 2 1 4
OUTPUT:
0 BULLS 0 COWS
Ok, so I started writing the code, and I wasn't sure what exactly I am supposed to be using, so I did this so far:
#get the length of the guess - an int number between 4(included) to 6(included)
secretL = input()
#get the base of the guess - an int number between 6(included) to 10(included)
secretB = input()
#get the guess
secret = raw_input()
secretsNumbers = map(int, secret.split())
#turn the chain into a singular INT number in order to make sure each of its digits does not equal or exceeds base, using %10
secretsNumbersMerge = int(''.join(map(str,secretsNumbers)))
newSecretsNumbersMerge = secretsNumbersMerge
while newSecretsNumbersMerge!= 0:
checker = newSecretsNumbersMerge%10
if checker<secretBase:
newSecretsNumbersMerge = newSecretsNumbersMerge/10
else:
print ("ERROR")
quit()
guess = raw_input()
guessNumbers = map(int, guess.split())
So far it's all good. This really makes sure the secret meets the base demands. Now I'm at the main point where I should check for bulls and cows and I'm not quite sure how to proceed from this point.
My idea is to first check for Bulls and then remove them (so it won't get mixed with cows), and then check for cows but yeah.. I'm clueless.
I'm not even sure what to use in Python.
Thanks in advance!
Here is your code but please try to understand each line of it:
import re
from collections import Counter
#get the length of the guess - an int number between 4(included) to 6(included)
secretL = input()
#get the base of the guess - an int number between 6(included) to 10(included)
secretB = input()
#get the guess
secret = raw_input()
# Check if the secret input uses a digit greater than the base value
# You can use the check on the next line as well. It can be made faster
# too by using search in place of findall.
# if len(re.findall(r"[^0-" + str(secretB) + r" ]+", secret)):
if sum((i!=" " and int(i) > secretB) for i in secret) > 0:
print("Error")
quit()
secretNumbers = map(int, secret.split())
guess = raw_input()
guessNumbers = map(int, guess.split())
# Count the bulls by iterating over the two lists simultaneously
bulls = sum(i==j for i, j in zip(secretNumbers, guessNumbers))
# Remove the bulls before counting the cows
secretNumbers, guessNumbers = zip(*((x,y) for x,y in zip(secretNumbers, guessNumbers) if x!=y))
# Cows are defined as the elements present in both the guess and the secret
# but not in the right position.
# If we ignore duplicates, this is the way to go about it.
cows = len(set(secretNumbers) & set(guessNumbers))
## If we count [1,1,2,4] and [5,3,1,1] to have 2 cows, this is how it should be:
#counter = Counter(secretNumbers) & Counter(guessNumbers)
#cows = sum(counter.itervalues())
print(str(bulls) + " BULLS " + str(cows) + " COWS")
Let me know if something is not clear and I'll add an explanation.
Also, I'm not aware of the rules of mastermind and have inferred them from your description. I'm not clear how you got 0 cows for the second example.
UPDATE 1
if sum(i > secretB for i in secretNumbers) > 0: how does it work exactly?
Please use backticks(`) to quote small pieces of code in comments, questions or answers. Now, let's break down this code into easily understandable pieces:
Consider the list comprehension [ i > secretB for i in secretNumbers]. This will generate a list of booleans. So, if your base is 6 and secretNumbers is [1,2,7,2,5], it will return [False, False, True, False, False]. (As per your comment, this is not the way the rule was to be interpreted but I'm pretty sure you can modify this condition to be what you need.)
sum() is a very useful standard built-in function in Python which returns the sum of any iterable passed to it. So, sum([1,2,3,4]) will return 10.
It remains to answer what does it mean to sum a list of boolean values. It might initially seem strange to add True to True this way, but I don't think it's unpythonic; after all, bool is a subclass of int in all versions since 2.3:
_
>>>issubclass(bool, int)
True
So, there you go: sum(i > secretB for i in secretNumbers) tells you exactly how many numbers in the input exceed the base.
UPDATE 2:
After a clarification from OP, the explanation of Update 1 doesn't apply to the code under discussion anymore though OP now understands the general technique of using list comprehensions to do powerful things.
Also, the condition for counting the COWS has been clarified and the code now lists two ways to do it - one, while ignoring duplicates; and second by counting each duplicate instance.

Is it possible to calculate the number of count inversions using quicksort?

I have already solved the problem using mergesort, now I am thinking is that possible to calculate the number using quicksort? I also coded the quicksort, but I don't know how to calculate. Here is my codeļ¼š
def Merge_and_Count(AL, AR):
count=0
i = 0
j = 0
A = []
for index in range(0, len(AL) + len(AR)):
if i<len(AL) and j<len(AR):
if AL[i] > AR[j]:
A.append(AR[j])
j = j + 1
count = count+len(AL) - i
else:
A.append(AL[i])
i = i + 1
elif i<len(AL):
A.append(AL[i])
i=i+1
elif j<len(AR):
A.append(AR[j])
j=j+1
return(count,A)
def Sort_and_Count(Arrays):
if len(Arrays)==1:
return (0,Arrays)
list1=Arrays[:len(Arrays) // 2]
list2=Arrays[len(Arrays) // 2:]
(LN,list1) = Sort_and_Count(list1)
(RN,list2) = Sort_and_Count(list2)
(M,Arrays)= Merge_and_Count(list1,list2)
return (LN + RN + M,Arrays)
Generally no, because during the partitioning, when you move a value to its correct side of the pivot, you don't know how many of the values you're moving it past are smaller than it and how many are larger. So, as soon as you do that you've lost information about the number of inversions in the original input.
I come across this problem for some times, As a whole, I think it should be still ok to use quick sort to compute the inversion count, as long as we do some modification to the original quick sort algorithm. (But I have not verified it yet, sorry for that).
Consider an array 3, 6, 2, 5, 4, 1. Support we use 3 as the pivot, the most voted answer is right in that the exchange might mess the orders of the other numbers. However, we might do it different by introducing a new temporary array:
Iterates over the array for the first time. During the iteration, moves all the numbers less than 3 to the temporary array. For each such number, we also records how much number larger than 3 are before it. In this case, the number 2 has one number 6 before it, and the number 1 has 3 number 6, 5, 4 before it. This could be done by a simple counting.
Then we copy 3 into the temporary array.
Then we iterates the array again and move the numbers large than 3 into the temporary array. At last we get 2 1 3 6 5 4.
The problem is that during this process how much inversion pairs are lost? The number is the sum of all the numbers in the first step, and the count of number less than the pivot in the second step. Then we have count all the inversion numbers that one is >= pivot and another is < pivot. Then we could recursively deal with the left part and the right part.

Categories

Resources