-
Notifications
You must be signed in to change notification settings - Fork 1
/
Fibonacci.cs
69 lines (60 loc) · 2.2 KB
/
Fibonacci.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using System;
namespace AlgorithmsAndDataStructures.Algorithms.Search
{
public class Fibonacci<T> : ISearchAlgorithm<T> where T : IComparable<T>
{
public int Search(T[] target, T value)
{
if (target is null)
{
return default;
}
var startingFibonacciNumber = 0;
var offset = -1;
while (FibonacciNumber(startingFibonacciNumber) < target.Length)
{
startingFibonacciNumber += 1;
}
while (FibonacciNumber(startingFibonacciNumber) > 1)
{
// Fibonacci number - 2 is ~ 1/3 of Fibonacci number
var splitIndex = Math.Min(offset + FibonacciNumber(startingFibonacciNumber - 2), target.Length - 1);
if (target[splitIndex].CompareTo(value) < 0)
{
// Fibonacci number - 1 is ~ 2/3 of Fibonacci number
startingFibonacciNumber -= 1;
offset = splitIndex;
}
else if (target[splitIndex].CompareTo(value) > 0)
{
// Fibonacci number - 2 is ~ 1/3 of Fibonacci number
startingFibonacciNumber -= 2;
}
else
{
return splitIndex;
}
}
// FibonacciNumber(startingFibonacciNumber) > 0 - check that array is not empty
if (FibonacciNumber(startingFibonacciNumber) > 0 && target[offset + 1].CompareTo(value) == 0)
{
return offset + 1;
}
return -1;
}
// It's not the best idea to generate it on the fly,
// it's better to either pre-generate them or generate them alongside the main loop
private static int FibonacciNumber(int number)
{
if (number < 1)
{
return 0;
}
if (number == 1)
{
return 1;
}
return FibonacciNumber(number - 1) + FibonacciNumber(number - 2);
}
}
}