-
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create and populate the Maths directory (#4)
* Add a sample of maths basic algorithms * Update maths/abs.nim Co-authored-by: Zoom <[email protected]> * Use openArray in absMaxSort Co-authored-by: Zoom <[email protected]> * Fix seq->openArray and int->SomeInteger * Use Positive as input instead * Update maths/addition_without_arithmetic.nim Co-authored-by: Pietro Peterlongo <[email protected]> * Name allocation number * [maths/abs] Replace maxAbsSort by signed[Min/Max]Abs * [Aliquot Sum] Add header * Add empty line at end of file * Remove Allocation number since it is a non standard algorithm * Fix titles * Run nimpretty on the files * Rename file and add DIRECTORY.md * abs: Fix variable name * Add export marker Co-authored-by: Zoom <[email protected]> * Add RE block in aliquot sum and improve RE Co-authored-by: Zoom <[email protected]> * Remove MD quotation marks for inline code * Add export marker for RE block * Remove extra ValueError --------- Co-authored-by: Dimitri LESNOFF <[email protected]> Co-authored-by: Zoom <[email protected]> Co-authored-by: Pietro Peterlongo <[email protected]> Co-authored-by: David Leal <[email protected]>
- Loading branch information
1 parent
c83ceae
commit cf013f1
Showing
4 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(@[]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |