Skip to content

Commit

Permalink
feat: Add egyptian fractions example.
Browse files Browse the repository at this point in the history
  • Loading branch information
goloroden committed Oct 28, 2024
1 parent 8762b58 commit fbf0f04
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ So far, the following exercises have been covered:
- [Clever max](./clevermax/) – calculates the maximum of two numbers
- [Cons, Car, Cdr & co.](./cons) – implements a cons cell and the corresponding functions
- [Continous maximum](./continuousmax/) – calculates the maximum of a sliding window
- [Egyptian fractions](./egyptianfractions/) – calculates the "Egyptian Fractions" version of a given fraction
- [Floyd](./floyd/) – implements Floyd's cycle-finding "Tortoise and Hare" algorithm
- [Heap](./heap/) – implements a heap from scratch, without using the built-in `container/heap` package
- [Markov count](./markovcount/) – figures out how often states are reached by a Markov chain
Expand Down
2 changes: 2 additions & 0 deletions egyptianfractions/documentation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package egyptianfractions calculates the "Egyptian Fractions" version of a given fraction
package egyptianfractions
16 changes: 16 additions & 0 deletions egyptianfractions/extend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package egyptianfractions

func Extend(a, b Fraction) (Fraction, Fraction) {
denominator := a.Denominator * b.Denominator

extendedA := Fraction{
Numerator: a.Numerator * b.Denominator,
Denominator: denominator,
}
extendedB := Fraction{
Numerator: b.Numerator * a.Denominator,
Denominator: denominator,
}

return extendedA, extendedB
}
22 changes: 22 additions & 0 deletions egyptianfractions/extend_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package egyptianfractions_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/thenativeweb/codingcircle/egyptianfractions"
)

func TestExtend(t *testing.T) {
fractionA := egyptianfractions.Fraction{1, 3}
fractionB := egyptianfractions.Fraction{4, 7}

extendedFractionA, extendedFractionB :=
egyptianfractions.Extend(fractionA, fractionB)

assert.Equal(t, 7, extendedFractionA.Numerator)
assert.Equal(t, 21, extendedFractionA.Denominator)

assert.Equal(t, 12, extendedFractionB.Numerator)
assert.Equal(t, 21, extendedFractionB.Denominator)
}
27 changes: 27 additions & 0 deletions egyptianfractions/find_egyptian_fractions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package egyptianfractions

import "math"

func FindEgyptianFractions(fraction Fraction) []Fraction {
fractions := []Fraction{}

for fraction.Numerator > 0 {
n := int(math.Ceil(
float64(fraction.Denominator) /
float64(fraction.Numerator)))

partialFraction := Fraction{1, n}

fractions = append(fractions, partialFraction)

extendedFraction, extendedPartialFraction :=
Extend(fraction, partialFraction)

fraction = Reduce(Fraction{
Numerator: extendedFraction.Numerator - extendedPartialFraction.Numerator,
Denominator: extendedFraction.Denominator,
})
}

return fractions
}
34 changes: 34 additions & 0 deletions egyptianfractions/find_egyptian_fractions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package egyptianfractions_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/thenativeweb/codingcircle/egyptianfractions"
)

func TestFindEgyptianFractions(t *testing.T) {
t.Run("returns 1/2 and 1/6 for 2/3", func(t *testing.T) {
fraction := egyptianfractions.Fraction{2, 3}

result := egyptianfractions.FindEgyptianFractions(fraction)

assert.Equal(
t,
[]egyptianfractions.Fraction{{1, 2}, {1, 6}},
result,
)
})

t.Run("returns 1/3, 1/11 and 1/231 for 3/7", func(t *testing.T) {
fraction := egyptianfractions.Fraction{3, 7}

result := egyptianfractions.FindEgyptianFractions(fraction)

assert.Equal(
t,
[]egyptianfractions.Fraction{{1, 3}, {1, 11}, {1, 231}},
result,
)
})
}
6 changes: 6 additions & 0 deletions egyptianfractions/fraction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package egyptianfractions

type Fraction struct {
Numerator int
Denominator int
}
10 changes: 10 additions & 0 deletions egyptianfractions/gcd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package egyptianfractions

func GCD(a, b int) int {
for b != 0 {
remainder := a % b
a = b
b = remainder
}
return a
}
20 changes: 20 additions & 0 deletions egyptianfractions/gcd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package egyptianfractions_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/thenativeweb/codingcircle/egyptianfractions"
)

func TestGCD(t *testing.T) {
t.Run("returns the greatest common divisor if one exists", func(t *testing.T) {
result := egyptianfractions.GCD(8, 12)
assert.Equal(t, 4, result)
})

t.Run("returns 1 if no greatest common divisor exists", func(t *testing.T) {
result := egyptianfractions.GCD(2, 3)
assert.Equal(t, 1, result)
})
}
10 changes: 10 additions & 0 deletions egyptianfractions/reduce.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package egyptianfractions

func Reduce(fraction Fraction) Fraction {
divisor := GCD(fraction.Numerator, fraction.Denominator)

return Fraction{
Numerator: fraction.Numerator / divisor,
Denominator: fraction.Denominator / divisor,
}
}
20 changes: 20 additions & 0 deletions egyptianfractions/reduce_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package egyptianfractions_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/thenativeweb/codingcircle/egyptianfractions"
)

func TestReduce(t *testing.T) {
fraction := egyptianfractions.Fraction{
Numerator: 4,
Denominator: 8,
}

reducedFraction := egyptianfractions.Reduce(fraction)

assert.Equal(t, 1, reducedFraction.Numerator)
assert.Equal(t, 2, reducedFraction.Denominator)
}

0 comments on commit fbf0f04

Please sign in to comment.