Skip to content

Commit 77d586c

Browse files
Merge branch 'TheAlgorithms:master' into main
2 parents 9ab78e1 + 1488cde commit 77d586c

File tree

10 files changed

+176
-18
lines changed

10 files changed

+176
-18
lines changed

Diff for: .github/workflows/directory_writer.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ jobs:
66
build:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@v1 # v1, NOT v2 or v3
9+
- uses: actions/checkout@v4
10+
with:
11+
fetch-depth: 0
1012
- uses: actions/setup-python@v4
1113
with:
1214
python-version: 3.x

Diff for: .github/workflows/project_euler.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,26 @@ jobs:
1414
project-euler:
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v3
17+
- uses: actions/checkout@v4
1818
- uses: actions/setup-python@v4
1919
with:
2020
python-version: 3.x
2121
- name: Install pytest and pytest-cov
2222
run: |
2323
python -m pip install --upgrade pip
24-
python -m pip install --upgrade pytest pytest-cov
24+
python -m pip install --upgrade numpy pytest pytest-cov
2525
- run: pytest --doctest-modules --cov-report=term-missing:skip-covered --cov=project_euler/ project_euler/
2626
validate-solutions:
2727
runs-on: ubuntu-latest
2828
steps:
29-
- uses: actions/checkout@v3
29+
- uses: actions/checkout@v4
3030
- uses: actions/setup-python@v4
3131
with:
3232
python-version: 3.x
3333
- name: Install pytest and requests
3434
run: |
3535
python -m pip install --upgrade pip
36-
python -m pip install --upgrade pytest requests
36+
python -m pip install --upgrade numpy pytest requests
3737
- run: pytest scripts/validate_solutions.py
3838
env:
3939
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Diff for: .pre-commit-config.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ repos:
1616
- id: auto-walrus
1717

1818
- repo: https://github.com/astral-sh/ruff-pre-commit
19-
rev: v0.0.287
19+
rev: v0.0.288
2020
hooks:
2121
- id: ruff
2222

2323
- repo: https://github.com/psf/black
24-
rev: 23.7.0
24+
rev: 23.9.1
2525
hooks:
2626
- id: black
2727

Diff for: DIRECTORY.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* [In Static Equilibrium](arithmetic_analysis/in_static_equilibrium.py)
66
* [Intersection](arithmetic_analysis/intersection.py)
77
* [Jacobi Iteration Method](arithmetic_analysis/jacobi_iteration_method.py)
8+
* [Junk](arithmetic_analysis/junk.py)
89
* [Lu Decomposition](arithmetic_analysis/lu_decomposition.py)
910
* [Newton Forward Interpolation](arithmetic_analysis/newton_forward_interpolation.py)
1011
* [Newton Method](arithmetic_analysis/newton_method.py)
@@ -628,6 +629,7 @@
628629
* [Pi Monte Carlo Estimation](maths/pi_monte_carlo_estimation.py)
629630
* [Points Are Collinear 3D](maths/points_are_collinear_3d.py)
630631
* [Pollard Rho](maths/pollard_rho.py)
632+
* [Polygonal Numbers](maths/polygonal_numbers.py)
631633
* [Polynomial Evaluation](maths/polynomial_evaluation.py)
632634
* Polynomials
633635
* [Single Indeterminate Operations](maths/polynomials/single_indeterminate_operations.py)
@@ -714,6 +716,7 @@
714716
* Activation Functions
715717
* [Exponential Linear Unit](neural_network/activation_functions/exponential_linear_unit.py)
716718
* [Leaky Rectified Linear Unit](neural_network/activation_functions/leaky_rectified_linear_unit.py)
719+
* [Scaled Exponential Linear Unit](neural_network/activation_functions/scaled_exponential_linear_unit.py)
717720
* [Back Propagation Neural Network](neural_network/back_propagation_neural_network.py)
718721
* [Convolution Neural Network](neural_network/convolution_neural_network.py)
719722
* [Perceptron](neural_network/perceptron.py)

