Skip to content

Commit

Permalink
Merge branch 'TheAlgorithms:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
SatinWukerORIG authored Jun 27, 2023
2 parents 4e8ee9f + 712ce48 commit a5c9904
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 45 deletions.
5 changes: 5 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
* [Catalan Numbers](dynamic_programming/catalan_numbers.nim)
* [Viterbi](dynamic_programming/viterbi.nim)

## Maths
* [Absolute value](maths/abs.nim)
* [Aliquot sum](maths/aliquot_sum.nim)
* [Bitwise Addition](maths/bitwise_addition.nim)

## Strings
* [Check Anagram](strings/check_anagram.nim)

Expand Down
58 changes: 29 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
<div align="center">
<!-- Title: -->
<a href="https://github.com/TheAlgorithms/">
<img src="https://raw.githubusercontent.com/TheAlgorithms/website/1cd824df116b27029f17c2d1b42d81731f28a920/public/logo.svg" height="100">
</a>
<h1><a href="https://github.com/TheAlgorithms/">The Algorithms</a> - Nim</h1>
<!-- Labels: -->
<!-- First row: -->
<a href="https://gitpod.io/#https://github.com/TheAlgorithms/Nim">
<img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square" height="20" alt="Gitpod Ready-to-Code">
</a>
<a href="https://github.com/TheAlgorithms/Nim/blob/master/CONTRIBUTING.md">
<img src="https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square" height="20" alt="Contributions Welcome">
</a>
<img src="https://img.shields.io/github/repo-size/TheAlgorithms/Nim.svg?label=Repo%20size&style=flat-square" height="20">
<a href="https://the-algorithms.com/discord">
<img src="https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA&style=flat-square" height="20" alt="Discord chat">
</a>
<a href="https://gitter.im/TheAlgorithms">
<img src="https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square" height="20" alt="Gitter chat">
</a>
<!-- Second row: -->
<br>
<!-- Short description: -->
<h3>Algorithms collection implemented in Nim - for education</h3>
</div>
# <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>

