Essentially, I'm given two lines of input. The first line is an integer length of the substring presented in the second line of input, consisting of only Gs and Hs, similar to 0s and 1s.
N = int(input())
chars = list(input())
lonely = 0
for i in range(3, N + 1):
for j in range(N - i + 1):
if ((chars[j:j + i].count('G') == 1) or (chars[j:j + i].count('H') == 1)):
lonely += 1
print(lonely)
An example input is:
5
GHGHG
for which the answer is 3: the answer is the number of the original string's substrings of length 3 or greater that only have one G or one H (this G or H is 'lonely'), and for the above sample, the substrings that meet this criterion are chars[0:3], chars[1:4], and chars[2:5]. While I think this is technically correct, there are no constraints on N so I am timing out for test cases where N = 5000 and such (I have a time limit of 4 seconds per test case).
How do I work around this?
Thank you!
You could split the string on "G" and analyse the size of the left and right streak of H on each side of the splits. This will let you use compute the number of substrings with that lonely G in them. The number of substrings for a given G split will be formed of 3 parts: The n Hs on the left will form n-1 substrings that end with the G. The m Hs on the right will form m-1 substrings starting with the G. And the product of the left and right (n x m) will form substrings with the G in between Hs.
def count3(chars):
count = 0
for lonely in "GH": # count for G, then H
streaks = map(len,chars.split(lonely))
left = next(streaks) # first left side
for right in streaks: # get right sides
count += max(0,left-1) # HH...G
count += max(0,right-1) # G...HH
count += left*right # H...G...H
left = right # track new left side
return count
Output:
for testCase in ("G","GH","GHH","HG","HGH","HGHH","HHG","HHGH","HHGHH",
"GG","HHHGHHH","GGHGG","GGH"):
print(testCase,count3(testCase))
G 0
GH 0
GHH 1
HG 0
HGH 1
HGHH 3
HHG 1
HHGH 3
HHGHH 6
GG 0
HHHGHHH 13
GGHGG 6
GGH 1
I haven't found anything even relevant to my question, so i may be asking it wrong.
I am working on an exercise where I am given sequential values starting at 1 and going to n, but not in order. I must find a missing value from the list.
My method is to add the full 1 => n value in a for loop but I can't figure out how to add n - 1 non-sequential values each as its own line of input in order to subtract it from the full value to get the missing one.
I have been searching modifications to for loops or just how to add n inputs of non-sequential numbers. If I am simply asking the wrong question, I am happy to do my own research if someone could point me in the right direction.
total = 0
for i in range (1 , (int(input())) + 1):
total += i
print(total)
for s in **?????(int(input()))**:
total -= s
print(total)
sample input:
5
3
2
5
1
expected output: 4
To fill in the approach you're using in your example code:
total = 0
n = int(input("How long is the sequence? "))
for i in range(1, n+1):
total += i
for i in range(1, n):
total -= int(input("Enter value {}: ".format(i)))
print("Missing value is: " + str(total))
That first for loop is unnecessary though. First of all, your loop is equivalent to the sum function:
total = sum(range(1,n+1))
But you can do away with any iteration altogether by using the formula:
total = int(n*(n+1)/2) # division causes float output so you have to convert back to an int
I don't know if you are supposed to create the initial data (with the missing item), so I added some lines to generate this sequence:
import random
n = 12 # or n = int(input('Enter n: ')) to get user input
# create a shuffled numeric sequence with one missing value
data = list(range(1,n+1))
data.remove(random.randrange(1,n+1))
random.shuffle(data)
print(data)
# create the corresponding reference sequence (without missing value)
data2 = list(range(1,n+1))
# find missing data with your algorithm
print("Missing value =", sum(data2)-sum(data))
Here is the output:
[12, 4, 11, 5, 2, 7, 1, 6, 8, 9, 10]
Missing value = 3
Quiz on Tutorials Point list the following question?
https://www.tutorialspoint.com/python/python_online_quiz.htm
Q 9 - What is the output of L[-2] if L = [1,2,3]?
A - 1
B - 2
C - 3
D - None of the above.
Answer : A Explanation 1, Negative: count from the right.
They are saying the answer is 1, but when I run the following in idle I get output of 2
L = [1,2,3]
print (L[-2])
output 2
is this a error on tutorial point or is it error in idle ?
My python version is 2.7
The Quiz should be wrong.
L[-1] refers to the last element of the list, 1. Therefore, L[-2] should refer to 2.
Assuming L = [1,2,3], we know that their elements positions are:
number 1 = position 0
number 2 = position 1
number 3 = position 2
So L[-2] is equal to 2, because:
Counting Forward:
L[0] = number 1
L[1] = number 2
L[2] = number 3
Counting Backward:
L[-1] = number 3
L[-2] = number 2
L[-3] = number 1
So... I think your quiz answer is wrong. The correct answer for L[-2] is the alternative B-2.
I'm very sorry I'm asking this question, but my coding skills are not so great, so I can not solve this problem: there is a grid 5*5, and a task is to find minimal number of "lights", or "1" settled in a special way: in every 3*3 square of the big square, there must be exactly 4 "lights". Counting with a pen, I've got this minimal number equals 7 (the answer is right). So my solution looks like this:
#creates a list
grid = []
#creates lines
for row in range(5):
grid.append([])
#creates columns
for column in range(5):
grid[row].append(0)
#one "light" must be in a center
grid[2][2] = 1
#this array counts all "lights" and will notice when there are 4 of them
light_number = []
def counter():
for row in range(0, 3):
for column in range(0, 3):
if grid[row][column] == 1:
light_number.append(1)
print(len(light_number))
As expected, counter() works only for the first little 3*3 square. Wanting to have only one function for searching "lights" and not 9, I`ve tried to write something like this:
def counter():
#initial range of the counter
row_min = 0
row_max = 3
column_min = 0
column_max = 3
for i in range(9):
for row in range(row_min, row_max):
for column in range(column_min, column_max):
if grid[row][column] == 1:
#write it in a list
light_number.append(1)
column_min += 1
column_max += 1
row_min += 1
row_max += 1
#print a number of total lights
print(len(light_number))
But it doesn't work, saying that grid[row][column] == 1 is out of range.
So, the problem is:
I can't write working counter, which should automatically see all little squares 3*3
I don't know, how to write all combinations of "lights".
Please, if you have ANY idea, tell me. If you think there can be another solution, please, say also. Thanks in advance.
Until someone comes up with a smarter algorithm, I can offer you a brute-force solution to enumerate all grids.
Represent each row of a grid as a "binary" number from 0 (all lights in a row are off) to 31 (all lights are on). Then, a grid will be a 5-tuple of such numbers. There are 32^5 = 33554432 grids - something that is possible to brute-force within minutes, if done efficiently.
To check a number of lights (bits) in a 3x3 square that starts at row r and column c (where r and c are between 0 and 2), use bit shifts and masks:
s = (nbits[7 & (g[r + 0] >> (2 - c))]
+nbits[7 & (g[r + 1] >> (2 - c))]
+nbits[7 & (g[r + 2] >> (2 - c))])
where g is a grid and nbits holds the number of bits for each number from 0 to 7. If some s != 4, the grid is not valid, go on to the next one.
Putting it all together:
import itertools
# 0 1 2 3 4 5 6 7
nbits = [ 0,1,1,2,1,2,2,3 ]
def check(g):
for r in range(3):
for c in range(3):
s = (nbits[7 & (g[r + 0] >> (2 - c))]
+nbits[7 & (g[r + 1] >> (2 - c))]
+nbits[7 & (g[r + 2] >> (2 - c))])
if s != 4:
return False
return True
for g in itertools.product(range(32), repeat=5):
if check(g):
print g
for row in g:
print '{:05b}'.format(row)
print
The question was about learning something about programming. As far as I can see, a simple backtrack-mechanism should be used:
import numpy as np
#initialize the grid with the middle set to one
grid = np.zeros((5,5))
grid[2,2] = 1
First, we need a simple check function, that returns True if the global grid is
gracefully filled with ones:
# a method to check all sub squares starting at row and column 0 through 2
def checkgrid():
# row 0 through 2
for r in xrange(3):
# column 0 through 2
for c in xrange(3):
# sum up all entries of grid matrix
if grid[r:r+3, c:c+3].sum() != 4:
return False
return True
And here we go with the main method. The idea is the following: Every grid entry has a
unique identifier between zero and 24, its "idx". The aim is to find a valid configuration
where the six ones are spread correctly over the 24 grid entries (25 - middle entry).
All possible binom(24, 6)=134596 solutions are enumerated through a simple loop and a recursive call to place the remaining entries, until the check-method returns True the first time, i.e. when a valid configuration is found.
# method that is recursively applied to set the next one
def recursive_trial(first, depth, maxdepth):
# all ones are placed: check the grid
if depth == maxdepth:
return checkgrid()
# enumerate possible grid positions as idx == 5 * r + c
for idx in xrange(first, 25 - (maxdepth - depth + 1)):
# get row and column idx
r = idx / 5
c = idx % 5
# skip the middle
if grid[r,c] == 1:
continue
# set entry to one
grid[r,c] = 1
# call method recursively to place missing ones until 7 in the remainder of the array
if recursive_trial(idx + 1, depth + 1, maxdepth):
return True
# set entry back to zero
grid[r,c] = 0
# at this point, we failed with the current configuration.
return False
A call to
recursive_trial(0, 0, 6)
print grid
yields (in a matter of milliseconds)
[[ 0. 0. 1. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 1. 1. 1. 1. 1.]
[ 0. 0. 1. 0. 0.]
[ 0. 0. 0. 0. 0.]]
This is how I will solve it:
grid = [[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0]]
grid33total = [[0,0,0],[0,0,0],[0,0,0]]
for i in range(3):
for j in range(3):
grid33total[i][j] = sum(sum(x[0+i:3+i]) for x in grid[0+j:3+j])
total = sum(sum(x) for x in grid33total)
The array grid33total contains the number of "lights" for each of the 3x3 squares.
So, thankfully to efforts and help, I've came up with a solution.
import itertools
from pprint import pprint
import sys
def check(grid):
count = 0
for row in range(3):
for column in range(3):
s = 0
for right in range(3):
for down in range(3):
if grid[row+right][column+down] == 1:
s += 1
if s == 4:
count += 1
if count != 9:
return False
else:
return True
for n in range(4, 25):
for comb in itertools.combinations(range(25), n):
grid = [[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
for index in comb:
row = index // 5
column = index % 5
grid[row][column] = 1
if check(grid):
print(n)
pprint(grid)
sys.exit()
I've decided to use itertools.combinations.
row = index // 5
column = index % 5
grid[row][column] = 1
is a very interesting way to determine whether there must be "1" or "0". Program looks at the result of integer division (//), and that will be a row number, and then at the residual (%), that will be a column number. Then it places "1" here.
I know, it's not so beautiful and short, as nbits solution, but it's also a possible variant. On my computer it works just about five minutes.
def tableCheck(elev, n, m):
tablePosCount = 0
rowPosCount = 0
for r in range(1, n):
for c in range(1, m):
if elev[r][c] > 0:
tablePosCount = tablePosCount + 1
rowPosCount = rowPosCount + 1
print 'Number of positive entries in row ', r , ' : ', rowPosCount
print 'Number of positive entries in table :', tablePosCount
return tablePosCount
elev = [[1,0,-1,-3,2], [0,0,1,-4,-1], [-2,2,8,1,1]]
tableCheck(elev, 3, 5)
I'm having some difficulty getting this code to run properly. If anyone can tell me why it might being giving me this output
Number of positive entries in row 1 : 1
Number of positive entries in row 2 : 2
Number of positive entries in row 2 : 3
Number of positive entries in row 2 : 4
Number of positive entries in row 2 : 5
Number of positive entries in table : 5
There are three things in your code that I suspect are errors, though since you don't describe the behavior you expect, it's possible that one or more of these is working as intended.
The first issue is that you print out the "row" number every time that you see a new value that is greater than 0. You probably want to unindent the print 'Number of positive entries in row ' line by two levels (to be even with the inner for loop).
The second issue is that you don't reset the count for each row, so the print statement I suggested you move will not give the right output after the first row. You probably want to move the rowPosCount = 0 line inside the outer loop.
The final issue is that you're skipping the first row and the first value of each later row. This is because your ranges go from 1 to n or m. Python indexing starts at 0, and ranges exclude their upper bound. You probably want for r in range(n) and for c in range(m), though iterating on the table values themselves (or an enumeration of them) would be more Pythonic.