Compare commits

...

12 Commits

Author SHA1 Message Date
Mayank Gupta
ed52f5d5e9
Merge e99d542de3 into 9a572dec2b 2024-10-05 22:14:25 +05:30
ARNAV RAJ
9a572dec2b
feat: Implemented Matrix Exponentiation Method (#11747)
* feat: add Matrix Exponentiation method
docs: updated the header documentation and added new documentation for
the new function.

* feat: added new function matrix exponetiation method

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* feat: This function uses the tail-recursive form of the Euclidean algorithm to calculate

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* reduced the number of characters per line in the comments

* removed unwanted code

* feat: Implemented a new function to swaap numbers without dummy variable

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* removed previos code

* Done with the required changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Done with the required changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Done with the required changes

* Done with the required changes

* Done with the required changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update maths/fibonacci.py

Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Done with the required changes

* Done with the required changes

* Done with the required changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>
2024-10-04 09:29:39 -07:00
Lonercode
59ff87dc55
Added doctests to min_cost_string_conversion.py and removed :c specifier (#11721)
* Added doctests to min_cost_string_conversion.py and removed :c specifier

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* resolved line length issues based on ruff requirements

* modified in compliance with ruff for line length

* Update strings/min_cost_string_conversion.py

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>
2024-10-04 02:36:14 -07:00
Sai Aswin Madhavan
917ad62105
Removed incorrect type hints (#11711) 2024-10-04 02:28:50 -07:00
Hardik Pawar
e20b503b24
Improve comments, add doctests for kahns_algorithm_topo.py (#11668)
* Improve comments, add doctests for kahns_algorithm_topo.py

* Improve function docstring

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Rename variables, remove print

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-10-04 02:06:08 -07:00
Mayank Gupta
e99d542de3
Update crawl_hindustan_times_and_get_top_news.py 2024-10-02 00:46:32 +05:30
pre-commit-ci[bot]
bbba57e583 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-01 19:11:22 +00:00
Mayank Gupta
c8ef30bfb8
Update crawl_hindustan_times_and_get_top_news.py 2024-10-02 00:40:59 +05:30
pre-commit-ci[bot]
cbef1c650b [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-01 19:05:52 +00:00
Mayank Gupta
541a64a6d8
Create crawl_hindustan_times_and_get_top_news.py 2024-10-02 00:35:28 +05:30
pre-commit-ci[bot]
ea533ae5b6 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-10-01 18:50:23 +00:00
Mayank Gupta
e5fe3959c1
Create crawl_hindustan_times_and_get_top_news.py 2024-10-02 00:15:31 +05:30
4 changed files with 230 additions and 25 deletions

View File

@ -1,36 +1,61 @@
def topological_sort(graph):
def topological_sort(graph: dict[int, list[int]]) -> list[int] | None:
"""
Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph
using BFS
Perform topological sorting of a Directed Acyclic Graph (DAG)
using Kahn's Algorithm via Breadth-First Search (BFS).
Topological sorting is a linear ordering of vertices in a graph such that for
every directed edge u v, vertex u comes before vertex v in the ordering.
Parameters:
graph: Adjacency list representing the directed graph where keys are
vertices, and values are lists of adjacent vertices.
Returns:
The topologically sorted order of vertices if the graph is a DAG.
Returns None if the graph contains a cycle.
Example:
>>> graph = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [], 5: []}
>>> topological_sort(graph)
[0, 1, 2, 3, 4, 5]
>>> graph_with_cycle = {0: [1], 1: [2], 2: [0]}
>>> topological_sort(graph_with_cycle)
"""
indegree = [0] * len(graph)
queue = []
topo = []
cnt = 0
topo_order = []
processed_vertices_count = 0
# Calculate the indegree of each vertex
for values in graph.values():
for i in values:
indegree[i] += 1
# Add all vertices with 0 indegree to the queue
for i in range(len(indegree)):
if indegree[i] == 0:
queue.append(i)
# Perform BFS
while queue:
vertex = queue.pop(0)
cnt += 1
topo.append(vertex)
for x in graph[vertex]:
indegree[x] -= 1
if indegree[x] == 0:
queue.append(x)
processed_vertices_count += 1
topo_order.append(vertex)
if cnt != len(graph):
print("Cycle exists")
else:
print(topo)
# Traverse neighbors
for neighbor in graph[vertex]:
indegree[neighbor] -= 1
if indegree[neighbor] == 0:
queue.append(neighbor)
if processed_vertices_count != len(graph):
return None # no topological ordering exists due to cycle
return topo_order # valid topological ordering
# Adjacency List of Graph
graph = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [], 5: []}
topological_sort(graph)
if __name__ == "__main__":
import doctest
doctest.testmod()

View File

@ -7,6 +7,8 @@ the Binet's formula function because the Binet formula function uses floats
NOTE 2: the Binet's formula function is much more limited in the size of inputs
that it can handle due to the size limitations of Python floats
NOTE 3: the matrix function is the fastest and most memory efficient for large n
See benchmark numbers in __main__ for performance comparisons/
https://en.wikipedia.org/wiki/Fibonacci_number for more information
@ -17,6 +19,9 @@ from collections.abc import Iterator
from math import sqrt
from time import time
import numpy as np
from numpy import ndarray
def time_func(func, *args, **kwargs):
"""
@ -230,6 +235,88 @@ def fib_binet(n: int) -> list[int]:
return [round(phi**i / sqrt_5) for i in range(n + 1)]
def matrix_pow_np(m: ndarray, power: int) -> ndarray:
"""
Raises a matrix to the power of 'power' using binary exponentiation.
Args:
m: Matrix as a numpy array.
power: The power to which the matrix is to be raised.
Returns:
The matrix raised to the power.
Raises:
ValueError: If power is negative.
>>> m = np.array([[1, 1], [1, 0]], dtype=int)
>>> matrix_pow_np(m, 0) # Identity matrix when raised to the power of 0
array([[1, 0],
[0, 1]])
>>> matrix_pow_np(m, 1) # Same matrix when raised to the power of 1
array([[1, 1],
[1, 0]])
>>> matrix_pow_np(m, 5)
array([[8, 5],
[5, 3]])
>>> matrix_pow_np(m, -1)
Traceback (most recent call last):
...
ValueError: power is negative
"""
result = np.array([[1, 0], [0, 1]], dtype=int) # Identity Matrix
base = m
if power < 0: # Negative power is not allowed
raise ValueError("power is negative")
while power:
if power % 2 == 1:
result = np.dot(result, base)
base = np.dot(base, base)
power //= 2
return result
def fib_matrix_np(n: int) -> int:
"""
Calculates the n-th Fibonacci number using matrix exponentiation.
https://www.nayuki.io/page/fast-fibonacci-algorithms#:~:text=
Summary:%20The%20two%20fast%20Fibonacci%20algorithms%20are%20matrix
Args:
n: Fibonacci sequence index
Returns:
The n-th Fibonacci number.
Raises:
ValueError: If n is negative.
>>> fib_matrix_np(0)
0
>>> fib_matrix_np(1)
1
>>> fib_matrix_np(5)
5
>>> fib_matrix_np(10)
55
>>> fib_matrix_np(-1)
Traceback (most recent call last):
...
ValueError: n is negative
"""
if n < 0:
raise ValueError("n is negative")
if n == 0:
return 0
m = np.array([[1, 1], [1, 0]], dtype=int)
result = matrix_pow_np(m, n - 1)
return int(result[0, 0])
if __name__ == "__main__":
from doctest import testmod
@ -242,3 +329,4 @@ if __name__ == "__main__":
time_func(fib_memoization, num) # 0.0100 ms
time_func(fib_recursive_cached, num) # 0.0153 ms
time_func(fib_recursive, num) # 257.0910 ms
time_func(fib_matrix_np, num) # 0.0000 ms

View File

@ -17,11 +17,27 @@ def compute_transform_tables(
delete_cost: int,
insert_cost: int,
) -> tuple[list[list[int]], list[list[str]]]:
"""
Finds the most cost efficient sequence
for converting one string into another.
>>> costs, operations = compute_transform_tables("cat", "cut", 1, 2, 3, 3)
>>> costs[0][:4]
[0, 3, 6, 9]
>>> costs[2][:4]
[6, 4, 3, 6]
>>> operations[0][:4]
['0', 'Ic', 'Iu', 'It']
>>> operations[3][:4]
['Dt', 'Dt', 'Rtu', 'Ct']
>>> compute_transform_tables("", "", 1, 2, 3, 3)
([[0]], [['0']])
"""
source_seq = list(source_string)
destination_seq = list(destination_string)
len_source_seq = len(source_seq)
len_destination_seq = len(destination_seq)
costs = [
[0 for _ in range(len_destination_seq + 1)] for _ in range(len_source_seq + 1)
]
@ -31,33 +47,51 @@ def compute_transform_tables(
for i in range(1, len_source_seq + 1):
costs[i][0] = i * delete_cost
ops[i][0] = f"D{source_seq[i - 1]:c}"
ops[i][0] = f"D{source_seq[i - 1]}"
for i in range(1, len_destination_seq + 1):
costs[0][i] = i * insert_cost
ops[0][i] = f"I{destination_seq[i - 1]:c}"
ops[0][i] = f"I{destination_seq[i - 1]}"
for i in range(1, len_source_seq + 1):
for j in range(1, len_destination_seq + 1):
if source_seq[i - 1] == destination_seq[j - 1]:
costs[i][j] = costs[i - 1][j - 1] + copy_cost
ops[i][j] = f"C{source_seq[i - 1]:c}"
ops[i][j] = f"C{source_seq[i - 1]}"
else:
costs[i][j] = costs[i - 1][j - 1] + replace_cost
ops[i][j] = f"R{source_seq[i - 1]:c}" + str(destination_seq[j - 1])
ops[i][j] = f"R{source_seq[i - 1]}" + str(destination_seq[j - 1])
if costs[i - 1][j] + delete_cost < costs[i][j]:
costs[i][j] = costs[i - 1][j] + delete_cost
ops[i][j] = f"D{source_seq[i - 1]:c}"
ops[i][j] = f"D{source_seq[i - 1]}"
if costs[i][j - 1] + insert_cost < costs[i][j]:
costs[i][j] = costs[i][j - 1] + insert_cost
ops[i][j] = f"I{destination_seq[j - 1]:c}"
ops[i][j] = f"I{destination_seq[j - 1]}"
return costs, ops
def assemble_transformation(ops: list[list[str]], i: int, j: int) -> list[str]:
"""
Assembles the transformations based on the ops table.
>>> ops = [['0', 'Ic', 'Iu', 'It'],
... ['Dc', 'Cc', 'Iu', 'It'],
... ['Da', 'Da', 'Rau', 'Rat'],
... ['Dt', 'Dt', 'Rtu', 'Ct']]
>>> x = len(ops) - 1
>>> y = len(ops[0]) - 1
>>> assemble_transformation(ops, x, y)
['Cc', 'Rau', 'Ct']
>>> ops1 = [['0']]
>>> x1 = len(ops1) - 1
>>> y1 = len(ops1[0]) - 1
>>> assemble_transformation(ops1, x1, y1)
[]
"""
if i == 0 and j == 0:
return []
elif ops[i][j][0] in {"C", "R"}:

View File

@ -0,0 +1,58 @@
"""
Fetch all the top headlines from Hindustan Times News website with
title, link to the news article and cover image link.
The following format is used while displaying the data
news = {
0: {
"title": <title-of-the-article>,
"link": <link-to-the-news-article>,
"img": <link-to-the-cover-image>
}
}
"""
import requests
from bs4 import BeautifulSoup
def fetch_ht_news() -> dict:
header = {
"Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
"Sec-GPC": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)\
AppleWebKit/537.36 (KHTML, like Gecko)\
Chrome/127.0.0.0 Safari/537.36",
"sec-ch-ua": '"Not)A;Brand";v="99", "Brave";v="127", "Chromium";v="127"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "Windows",
}
url = "https://www.hindustantimes.com/"
page_request = requests.get(url, headers=header, timeout=10)
data = page_request.content
soup = BeautifulSoup(data, "html.parser")
news = {}
counter = 0
for divtag in soup.find_all("div", {"class": "timeAgo"}):
if "liveStory" not in divtag["class"]:
head = divtag.find(class_="hdg3")
title = head.get_text()
link = divtag["data-weburl"]
imgtag = divtag.find("img")
try:
img = imgtag["data-src"]
except KeyError:
img = imgtag["src"]
news[counter] = {"title": title, "link": link, "img": img}
counter += 1
return news
if __name__ == "__main__":
fetch_ht_news()