init
This commit is contained in:
@@ -0,0 +1,64 @@
|
|||||||
|
# Fibonacci Number Generator (O(1) Runtime)
|
||||||
|
|
||||||
|
This project demonstrates a Fibonacci number generator with O(1) lookup time using a precomputed lookup table approach.
|
||||||
|
|
||||||
|
## Implementation Overview
|
||||||
|
|
||||||
|
The solution uses a **precomputed lookup table** to achieve constant-time access to Fibonacci numbers:
|
||||||
|
|
||||||
|
### Key Features:
|
||||||
|
- **O(1) Runtime**: Accessing any Fibonacci number takes constant time
|
||||||
|
- **Memory Efficient**: Stores only necessary values in memory
|
||||||
|
- **Error Handling**: Validates input indices and handles out-of-range requests
|
||||||
|
- **Windows Compatible**: Uses Windows system calls for console output
|
||||||
|
|
||||||
|
## Approach Explanation
|
||||||
|
|
||||||
|
Instead of calculating Fibonacci numbers through iteration or recursion (which would be O(n) or O(2^n)), this implementation:
|
||||||
|
|
||||||
|
1. Precomputes Fibonacci numbers up to a certain limit (50 numbers in this case)
|
||||||
|
2. Stores them in a lookup table (array)
|
||||||
|
3. Provides constant-time access by simply indexing into the array
|
||||||
|
|
||||||
|
This approach trades memory for speed - we use more memory to store precomputed values, but achieve O(1) lookup time.
|
||||||
|
|
||||||
|
## Files Included
|
||||||
|
|
||||||
|
### 1. fibonacci.asm
|
||||||
|
- AMD64 assembly implementation using Windows syscalls
|
||||||
|
- Uses lookup table for O(1) access
|
||||||
|
- Includes Windows API calls for console output
|
||||||
|
|
||||||
|
### 2. fibonacci.nasm
|
||||||
|
- Alternative NASM version of the Fibonacci generator
|
||||||
|
- Same functionality as the .asm file but with NASM syntax
|
||||||
|
|
||||||
|
### 3. fibonacci.cpp
|
||||||
|
- C++ demonstration showing the same lookup table concept
|
||||||
|
- Easier to compile and run
|
||||||
|
- Demonstrates O(1) access pattern
|
||||||
|
|
||||||
|
## How O(1) is Achieved
|
||||||
|
|
||||||
|
The O(1) runtime comes from:
|
||||||
|
1. **Precomputation**: All Fibonacci numbers are calculated once at compile time
|
||||||
|
2. **Direct Access**: The lookup table allows direct indexing without computation
|
||||||
|
3. **Constant Time Operations**: Array access in memory takes constant time regardless of index
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To run the C++ version (if you have a compiler):
|
||||||
|
```
|
||||||
|
g++ -o fibonacci.exe fibonacci.cpp
|
||||||
|
fibonacci.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
The program will output Fibonacci numbers at various indices, demonstrating that all lookups are O(1) time complexity.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- The lookup table is limited to precomputed values (50 in this case)
|
||||||
|
- For larger indices, a different approach would be needed
|
||||||
|
- Memory usage increases with the number of precomputed values
|
||||||
|
|
||||||
|
This implementation shows how algorithmic design can optimize for specific use cases - trading memory for time complexity when constant-time access is required.
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
@echo off
|
||||||
|
echo Building Fibonacci assembler program...
|
||||||
|
|
||||||
|
; Check if MASM is available
|
||||||
|
if exist "C:\Program Files (x86)\Windows Kits\10\bin\x64\ml64.exe" (
|
||||||
|
echo Assembling with ML64...
|
||||||
|
"C:\Program Files (x86)\Windows Kits\10\bin\x64\ml64.exe" /c fibonacci.asm
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo Linking...
|
||||||
|
link /SUBSYSTEM:CONSOLE fibonacci.obj kernel32.lib user32.lib
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo Build successful!
|
||||||
|
echo Run with: fibonacci.exe
|
||||||
|
) else (
|
||||||
|
echo Linking failed!
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo Assembly failed!
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo ML64 assembler not found. Please ensure Windows SDK is installed.
|
||||||
|
echo You can try using nasm instead:
|
||||||
|
echo nasm -f win64 fibonacci.asm -o fibonacci.obj
|
||||||
|
echo link /SUBSYSTEM:CONSOLE fibonacci.obj kernel32.lib user32.lib
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
@echo off
|
||||||
|
echo Building Fibonacci C++ program...
|
||||||
|
|
||||||
|
echo Compiling with g++...
|
||||||
|
g++ -o fibonacci.exe fibonacci.cpp
|
||||||
|
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo Build successful!
|
||||||
|
echo Run with: fibonacci.exe
|
||||||
|
echo.
|
||||||
|
echo Running the program:
|
||||||
|
fibonacci.exe
|
||||||
|
) else (
|
||||||
|
echo Compile failed!
|
||||||
|
echo Make sure you have a C++ compiler installed (like MinGW or Visual Studio)
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
@echo off
|
||||||
|
echo Building Fibonacci assembler program with NASM...
|
||||||
|
|
||||||
|
if exist "C:\Program Files\NASM\nasm.exe" (
|
||||||
|
echo Assembling with NASM...
|
||||||
|
"C:\Program Files\NASM\nasm.exe" -f win64 fibonacci.nasm -o fibonacci.obj
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo Linking...
|
||||||
|
link /SUBSYSTEM:CONSOLE fibonacci.obj kernel32.lib
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo Build successful!
|
||||||
|
echo Run with: fibonacci.exe
|
||||||
|
) else (
|
||||||
|
echo Linking failed!
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo Assembly failed!
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo NASM assembler not found.
|
||||||
|
echo Please install NASM from https://www.nasm.us/
|
||||||
|
echo Then run: nasm -f win64 fibonacci.nasm -o fibonacci.obj
|
||||||
|
echo And then: link /SUBSYSTEM:CONSOLE fibonacci.obj kernel32.lib
|
||||||
|
)
|
||||||
|
|
||||||
|
pause
|
||||||
+134
@@ -0,0 +1,134 @@
|
|||||||
|
; Fibonacci number generator using AMD64 assembly with Windows syscalls
|
||||||
|
; Uses lookup table for O(1) access
|
||||||
|
; Author: Assistant
|
||||||
|
|
||||||
|
.686p
|
||||||
|
.xmm
|
||||||
|
.model flat, C
|
||||||
|
|
||||||
|
include kernel32.inc
|
||||||
|
include user32.inc
|
||||||
|
|
||||||
|
includelib kernel32.lib
|
||||||
|
includelib user32.lib
|
||||||
|
|
||||||
|
.data
|
||||||
|
; Precomputed Fibonacci numbers (first 50)
|
||||||
|
fib_table DWORD 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
|
||||||
|
fib_table DWORD 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765
|
||||||
|
fib_table DWORD 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040
|
||||||
|
fib_table DWORD 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155
|
||||||
|
fib_table DWORD 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903
|
||||||
|
|
||||||
|
; Error messages
|
||||||
|
msg_error DWORD 'Error: Index out of range', 0
|
||||||
|
msg_success DWORD 'Fibonacci number: ', 0
|
||||||
|
|
||||||
|
; Console handles
|
||||||
|
hStdOut HANDLE ?
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
; Function to get Fibonacci number at index n (0-based)
|
||||||
|
; Input: EAX = index
|
||||||
|
; Output: EAX = Fibonacci number
|
||||||
|
get_fibonacci PROC
|
||||||
|
; Validate input
|
||||||
|
cmp eax, 0
|
||||||
|
jl invalid_input
|
||||||
|
|
||||||
|
; Check if index is within range (max 50)
|
||||||
|
cmp eax, 49
|
||||||
|
jg invalid_input
|
||||||
|
|
||||||
|
; Calculate address in table
|
||||||
|
mov ebx, eax
|
||||||
|
shl ebx, 2 ; Multiply by 4 (DWORD size)
|
||||||
|
|
||||||
|
; Load Fibonacci number from table
|
||||||
|
mov eax, fib_table[ebx]
|
||||||
|
ret
|
||||||
|
|
||||||
|
invalid_input:
|
||||||
|
xor eax, eax ; Return 0 for invalid input
|
||||||
|
ret
|
||||||
|
get_fibonacci ENDP
|
||||||
|
|
||||||
|
; Function to print a number to console
|
||||||
|
print_number PROC
|
||||||
|
; Input: EAX = number to print
|
||||||
|
push eax
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
; Convert number to string and print
|
||||||
|
mov ebx, 10
|
||||||
|
mov ecx, 0 ; Digit count
|
||||||
|
|
||||||
|
; Special case for zero
|
||||||
|
cmp eax, 0
|
||||||
|
jne convert_loop
|
||||||
|
mov ecx, 1
|
||||||
|
jmp print_digits
|
||||||
|
|
||||||
|
convert_loop:
|
||||||
|
cmp eax, 0
|
||||||
|
je print_digits
|
||||||
|
|
||||||
|
xor edx, edx ; Clear high bits
|
||||||
|
div ebx ; Divide by 10
|
||||||
|
push edx ; Push remainder (digit)
|
||||||
|
inc ecx ; Increment digit count
|
||||||
|
jmp convert_loop
|
||||||
|
|
||||||
|
print_digits:
|
||||||
|
cmp ecx, 0
|
||||||
|
je done_printing
|
||||||
|
|
||||||
|
pop eax ; Get digit back
|
||||||
|
add eax, '0' ; Convert to ASCII
|
||||||
|
push eax
|
||||||
|
|
||||||
|
; Write character to console
|
||||||
|
mov edx, esp
|
||||||
|
push 1 ; Number of characters
|
||||||
|
push edx ; Address of character
|
||||||
|
push hStdOut ; Handle
|
||||||
|
call WriteConsoleA
|
||||||
|
|
||||||
|
add esp, 12 ; Clean up stack
|
||||||
|
|
||||||
|
dec ecx
|
||||||
|
jmp print_digits
|
||||||
|
|
||||||
|
done_printing:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
print_number ENDP
|
||||||
|
|
||||||
|
; Main program entry point
|
||||||
|
main PROC
|
||||||
|
; Get console handle
|
||||||
|
push -11 ; STD_OUTPUT_HANDLE
|
||||||
|
call GetStdHandle
|
||||||
|
mov hStdOut, eax
|
||||||
|
|
||||||
|
; Test Fibonacci numbers
|
||||||
|
mov eax, 10 ; Get 11th Fibonacci number (0-indexed)
|
||||||
|
call get_fibonacci
|
||||||
|
|
||||||
|
; Print result
|
||||||
|
push eax
|
||||||
|
call print_number
|
||||||
|
add esp, 4
|
||||||
|
|
||||||
|
; Exit program
|
||||||
|
push 0
|
||||||
|
call ExitProcess
|
||||||
|
main ENDP
|
||||||
|
|
||||||
|
END main
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class FibonacciGenerator {
|
||||||
|
private:
|
||||||
|
static std::vector<long long> fib_table;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// O(1) lookup for Fibonacci numbers
|
||||||
|
static long long getFibonacci(int index) {
|
||||||
|
if (index < 0 || index >= fib_table.size()) {
|
||||||
|
return -1; // Error case
|
||||||
|
}
|
||||||
|
return fib_table[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print Fibonacci number at given index
|
||||||
|
static void printFibonacci(int index) {
|
||||||
|
long long result = getFibonacci(index);
|
||||||
|
if (result == -1) {
|
||||||
|
std::cout << "Error: Index out of range" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Fibonacci number at index " << index << ": " << result << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Precomputed Fibonacci numbers (first 50)
|
||||||
|
std::vector<long long> FibonacciGenerator::fib_table = {
|
||||||
|
1, 1, 2, 3, 5, 8, 13, 21, 34, 55,
|
||||||
|
89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765,
|
||||||
|
10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040,
|
||||||
|
1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155,
|
||||||
|
165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Fibonacci Number Generator (O(1) lookup)" << std::endl;
|
||||||
|
std::cout << "========================================" << std::endl;
|
||||||
|
|
||||||
|
// Test various indices
|
||||||
|
int test_indices[] = {0, 5, 10, 15, 20, 25, 30, 40, 45, 49};
|
||||||
|
int num_tests = sizeof(test_indices) / sizeof(test_indices[0]);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_tests; i++) {
|
||||||
|
FibonacciGenerator::printFibonacci(test_indices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test error case
|
||||||
|
std::cout << "\nTesting error case:" << std::endl;
|
||||||
|
FibonacciGenerator::printFibonacci(50);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
; Fibonacci number generator using AMD64 assembly with Windows syscalls
|
||||||
|
; Uses lookup table for O(1) access
|
||||||
|
; Author: Assistant
|
||||||
|
|
||||||
|
global _main
|
||||||
|
extern _ExitProcess@4
|
||||||
|
extern _GetStdHandle@4
|
||||||
|
extern _WriteConsoleA@16
|
||||||
|
|
||||||
|
section .data
|
||||||
|
; Precomputed Fibonacci numbers (first 50)
|
||||||
|
fib_table dd 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
|
||||||
|
fib_table dd 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765
|
||||||
|
fib_table dd 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040
|
||||||
|
fib_table dd 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155
|
||||||
|
fib_table dd 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903
|
||||||
|
|
||||||
|
; Console handles
|
||||||
|
hStdOut dd 0
|
||||||
|
|
||||||
|
; Error messages
|
||||||
|
msg_error db 'Error: Index out of range', 0
|
||||||
|
msg_success db 'Fibonacci number: ', 0
|
||||||
|
|
||||||
|
section .text
|
||||||
|
; Function to get Fibonacci number at index n (0-based)
|
||||||
|
; Input: RDI = index
|
||||||
|
; Output: RAX = Fibonacci number
|
||||||
|
get_fibonacci:
|
||||||
|
; Validate input
|
||||||
|
cmp rdi, 0
|
||||||
|
jl invalid_input
|
||||||
|
|
||||||
|
; Check if index is within range (max 50)
|
||||||
|
cmp rdi, 49
|
||||||
|
jg invalid_input
|
||||||
|
|
||||||
|
; Calculate address in table
|
||||||
|
mov rax, rdi
|
||||||
|
shl rax, 2 ; Multiply by 4 (DWORD size)
|
||||||
|
|
||||||
|
; Load Fibonacci number from table
|
||||||
|
mov eax, [fib_table + rax]
|
||||||
|
ret
|
||||||
|
|
||||||
|
invalid_input:
|
||||||
|
xor rax, rax ; Return 0 for invalid input
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Function to print a number to console
|
||||||
|
print_number:
|
||||||
|
; Input: RAX = number to print
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
|
||||||
|
; Convert number to string and print
|
||||||
|
mov rbx, 10
|
||||||
|
mov rcx, 0 ; Digit count
|
||||||
|
|
||||||
|
; Special case for zero
|
||||||
|
cmp rax, 0
|
||||||
|
jne convert_loop
|
||||||
|
mov rcx, 1
|
||||||
|
jmp print_digits
|
||||||
|
|
||||||
|
convert_loop:
|
||||||
|
cmp rax, 0
|
||||||
|
je print_digits
|
||||||
|
|
||||||
|
xor rdx, rdx ; Clear high bits
|
||||||
|
div rbx ; Divide by 10
|
||||||
|
push rdx ; Push remainder (digit)
|
||||||
|
inc rcx ; Increment digit count
|
||||||
|
jmp convert_loop
|
||||||
|
|
||||||
|
print_digits:
|
||||||
|
cmp rcx, 0
|
||||||
|
je done_printing
|
||||||
|
|
||||||
|
pop rax ; Get digit back
|
||||||
|
add rax, '0' ; Convert to ASCII
|
||||||
|
push rax
|
||||||
|
|
||||||
|
; Write character to console
|
||||||
|
mov edx, esp
|
||||||
|
push 1 ; Number of characters
|
||||||
|
push edx ; Address of character
|
||||||
|
push dword [hStdOut] ; Handle
|
||||||
|
call _WriteConsoleA@16
|
||||||
|
|
||||||
|
add rsp, 12 ; Clean up stack
|
||||||
|
|
||||||
|
dec rcx
|
||||||
|
jmp print_digits
|
||||||
|
|
||||||
|
done_printing:
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Main program entry point
|
||||||
|
_main:
|
||||||
|
; Get console handle
|
||||||
|
mov rdi, -11 ; STD_OUTPUT_HANDLE
|
||||||
|
call _GetStdHandle@4
|
||||||
|
mov [hStdOut], eax
|
||||||
|
|
||||||
|
; Test Fibonacci numbers
|
||||||
|
mov rdi, 10 ; Get 11th Fibonacci number (0-indexed)
|
||||||
|
call get_fibonacci
|
||||||
|
|
||||||
|
; Print result
|
||||||
|
push rax
|
||||||
|
call print_number
|
||||||
|
add rsp, 8
|
||||||
|
|
||||||
|
; Exit program
|
||||||
|
mov rdi, 0
|
||||||
|
call _ExitProcess@4
|
||||||
Reference in New Issue
Block a user