Finding unique triangles given in n number of triangles in python - python-3.x

Given n-number of triangles, we are required to find how many triangles are unique out of given triangles. For each triangle we are given three integers a, b and c (the sides of a triangle).
A triangle is said to be unique if there is no other triangle with same set of sides.
Sample Input:
7 6 5
5 7 6
8 2 9
2 3 4
2 4 3
Sample Output:
1
Explanation:
Each line is a triangle with 3 sides given. The first two triangles are identical since they have similar sides (just the orders are different). ie. the sum of all the sides for both triangles are equal.
The third triangle '8 2 9' is unique since no other triangle has the exact similar sides. So the output is 1 (total number of unique triangles)
Sample Input:
34 5 32
15 20 6
4 2 3
5 6 9
15 20 6
34 5 32
Sample Output:
2
Here the triangles '423' and '560' are unique. So the output is 2 (total number of unique triangles)
This is what I did...
n = int(input())
arr = [list(map(int, input().split())) for x in range(n)]
def uniqueTriangle(arr):
row = len(arr)
col = len(arr[0])
mp = {}
hel = {}
for i in range(row):
tri = arr[i]
tri.sort()
strA = [str(x) for x in tri]
strB = ''
strB = strB.join(strA)
if strB not in mp.values():
mo[i] = strB
else:
hell[i] = strB
count = 0
for i in range(row):
if i in mp:
val = mp.get(i)
if val not in hel.values():
count = count + 1
print (count)
Apologize for the ugly code. But how can I make this code better?

from collections import Counter
arr = [[7, 6, 5],[5, 7, 6],[8, 2, 9],[2, 3, 4],[2, 4, 3]]
def unique_triangles(arr):
counter = Counter([frozenset(a) for a in arr])
return len([res for res in counter if counter[res] == 1])
Use frozenset to mark each unique set of triangle
use collections.Counter to count the number of unique sets found in the input array
return the set appeared only once

This is what I did :
n = int(input())
l=[]
for i in range(n):
t = [int(side) for side in input().split()]
l.append(set(t))
ans=[]
for j in l:
count=0
for i in l:
if i==j:
count+=1
if count==1:
ans.append(j)
print(len(ans))

Related

pandas listing same indexes

if a table has the same index 3 times in a row, I want it to fetch me this dataframe.
example
index var1
1 a
2 b
2 c
2 d
3 e
2 f
5 g
2 f
After the code
expected output
index var1
2 b
2 c
2 d
One option is to split data frame on the diff index, check size of each chunk and filter out chunks with sizes smaller then threshold and then recombine them:
import pandas as pd
import numpy as np
diff_indices = np.flatnonzero(df['index'].diff().ne(0))
diff_indices
# array([0, 1, 4, 5, 6, 7], dtype=int32)
pd.concat([chunk for chunk in np.split(df, diff_indices) if len(chunk) >= 3])
index var1
1 2 b
2 2 c
3 2 d
Let us identify the blocks of consecutive indices using cumsum, then group and transform with count to find the size of each block then select the rows where the block size > 2
b = df['index'].diff().ne(0).cumsum()
df[b.groupby(b).transform('count') > 2]
index var1
1 2 b
2 2 c
3 2 d
You can assign consecutive rows to same value by comparing with next and cumsum. Then groupby consecutive rows and keep the group where number of rows are 3 times
m = df['index'].ne(df['index'].shift()).cumsum()
out = df.groupby(m).filter(lambda col: len(col) == 3)
print(out)
index var1
1 2 b
2 2 c
3 2 d
Here's one more solution on top of the ones above (this one is more generalizable, since it selects ALL slices that meet the given criterium):
import pandas as pd
df['diff_index'] = df['index'].diff(-1) # calcs the index diff
df = df.fillna(999) # get rid of NaNs
df['diff_index'] = df['diff_index'].astype(int) # convert the diff to int
df_selected = [] # create a list of all dfs we're going to slice
l = list(df['diff_index'])
for i in range(len(l)-1):
if l[i] == 0 and l[i+1] == 0: # if 2 consecutive 0s are found, get the slice
df_temp = df[df.index.isin([i,i+1,i+2])]
del df_temp['diff_index']
df_selected.append(df_temp) # append the slice to our list
print(df_selected) # list all identified data frames (in your example, there will be only one
[ index var1
1 2 b
2 2 c
3 2 d]

How to fill a matrix with equal sum of rows and columns?