Diff for: arithmetic_analysis/jacobi_iteration_method.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
def jacobi_iteration_method(
1313
coefficient_matrix: NDArray[float64],
1414
constant_matrix: NDArray[float64],
15-
init_val: list[int],
15+
init_val: list[float],
1616
iterations: int,
1717
) -> list[float]:
1818
"""
@@ -115,6 +115,7 @@ def jacobi_iteration_method(
115115

116116
strictly_diagonally_dominant(table)
117117

118+
"""
118119
# Iterates the whole matrix for given number of times
119120
for _ in range(iterations):
120121
new_val = []
@@ -130,8 +131,37 @@ def jacobi_iteration_method(
130131
temp = (temp + val) / denom
131132
new_val.append(temp)
132133
init_val = new_val
134+
"""
135+
136+
# denominator - a list of values along the diagonal
137+
denominator = np.diag(coefficient_matrix)
138+
139+
# val_last - values of the last column of the table array
140+
val_last = table[:, -1]
141+
142+
# masks - boolean mask of all strings without diagonal
143+
# elements array coefficient_matrix
144+
masks = ~np.eye(coefficient_matrix.shape[0], dtype=bool)
145+
146+
# no_diagonals - coefficient_matrix array values without diagonal elements
147+
no_diagonals = coefficient_matrix[masks].reshape(-1, rows - 1)
148+
149+
# Here we get 'i_col' - these are the column numbers, for each row
150+
# without diagonal elements, except for the last column.
151+
i_row, i_col = np.where(masks)
152+
ind = i_col.reshape(-1, rows - 1)
153+
154+
#'i_col' is converted to a two-dimensional list 'ind', which will be
155+
# used to make selections from 'init_val' ('arr' array see below).
156+
157+
# Iterates the whole matrix for given number of times
158+
for _ in range(iterations):
159+
arr = np.take(init_val, ind)
160+
sum_product_rows = np.sum((-1) * no_diagonals * arr, axis=1)
161+
new_val = (sum_product_rows + val_last) / denominator
162+
init_val = new_val
133163

134-
return [float(i) for i in new_val]
164+
return new_val.tolist()
135165

136166

137167
# Checks if the given matrix is strictly diagonally dominant

Diff for: arithmetic_analysis/junk.py

Whitespace-only changes.

Diff for: data_structures/linked_list/__init__.py

+50-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,56 @@ def __init__(self) -> None:
2121
self.head: Node | None = None
2222
self.size = 0
2323

24-
def add(self, item: Any) -> None:
25-
self.head = Node(item, self.head)
24+
def add(self, item: Any, position: int = 0) -> None:
25+
"""
26+
Add an item to the LinkedList at the specified position.
27+
Default position is 0 (the head).
28+
29+
Args:
30+
item (Any): The item to add to the LinkedList.
31+
position (int, optional): The position at which to add the item.
32+
Defaults to 0.
33+
34+
Raises:
35+
ValueError: If the position is negative or out of bounds.
36+
37+
>>> linked_list = LinkedList()
38+
>>> linked_list.add(1)
39+
>>> linked_list.add(2)
40+
>>> linked_list.add(3)
41+
>>> linked_list.add(4, 2)
42+
>>> print(linked_list)
43+
3 --> 2 --> 4 --> 1
44+
45+
# Test adding to a negative position
46+
>>> linked_list.add(5, -3)
47+
Traceback (most recent call last):
48+
...
49+
ValueError: Position must be non-negative
50+
51+
# Test adding to an out-of-bounds position
52+
>>> linked_list.add(5,7)
53+
Traceback (most recent call last):
54+
...
55+
ValueError: Out of bounds
56+
>>> linked_list.add(5, 4)
57+
>>> print(linked_list)
58+
3 --> 2 --> 4 --> 1 --> 5
59+
"""
60+
if position < 0:
61+
raise ValueError("Position must be non-negative")
62+
63+
if position == 0 or self.head is None:
64+
new_node = Node(item, self.head)
65+
self.head = new_node
66+
else:
67+
current = self.head
68+
for _ in range(position - 1):
69+
current = current.next
70+
if current is None:
71+
raise ValueError("Out of bounds")
72+
new_node = Node(item, current.next)
73+
current.next = new_node
2674
self.size += 1
2775

2876
def remove(self) -> Any:

Diff for: maths/polygonal_numbers.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
def polygonal_num(num: int, sides: int) -> int:
2+
"""
3+
Returns the `num`th `sides`-gonal number. It is assumed that `num` >= 0 and
4+
`sides` >= 3 (see for reference https://en.wikipedia.org/wiki/Polygonal_number).
5+
6+
>>> polygonal_num(0, 3)
7+
0
8+
>>> polygonal_num(3, 3)
9+
6
10+
>>> polygonal_num(5, 4)
11+
25
12+
>>> polygonal_num(2, 5)
13+
5
14+
>>> polygonal_num(-1, 0)
15+
Traceback (most recent call last):
16+
...
17+
ValueError: Invalid input: num must be >= 0 and sides must be >= 3.
18+
>>> polygonal_num(0, 2)
19+
Traceback (most recent call last):
20+
...
21+
ValueError: Invalid input: num must be >= 0 and sides must be >= 3.
22+
"""
23+
if num < 0 or sides < 3:
24+
raise ValueError("Invalid input: num must be >= 0 and sides must be >= 3.")
25+
26+
return ((sides - 2) * num**2 - (sides - 4) * num) // 2
27+
28+
29+
if __name__ == "__main__":
30+
import doctest
31+
32+
doctest.testmod()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""
2+
Implements the Scaled Exponential Linear Unit or SELU function.
3+
The function takes a vector of K real numbers and two real numbers
4+
alpha(default = 1.6732) & lambda (default = 1.0507) as input and
5+
then applies the SELU function to each element of the vector.
6+
SELU is a self-normalizing activation function. It is a variant
7+
of the ELU. The main advantage of SELU is that we can be sure
8+
that the output will always be standardized due to its
9+
self-normalizing behavior. That means there is no need to
10+
include Batch-Normalization layers.
11+
References :
12+
https://iq.opengenus.org/scaled-exponential-linear-unit/
13+
"""
14+
15+
import numpy as np
16+
17+
18+
def scaled_exponential_linear_unit(
19+
vector: np.ndarray, alpha: float = 1.6732, lambda_: float = 1.0507
20+
) -> np.ndarray:
21+
"""
22+
Applies the Scaled Exponential Linear Unit function to each element of the vector.
23+
Parameters :
24+
vector : np.ndarray
25+
alpha : float (default = 1.6732)
26+
lambda_ : float (default = 1.0507)
27+
28+
Returns : np.ndarray
29+
Formula : f(x) = lambda_ * x if x > 0
30+
lambda_ * alpha * (e**x - 1) if x <= 0
31+
Examples :
32+
>>> scaled_exponential_linear_unit(vector=np.array([1.3, 3.7, 2.4]))
33+
array([1.36591, 3.88759, 2.52168])
34+
35+
>>> scaled_exponential_linear_unit(vector=np.array([1.3, 4.7, 8.2]))
36+
array([1.36591, 4.93829, 8.61574])
37+
"""
38+
return lambda_ * np.where(vector > 0, vector, alpha * (np.exp(vector) - 1))
39+
40+
41+
if __name__ == "__main__":
42+
import doctest
43+
44+
doctest.testmod()

Diff for: project_euler/problem_070/sol1.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
"""
3131
from __future__ import annotations
3232

33+
import numpy as np
34+
3335

3436
def get_totients(max_one: int) -> list[int]:
3537
"""
@@ -42,17 +44,14 @@ def get_totients(max_one: int) -> list[int]:
4244
>>> get_totients(10)
4345
[0, 1, 1, 2, 2, 4, 2, 6, 4, 6]
4446
"""
45-
totients = [0] * max_one
46-
47-
for i in range(max_one):
48-
totients[i] = i
47+
totients = np.arange(max_one)
4948

5049
for i in range(2, max_one):
5150
if totients[i] == i:
52-
for j in range(i, max_one, i):
53-
totients[j] -= totients[j] // i
51+
x = np.arange(i, max_one, i) # array of indexes to select
52+
totients[x] -= totients[x] // i
5453

55-
return totients
54+
return totients.tolist()
5655

5756

5857
def has_same_digits(num1: int, num2: int) -> bool:

0 commit comments

Comments
 (0)