[![Gitpod Ready-to-Code][badge-gitpod]](https://gitpod.io/#https://github.com/TheAlgorithms/Nim)
[![Contributions Welcome][badge-contributions]](https://github.com/TheAlgorithms/Nim/blob/master/CONTRIBUTING.md)
![Repo size][badge-reposize]
</br>
[![Discord chat][badge-discord]][chat-discord]
[![Gitter chat][badge-gitter]][chat-gitter]
[![Matrix room][badge-matrix]][chat-matrix]

## Algorithms collection implemented in Nim - for education

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.

## Getting Started

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

## List of Algorithms

See our [directory](DIRECTORY.md) for easier navigation and a better overview of the project.

You can also browse the implementations on [the website](https://the-algorithms.com/language/nim).

## Community Channels

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!
We are on [Discord](https://the-algorithms.com/discord) and [Gitter][chat-gitter]/[Matrix][chat-matrix]!

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

See our [directory](DIRECTORY.md) for easier navigation and a better overview of the project.
<!-- links -->
[chat-discord]: https://the-algorithms.com/discord
[chat-gitter]: https://gitter.im/#TheAlgorithms_community:gitter.im
[chat-matrix]: https://matrix.to/#/#TheAlgorithms_community:gitter.im
[badge-contributions]: https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square
[badge-discord]: https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA&style=flat-square
[badge-matrix]: https://img.shields.io/badge/matrix-TheAlgorithms_community-0dbd8b?logo=matrix
[badge-gitpod]: https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square
[badge-gitter]: https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square
[badge-reposize]: https://img.shields.io/github/repo-size/TheAlgorithms/Nim.svg?label=Repo%20size&style=flat-square
5 changes: 4 additions & 1 deletion config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import std/[os, sequtils]
from std/strutils import startsWith, endsWith
from std/strformat import `&`

--mm:arc # TODO: check if still needs to be below imports on Nim > 1.6.12

const IgnorePathPrefixes = ["."]

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

############ Tasks
task test, "Test everything":
--warning: "BareExcept:off"
--hints: off
var failedUnits: seq[string]

for path in modules():
echo &"Testing {path}:"
try: exec(&"nim --hints:off r \"{path}\"")
try: selfExec(&"-f --warning[BareExcept]:off --hints:off r \"{path}\"")
except OSError:
failedUnits.add(path)
if failedUnits.len > 0:
Expand Down
120 changes: 120 additions & 0 deletions maths/abs.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
## Absolute value
{.push raises: [].}
import std/strutils

runnableExamples:
assert absVal(-5.1) == 5.1
assert absMin(@[-1, 2, -3]) == 1
assert absMax(@[-1, 2, -3]) == 3
assert signedMinAbs(@[3, -10, -2]) == -2
assert signedMaxAbs(@[3, -10, -2]) == -10

func absVal*[T: SomeFloat](num: T): T =
## Returns the absolute value of a number.
## Use `math.abs <https://nim-lang.org/docs/system.html#abs%2CT>`_ instead!
return if num < 0.0: -num else: num

# Same for Integers but returns a Natural
func absVal*[T: SomeInteger](num: T): Natural = (if num < 0: -num else: num)

func absMin*(x: openArray[int]): Natural {.raises: [ValueError].} =
## Returns the smallest element in absolute value in a sequence.
if x.len == 0:
raise newException(ValueError, """Cannot find absolute minimum
of an empty sequence""".unindent)
result = absVal(x[0])
for i in 1 ..< x.len:
if absVal(x[i]) < result:
result = absVal(x[i])

func absMax*(x: openArray[int]): Natural {.raises: [ValueError].} =
## Returns the largest element in absolute value in a sequence.
if x.len == 0:
raise newException(ValueError, """Cannot find absolute maximum of an empty
sequence""".unindent)
result = absVal(x[0])
for i in 1 ..< x.len:
if absVal(x[i]) > result:
result = absVal(x[i])

func signedMinAbs*(x: openArray[int]): int {.raises: [ValueError].} =
## Returns the first signed element whose absolute value
## is the smallest in a sequence.
if x.len == 0:
raise newException(ValueError, """Cannot find absolute maximum of an empty
sequence""".unindent)
var (min, minAbs) = (x[0], absVal(x[0]))
for n in x:
let nAbs = absVal(n)
if nAbs < minAbs: (min, minAbs) = (n, nAbs)
min

func signedMaxAbs*(x: openArray[int]): int {.raises: [ValueError].} =
## Returns the first signed element whose absolute value
## is the largest in a sequence.
if x.len == 0:
raise newException(ValueError, """Cannot find absolute maximum of an empty
sequence""".unindent)
var (max, maxAbs) = (x[0], absVal(x[0]))
for n in x:
let nAbs = absVal(n)
if nAbs > maxAbs: (max, maxAbs) = (n, nAbs)
max

when isMainModule:
import std/[unittest, random]
randomize()

suite "Check absVal":
test "Check absVal":
check:
absVal(11.2) == 11.2
absVal(5) == 5
absVal(-5.1) == 5.1
absVal(-5) == absVal(5)
absVal(0) == 0

suite "Check absMin":
test "Check absMin":
check:
absMin(@[-1, 2, -3]) == 1
absMin(@[0, 5, 1, 11]) == 0
absMin(@[3, -10, -2]) == 2
absMin([-1, 2, -3]) == 1
absMin([0, 5, 1, 11]) == 0
absMin([3, -10, -2]) == 2

test "absMin on empty sequence raises ValueError":
doAssertRaises(ValueError):
discard absMin(@[])

suite "Check absMax":
test "Check absMax":
check:
absMax(@[0, 5, 1, 11]) == 11
absMax(@[3, -10, -2]) == 10
absMax(@[-1, 2, -3]) == 3

test "`absMax` on empty sequence raises ValueError":
doAssertRaises(ValueError):
discard absMax(@[])

suite "Check signedMinAbs":
test "Check signedMinAbs":
check:
signedMinAbs(@[0, 5, 1, 11]) == 0
signedMinAbs(@[3, -2, 1, -4, 5, -6]) == 1
signedMinAbs(@[3, -2, -1, -4, 5, -6]) == -1

test "Among two minimal elements, the first one is returned":
check signedMinAbs(@[3, -2, 1, -4, 5, -6, -1]) == 1

suite "Check signedMaxAbs":
test "Check signedMaxAbs":
check:
signedMaxAbs(@[3, -2, 1, -4, 5, -6]) == -6
signedMaxAbs(@[0, 5, 1, 11]) == 11

test "signedMaxAbs on empty sequence raises ValueError":
doAssertRaises(ValueError):
discard signedMaxAbs(@[])
31 changes: 31 additions & 0 deletions maths/aliquot_sum.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Aliquot sum
## In number theory, the aliquot sum s(n) of a positive integer n is the sum of
## all proper divisors of n, that is, all divisors of n other than n itself.
## https://en.wikipedia.org/wiki/Aliquot_sum

runnableExamples:
import std/strformat
const expected = [16, 117]
for i, number in [12, 100].pairs():
let sum = aliquotSum(number)
assert sum == expected[i]
echo fmt"The sum of all the proper divisors of {number} is {sum}"

func aliquotSum*(number: Positive): Natural =
## Returns the sum of all the proper divisors of the number
## Example: aliquotSum(12) = 1 + 2 + 3 + 4 + 6 = 16
result = 0
for divisor in 1 .. (number div 2):
if number mod divisor == 0:
result += divisor

when isMainModule:
import std/unittest
suite "Check aliquotSum":
test "aliquotSum on small values":
var
input = @[1, 2, 9, 12, 27, 100]
expected = @[0, 1, 4, 16, 13, 117]
for i in 0 ..< input.len:
check:
aliquotSum(input[i]) == expected[i]
34 changes: 34 additions & 0 deletions maths/arc_length.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Arc Length of a Circle
## https://en.wikipedia.org/wiki/Arc_length
import std/math
{.push raises: [].}

func arcLengthDegree(radius: float, angle: float): float =
## Calculate the length of an arc given the `radius` and `angle` in degrees.
return PI * radius * (angle / 180)

func arcLengthRadian(radius: float, angle: float): float =
## Calculate the length of an arc given the `radius` and `angle` in radians.
return radius * angle

when isMainModule:
import std/unittest
const UnitsInLastPlace = 1
suite "Arc Length":
test "radius 5, angle 45":
check almostEqual(arcLengthDegree(5, 45), 3.926990816987241, UnitsInLastPlace)
test "radius 15, angle 120":
check almostEqual(arcLengthDegree(15, 120), 31.41592653589793, UnitsInLastPlace)
test "radius 10, angle 90":
check almostEqual(arcLengthDegree(10, 90), 15.70796326794897, UnitsInLastPlace)

suite "Arc Length":
test "radius 5, angle 45":
check almostEqual(arcLengthRadian(5, degToRad(45.0)), 3.926990816987241,
UnitsInLastPlace)
test "radius 15, angle 120":
check almostEqual(arcLengthRadian(15, degToRad(120.0)), 31.41592653589793,
UnitsInLastPlace)
test "radius 10, angle 90":
check almostEqual(arcLengthRadian(10, degToRad(90.0)), 15.70796326794897,
UnitsInLastPlace)
38 changes: 38 additions & 0 deletions maths/bitwise_addition.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Bitwise Addition
## Illustrate how to implement addition of integers using bitwise operations
## See https://en.wikipedia.org/wiki/Bitwise_operation#Applications
runnableExamples:
import std/strformat
var
a = 5
b = 6
echo fmt"The sum of {a} and {b} is {add(a,b)}"

func add*(first: int, second: int): int =
## Implementation of addition of integer with `and`, `xor` and `shl`
## boolean operators.
var first = first
var second = second
while second != 0:
var c = first and second
first = first xor second
second = c shl 1
return first

when isMainModule:
import std/unittest

suite "Check addition":
test "Addition of two positive numbers":
check:
add(3, 5) == 8
add(13, 5) == 18
test "Addition of two negative numbers":
check:
add(-7, -2) == -9
add(-321, -0) == -321
test "Addition of one positive and one negative number":
check:
add(-7, 2) == -5
add(-13, 5) == -8
add(13, -5) == 8
2 changes: 0 additions & 2 deletions nim.cfg

This file was deleted.

Loading

0 comments on commit a5c9904

Please sign in to comment.