I have a N x N matrix with integer elements.
We have two inputs : n and k.
There is two condition for solving this problem:
1- sum of matrix's columns and rows should be equal to k.
2- Difference between max and min numbers in matrix should be minimum.
I wrote a code in python but it doesn't work well.
n , k = map(int,input().split())
matrix = [[k//n]*n for i in range(n)]
def row_sum(matrix,row):
return sum(matrix[row])
def col_sum(matrix,col):
res = 0
for i in matrix:
res += i[col]
return res
for i in range(n):
for j in range(n):
if (row_sum(matrix,i) != k) and (col_sum(matrix, j) != k):
matrix[i][j] += 1
for i in matrix:
print(*i)
for example we have a 5x5 matrix that sum of its columns and rows should be equal to 6:
input : 5 6
output :
2 1 1 1 1
1 2 1 1 1
1 1 2 1 1
1 1 1 2 1
1 1 1 1 2
but it doesn't work well:
input : 6 11
output:
2 2 2 2 2 1
2 2 2 2 2 1
2 2 2 2 2 1
2 2 2 2 2 1
2 2 2 2 2 1
1 1 1 1 1 2
I spend a lot of time on this and i can't solve it. Please Help!
(This problem is not a homework or something like that. It's a question from an algorithm contest and the contest is over!)
The solution is to work out the first row (using the code you already have), and then set each row to be the row above it rotated one position.
So for example if the first row has the values
a b c d e
then you rotate one position each row to get
a b c d e
b c d e a
c d e a b
d e a b c
e a b c d
Since each value gets placed in each column once the columns will contain one of each value and so add up to the same total, and since each row has the same values just moved around all the rows add up the same too.
Code:
n , k = map(int,input().split())
matrix = [[k//n]*n for i in range(n)]
def row_sum(matrix,row):
return sum(matrix[row])
for j in range(n):
if (row_sum(matrix,0) != k):
matrix[0][j] += 1
for i in range(1, n):
for j in range(n):
matrix[i][j] = matrix[i-1][(j+1)%n]
for i in matrix:
print(*i)

Two new columns based on return has two values in dataframe apply

I have a DataFrame:
Num
1
2
3
def foo(x):
return x**2, x**3
When I did df['sq','cube'] = df['num'].apply(foo)
It is making a single column like below:
num (sq,cub)
1 (1,1)
2 (4,8)
3 (9,27)
I want these column separate with their values
num sq cub
1 1 1
2 4 8
3 9 27
How can I achieve this...?
obj = df['num'].apply(foo)
df['sq'] = obj.str[0]
df['cube'] = obj.str[1]

Is it possible to create a fibonacci series using generator expression?

Recently an interviewer ask me to create a fibonacci seris of len 10 (n=10) using generator expression. We can do it using generator function -
def fibonacci(n):
n1, n2, nth, count = 0, 1, 1, 0
while count < n:
yield nth
nth = n1 + n2
n1 = n2
n2 = nth
count += 1
for item in fibonacci(10):
print(item, end=' ')
print()
OUTPUT: 1 1 2 3 5 8 13 21 34 55
Can we generate same fibonacci series output using generator expression?

How to generate pyramid of numbers (using only 1-3) using Python?

I'm wondering how to create a pyramid using only element (1,2,3) regardless of how many rows.
For eg. Rows = 7 ,
1
22
333
1111
22222
333333
1111111
I've have tried creating a normal pyramid with numbers according to rows.
eg.
1
22
333
4444
55555
666666
Code that I tried to make a Normal Pyramid
n = int(input("Enter the number of rows:"))
for rows in range (1, n+1):
for times in range (rows):
print(rows, end=" ")
print("\n")
You need to adjust your ranges and use the modulo operator % - it gives you the remainer of any number diveded by some other number.Modulo 3 returns 0,1 or 2. Add 1 to get your desired range of values:
1 % 3 = 1
2 % 3 = 2 # 2 "remain" as 2 // 3 = 0 - so remainder is: 2 - (2//3)*3 = 2 - 0 = 2
3 % 3 = 0 # no remainder, as 3 // 3 = 1 - so remainder is: 3 - (3//3)*3 = 3 - 1*3 = 0
Full code:
n = int(input("Enter the number of rows: "))
print()
for rows in range (0, n): # start at 0
for times in range (rows+1): # start at 0
print( rows % 3 + 1, end=" ") # print 0 % 3 +1 , 1 % 3 +1, ..., etc.
print("")
Output:
Enter the number of rows: 6
1
2 2
3 3 3
1 1 1 1
2 2 2 2 2
3 3 3 3 3 3
See:
Modulo operator in Python
What is the result of % in Python?
binary-arithmetic-operations
A one-liner (just for the record):
>>> n = 7
>>> s = "\n".join(["".join([str(1+i%3)]*(1+i)) for i in range(n)])
>>> s
'1\n22\n333\n1111\n22222\n333333\n1111111'
>>> print(s)
1
22
333
1111
22222
333333
1111111
Nothing special: you have to use the modulo operator to cycle the values.
"".join([str(1+i%3)]*(1+i)) builds the (i+1)-th line: i+1 times 1+i%3 (thats is 1 if i=0, 2 if i=1, 3 if i=2, 1 if i=4, ...).
Repeat for i=0..n-1 and join with a end of line char.
Using cycle from itertools, i.e. a generator.
from itertools import cycle
n = int(input("Enter the number of rows:"))
a = cycle((1,2,3))
for x,y in zip(range(1,n),a):
print(str(x)*y)
(update) Rewritten as two-liner
from itertools import cycle
n = int(input("Enter the number of rows:"))
print(*[str(y)*x for x,y in zip(range(1,n),cycle((1,2,3)))],sep="\n")

Resources