Skip to content

Commit a5c9904

Browse files
Merge branch 'TheAlgorithms:main' into main
2 parents 4e8ee9f + 712ce48 commit a5c9904

10 files changed

+401
-45
lines changed

DIRECTORY.md

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
* [Catalan Numbers](dynamic_programming/catalan_numbers.nim)
77
* [Viterbi](dynamic_programming/viterbi.nim)
88

9+
## Maths
10+
* [Absolute value](maths/abs.nim)
11+
* [Aliquot sum](maths/aliquot_sum.nim)
12+
* [Bitwise Addition](maths/bitwise_addition.nim)
13+
914
## Strings
1015
* [Check Anagram](strings/check_anagram.nim)
1116

README.md

+29-29
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
1-
<div align="center">
2-
<!-- Title: -->
3-
<a href="https://github.com/TheAlgorithms/">
4-
<img src="https://raw.githubusercontent.com/TheAlgorithms/website/1cd824df116b27029f17c2d1b42d81731f28a920/public/logo.svg" height="100">
5-
</a>
6-
<h1><a href="https://github.com/TheAlgorithms/">The Algorithms</a> - Nim</h1>
7-
<!-- Labels: -->
8-
<!-- First row: -->
9-
<a href="https://gitpod.io/#https://github.com/TheAlgorithms/Nim">
10-
<img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square" height="20" alt="Gitpod Ready-to-Code">
11-
</a>
12-
<a href="https://github.com/TheAlgorithms/Nim/blob/master/CONTRIBUTING.md">
13-
<img src="https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square" height="20" alt="Contributions Welcome">
14-
</a>
15-
<img src="https://img.shields.io/github/repo-size/TheAlgorithms/Nim.svg?label=Repo%20size&style=flat-square" height="20">
16-
<a href="https://the-algorithms.com/discord">
17-
<img src="https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA&style=flat-square" height="20" alt="Discord chat">
18-
</a>
19-
<a href="https://gitter.im/TheAlgorithms">
20-
<img src="https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square" height="20" alt="Gitter chat">
21-
</a>
22-
<!-- Second row: -->
23-
<br>
24-
<!-- Short description: -->
25-
<h3>Algorithms collection implemented in Nim - for education</h3>
26-
</div>
1+
# <a href="https://github.com/TheAlgorithms/">The Algorithms</a> – Nim&nbsp;<img src="https://raw.githubusercontent.com/nim-lang/assets/master/Art/logo-crown.png" height="28px"/><a href="https://github.com/TheAlgorithms/"><img align="right" src="https://raw.githubusercontent.com/TheAlgorithms/website/main/public/logo.svg" height="100"></a>
2+
3+
[![Gitpod Ready-to-Code][badge-gitpod]](https://gitpod.io/#https://github.com/TheAlgorithms/Nim)
4+
[![Contributions Welcome][badge-contributions]](https://github.com/TheAlgorithms/Nim/blob/master/CONTRIBUTING.md)
5+
![Repo size][badge-reposize]
6+
</br>
7+
[![Discord chat][badge-discord]][chat-discord]
8+
[![Gitter chat][badge-gitter]][chat-gitter]
9+
[![Matrix room][badge-matrix]][chat-matrix]
10+
11+
## Algorithms collection implemented in Nim - for education
2712

2813
Implementations are for learning purposes only. They may be less efficient than the implementations in the [Nim standard library](https://nim-lang.org/docs/lib.html) or [Nimble packages](https://nimble.directory/). Use them at your discretion.
2914

3015
## Getting Started
3116

3217
Read through our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
3318

19+
## List of Algorithms
20+
21+
See our [directory](DIRECTORY.md) for easier navigation and a better overview of the project.
22+
23+
You can also browse the implementations on [the website](https://the-algorithms.com/language/nim).
24+
3425
## Community Channels
3526

36-
We are on [Discord](https://the-algorithms.com/discord) and [Gitter](https://gitter.im/TheAlgorithms)! Community channels are a great way for you to ask questions and get help. Please join us!
27+
We are on [Discord](https://the-algorithms.com/discord) and [Gitter][chat-gitter]/[Matrix][chat-matrix]!
3728

38-
## List of Algorithms
29+
Community channels are a great way for you to ask questions and get help. Please join us!
3930

40-
See our [directory](DIRECTORY.md) for easier navigation and a better overview of the project.
31+
<!-- links -->
32+
[chat-discord]: https://the-algorithms.com/discord
33+
[chat-gitter]: https://gitter.im/#TheAlgorithms_community:gitter.im
34+
[chat-matrix]: https://matrix.to/#/#TheAlgorithms_community:gitter.im
35+
[badge-contributions]: https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square
36+
[badge-discord]: https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA&style=flat-square
37+
[badge-matrix]: https://img.shields.io/badge/matrix-TheAlgorithms_community-0dbd8b?logo=matrix
38+
[badge-gitpod]: https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square
39+
[badge-gitter]: https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square
40+
[badge-reposize]: https://img.shields.io/github/repo-size/TheAlgorithms/Nim.svg?label=Repo%20size&style=flat-square

config.nims

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import std/[os, sequtils]
1313
from std/strutils import startsWith, endsWith
1414
from std/strformat import `&`
1515

16+
--mm:arc # TODO: check if still needs to be below imports on Nim > 1.6.12
17+
1618
const IgnorePathPrefixes = ["."]
1719

1820
func isIgnored(path: string): bool =
@@ -27,12 +29,13 @@ iterator modules(dir: string = getCurrentDir()): string =
2729

2830
############ Tasks
2931
task test, "Test everything":
32+
--warning: "BareExcept:off"
3033
--hints: off
3134
var failedUnits: seq[string]
3235

3336
for path in modules():
3437
echo &"Testing {path}:"
35-
try: exec(&"nim --hints:off r \"{path}\"")
38+
try: selfExec(&"-f --warning[BareExcept]:off --hints:off r \"{path}\"")
3639
except OSError:
3740
failedUnits.add(path)
3841
if failedUnits.len > 0:

maths/abs.nim

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
## Absolute value
2+
{.push raises: [].}
3+
import std/strutils
4+
5+
runnableExamples:
6+
assert absVal(-5.1) == 5.1
7+
assert absMin(@[-1, 2, -3]) == 1
8+
assert absMax(@[-1, 2, -3]) == 3
9+
assert signedMinAbs(@[3, -10, -2]) == -2
10+
assert signedMaxAbs(@[3, -10, -2]) == -10
11+
12+
func absVal*[T: SomeFloat](num: T): T =
13+
## Returns the absolute value of a number.
14+
## Use `math.abs <https://nim-lang.org/docs/system.html#abs%2CT>`_ instead!
15+
return if num < 0.0: -num else: num
16+
17+
# Same for Integers but returns a Natural
18+
func absVal*[T: SomeInteger](num: T): Natural = (if num < 0: -num else: num)
19+
20+
func absMin*(x: openArray[int]): Natural {.raises: [ValueError].} =
21+
## Returns the smallest element in absolute value in a sequence.
22+
if x.len == 0:
23+
raise newException(ValueError, """Cannot find absolute minimum
24+
of an empty sequence""".unindent)
25+
result = absVal(x[0])
26+
for i in 1 ..< x.len:
27+
if absVal(x[i]) < result:
28+
result = absVal(x[i])
29+
30+
func absMax*(x: openArray[int]): Natural {.raises: [ValueError].} =
31+
## Returns the largest element in absolute value in a sequence.
32+
if x.len == 0:
33+
raise newException(ValueError, """Cannot find absolute maximum of an empty
34+
sequence""".unindent)
35+
result = absVal(x[0])
36+
for i in 1 ..< x.len:
37+
if absVal(x[i]) > result:
38+
result = absVal(x[i])
39+
40+
func signedMinAbs*(x: openArray[int]): int {.raises: [ValueError].} =
41+
## Returns the first signed element whose absolute value
42+
## is the smallest in a sequence.
43+
if x.len == 0:
44+
raise newException(ValueError, """Cannot find absolute maximum of an empty
45+
sequence""".unindent)
46+
var (min, minAbs) = (x[0], absVal(x[0]))
47+
for n in x:
48+
let nAbs = absVal(n)
49+
if nAbs < minAbs: (min, minAbs) = (n, nAbs)
50+
min
51+
52+
func signedMaxAbs*(x: openArray[int]): int {.raises: [ValueError].} =
53+
## Returns the first signed element whose absolute value
54+
## is the largest in a sequence.
55+
if x.len == 0:
56+
raise newException(ValueError, """Cannot find absolute maximum of an empty
57+
sequence""".unindent)
58+
var (max, maxAbs) = (x[0], absVal(x[0]))
59+
for n in x:
60+
let nAbs = absVal(n)
61+
if nAbs > maxAbs: (max, maxAbs) = (n, nAbs)
62+
max
63+
64+
when isMainModule:
65+
import std/[unittest, random]
66+
randomize()
67+
68+
suite "Check absVal":
69+
test "Check absVal":
70+
check:
71+
absVal(11.2) == 11.2
72+
absVal(5) == 5
73+
absVal(-5.1) == 5.1
74+
absVal(-5) == absVal(5)
75+
absVal(0) == 0
76+
77+
suite "Check absMin":
78+
test "Check absMin":
79+
check:
80+
absMin(@[-1, 2, -3]) == 1
81+
absMin(@[0, 5, 1, 11]) == 0
82+
absMin(@[3, -10, -2]) == 2
83+
absMin([-1, 2, -3]) == 1
84+
absMin([0, 5, 1, 11]) == 0
85+
absMin([3, -10, -2]) == 2
86+
87+
test "absMin on empty sequence raises ValueError":
88+
doAssertRaises(ValueError):
89+
discard absMin(@[])
90+
91+
suite "Check absMax":
92+
test "Check absMax":
93+
check:
94+
absMax(@[0, 5, 1, 11]) == 11
95+
absMax(@[3, -10, -2]) == 10
96+
absMax(@[-1, 2, -3]) == 3
97+
98+
test "`absMax` on empty sequence raises ValueError":
99+
doAssertRaises(ValueError):
100+
discard absMax(@[])
101+
102+
suite "Check signedMinAbs":
103+
test "Check signedMinAbs":
104+
check:
105+
signedMinAbs(@[0, 5, 1, 11]) == 0
106+
signedMinAbs(@[3, -2, 1, -4, 5, -6]) == 1
107+
signedMinAbs(@[3, -2, -1, -4, 5, -6]) == -1
108+
109+
test "Among two minimal elements, the first one is returned":
110+
check signedMinAbs(@[3, -2, 1, -4, 5, -6, -1]) == 1
111+
112+
suite "Check signedMaxAbs":
113+
test "Check signedMaxAbs":
114+
check:
115+
signedMaxAbs(@[3, -2, 1, -4, 5, -6]) == -6
116+
signedMaxAbs(@[0, 5, 1, 11]) == 11
117+
118+
test "signedMaxAbs on empty sequence raises ValueError":
119+
doAssertRaises(ValueError):
120+
discard signedMaxAbs(@[])

maths/aliquot_sum.nim

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Aliquot sum
2+
## In number theory, the aliquot sum s(n) of a positive integer n is the sum of
3+
## all proper divisors of n, that is, all divisors of n other than n itself.
4+
## https://en.wikipedia.org/wiki/Aliquot_sum
5+
6+
runnableExamples:
7+
import std/strformat
8+
const expected = [16, 117]
9+
for i, number in [12, 100].pairs():
10+
let sum = aliquotSum(number)
11+
assert sum == expected[i]
12+
echo fmt"The sum of all the proper divisors of {number} is {sum}"
13+
14+
func aliquotSum*(number: Positive): Natural =
15+
## Returns the sum of all the proper divisors of the number
16+
## Example: aliquotSum(12) = 1 + 2 + 3 + 4 + 6 = 16
17+
result = 0
18+
for divisor in 1 .. (number div 2):
19+
if number mod divisor == 0:
20+
result += divisor
21+
22+
when isMainModule:
23+
import std/unittest
24+
suite "Check aliquotSum":
25+
test "aliquotSum on small values":
26+
var
27+
input = @[1, 2, 9, 12, 27, 100]
28+
expected = @[0, 1, 4, 16, 13, 117]
29+
for i in 0 ..< input.len:
30+
check:
31+
aliquotSum(input[i]) == expected[i]

maths/arc_length.nim

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Arc Length of a Circle
2+
## https://en.wikipedia.org/wiki/Arc_length
3+
import std/math
4+
{.push raises: [].}
5+
6+
func arcLengthDegree(radius: float, angle: float): float =
7+
## Calculate the length of an arc given the `radius` and `angle` in degrees.
8+
return PI * radius * (angle / 180)
9+
10+
func arcLengthRadian(radius: float, angle: float): float =
11+
## Calculate the length of an arc given the `radius` and `angle` in radians.
12+
return radius * angle
13+
14+
when isMainModule:
15+
import std/unittest
16+
const UnitsInLastPlace = 1
17+
suite "Arc Length":
18+
test "radius 5, angle 45":
19+
check almostEqual(arcLengthDegree(5, 45), 3.926990816987241, UnitsInLastPlace)
20+
test "radius 15, angle 120":
21+
check almostEqual(arcLengthDegree(15, 120), 31.41592653589793, UnitsInLastPlace)
22+
test "radius 10, angle 90":
23+
check almostEqual(arcLengthDegree(10, 90), 15.70796326794897, UnitsInLastPlace)
24+
25+
suite "Arc Length":
26+
test "radius 5, angle 45":
27+
check almostEqual(arcLengthRadian(5, degToRad(45.0)), 3.926990816987241,
28+
UnitsInLastPlace)
29+
test "radius 15, angle 120":
30+
check almostEqual(arcLengthRadian(15, degToRad(120.0)), 31.41592653589793,
31+
UnitsInLastPlace)
32+
test "radius 10, angle 90":
33+
check almostEqual(arcLengthRadian(10, degToRad(90.0)), 15.70796326794897,
34+
UnitsInLastPlace)

maths/bitwise_addition.nim

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Bitwise Addition
2+
## Illustrate how to implement addition of integers using bitwise operations
3+
## See https://en.wikipedia.org/wiki/Bitwise_operation#Applications
4+
runnableExamples:
5+
import std/strformat
6+
var
7+
a = 5
8+
b = 6
9+
echo fmt"The sum of {a} and {b} is {add(a,b)}"
10+
11+
func add*(first: int, second: int): int =
12+
## Implementation of addition of integer with `and`, `xor` and `shl`
13+
## boolean operators.
14+
var first = first
15+
var second = second
16+
while second != 0:
17+
var c = first and second
18+
first = first xor second
19+
second = c shl 1
20+
return first
21+
22+
when isMainModule:
23+
import std/unittest
24+
25+
suite "Check addition":
26+
test "Addition of two positive numbers":
27+
check:
28+
add(3, 5) == 8
29+
add(13, 5) == 18
30+
test "Addition of two negative numbers":
31+
check:
32+
add(-7, -2) == -9
33+
add(-321, -0) == -321
34+
test "Addition of one positive and one negative number":
35+
check:
36+
add(-7, 2) == -5
37+
add(-13, 5) == -8
38+
add(13, -5) == 8

nim.cfg

-2
This file was deleted.

0 commit comments

Comments
 (0)