diff --git a/.github/workflows/check_code_format.yml b/.github/workflows/check_code_format.yml
new file mode 100644
index 0000000..dc11f66
--- /dev/null
+++ b/.github/workflows/check_code_format.yml
@@ -0,0 +1,40 @@
+---
+name: check_code_format
+
+'on':
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ check_format_code:
+ name: check format code
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install fprettify
+ run: pip install fprettify
+
+ - name: Display fprettify version
+ run: fprettify --version
+
+ - name: Format code
+ run: |
+ git clean -f -x -d
+ fprettify --indent 4 --recursive .
+
+ - name: Fail if needs reformatting
+ run: |
+ if [[ $(git status --porcelain) ]]; then
+ echo "please reformat/fprettify these files:"
+ git status --porcelain=v1
+ exit 1
+ fi
+
+ - name: Exact diff of needed reformatting
+ if: failure()
+ run: git diff
+...
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ef62b3a..55a9b27 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,16 @@
cmake_minimum_required(VERSION 3.16)
project(FortranProject LANGUAGES Fortran)
-add_compile_options(-Wall -Wextra -Wpedantic)
+add_compile_options(
+ -Wall
+ -Wextra
+ -Wpedantic
+ -Waliasing
+ -Wconversion-extra
+ -Wimplicit-interface
+ -Wimplicit-procedure
+ -Wsurprising
+ -Werror)
function(add_fortran_sources DIR SOURCES)
file(GLOB_RECURSE NEW_SOURCES "${DIR}/*.f90")
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 9db0263..296bcaf 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -12,6 +12,7 @@
## Searches
* [linear_search](/modules/searches/linear_search.f90)
* [recursive_linear_search](/modules/searches/recursive_linear_search.f90)
+* [ternary_search](/modules/searches/ternary_search_module.f90)
## Sorts
* [bubble_sort](/modules/sorts/bubble_sort.f90)
* [recursive_bubble_sort](/modules/sorts/recursive_bubble_sort.f90)
diff --git a/README.md b/README.md
index c9d2e21..85c152c 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
-
+
diff --git a/examples/searches/example_ternary_search_array_based.f90 b/examples/searches/example_ternary_search_array_based.f90
new file mode 100644
index 0000000..e53ee3b
--- /dev/null
+++ b/examples/searches/example_ternary_search_array_based.f90
@@ -0,0 +1,20 @@
+! Example Program: Array-based Ternary Search
+! This program demonstrates how to use the array-based ternary search algorithm
+! implemented in the `ternary_search` module to find a target element in a sorted array.
+
+program example_ternary_search_array
+ use ternary_search
+ implicit none
+ integer :: result ! Holds the index of the found target
+ integer, dimension(10) :: arr = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] ! Sorted Test Array
+ integer :: target ! Target value to search for
+
+ target = 17
+ result = ternary_search_array(arr, target, 1, size(arr))
+
+ if (result /= -1) then
+ print *, "Target found at index:", result
+ else
+ print *, "Target not found."
+ end if
+end program example_ternary_search_array
diff --git a/examples/searches/example_ternary_search_function_based.f90 b/examples/searches/example_ternary_search_function_based.f90
new file mode 100644
index 0000000..bfa60a2
--- /dev/null
+++ b/examples/searches/example_ternary_search_function_based.f90
@@ -0,0 +1,74 @@
+!> Example Program: Function-based Ternary Search for Minimum and Maximum
+!!
+!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
+!! in Pull Request: #24
+!! https://github.com/TheAlgorithms/Fortran/pull/24
+!!
+!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
+!! addressing bugs/corrections to this file. Thank you!
+!!
+!! This program demonstrates how to use the function-based ternary search algorithm
+!! from the `ternary_search` module to find the minimum and maximum of unimodal functions.
+
+program ternary_search_function_based
+ use ternary_search
+ implicit none
+
+ ! Define the variables
+ integer, parameter :: dp = kind(0.0d0) ! Define double precision kind
+ real(8) :: result_min, result_max ! Results for minimum and maximum values
+ real(8) :: min_point, max_point ! Points where minimum and maximum occur
+ real(8) :: left, right, tol ! Left and right bounds, and tolerance
+
+ interface
+ ! Function with a minimum (example function - defined externally)
+ real(8) function f_min(x)
+ real(8), intent(in) :: x
+ end function f_min
+
+ ! Function with a maximum (example function - defined externally)
+ real(8) function f_max(x)
+ real(8), intent(in) :: x
+ end function f_max
+ end interface
+
+ ! The boundary values can vary depending on the problem context.
+ ! In this example, they are chosen arbitrarily.
+ left = 0.0d0
+ right = 10.0d0
+
+ ! The tolerance value defines how close the left and right bounds must be for the search to terminate.
+ tol = 1.0e-6_dp
+
+ ! Call the ternary search to find the minimum point of f_min
+ min_point = ternary_search_minimum(f_min, left, right, tol)
+ result_min = f_min(min_point)
+
+ ! Call the ternary search to find the maximum point of f_max
+ max_point = ternary_search_maximum(f_max, left, right, tol)
+ result_max = f_max(max_point)
+
+ print *, "Minimum of the function f_min is at x =", min_point, "with value =", result_min
+ print *, "Maximum of the function f_max is at x =", max_point, "with value =", result_max
+
+end program ternary_search_function_based
+
+! Define the unimodal function f_min with a minimum near x = 5.0
+! The quadratic term (x - 5.0)**2 defines a parabola that is concave upward with a minimum at x = 5.0
+! and values increasing as x moves away from 5.
+! The cosine term introduces oscillations, affecting the exact location of the minimum slightly away from 5.0.
+
+real(8) function f_min(x)
+ real(8), intent(in) :: x
+ f_min = (x - 5.0d0)**2 + cos(x) ! Example of a quadratic function with a cosine oscillation
+end function f_min
+
+! Define the unimodal function f_max with a maximum near x = 5.0
+! The quadratic term -(x - 5.0)**2 defines a parabola that is concave downward with a maximum at x = 5.0
+! and values decreasing as x moves away from 5.
+! The cosine term introduces oscillations, affecting the exact location of the maximum slightly away from 5.0.
+
+real(8) function f_max(x)
+ real(8), intent(in) :: x
+ f_max = -(x - 5.0d0)**2 + cos(x) ! Example of a quadratic function with a cosine oscillation
+end function f_max
diff --git a/modules/searches/ternary_search_module.f90 b/modules/searches/ternary_search_module.f90
new file mode 100644
index 0000000..9cd1b67
--- /dev/null
+++ b/modules/searches/ternary_search_module.f90
@@ -0,0 +1,160 @@
+!> Ternary Search Algorithm Module
+!!
+!! This module implements two types of ternary search algorithm: array-based and function-based.
+!!
+!! Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
+!! in Pull Request: #24
+!! https://github.com/TheAlgorithms/Fortran/pull/24
+!!
+!! Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request
+!! addressing bugs/corrections to this file. Thank you!
+!!
+!! The array-based ternary search is used to find a target element within a sorted array, while the function-based
+!! approach is used to find the minimum or maximum of a unimodal function.
+!!
+!! Array-based ternary search:
+!! - Given a sorted array and a target, it splits the array into three parts and recursively searches for the target.
+!!
+!! Function-based ternary search:
+!! - Used for unimodal functions, which have a single peak (maximum) or valley (minimum).
+!! This method divides the function’s search space into thirds to converge on the minimum or maximum.
+!!
+
+module ternary_search
+ implicit none
+contains
+
+ !> Array-based ternary search algorithm
+ !! This recursive function searches for the target value in a sorted array.
+ !!
+ !! Input:
+ !! - arr: The sorted array to search within.
+ !! - target: The value to search for.
+ !! - left, right: The range of indices within which to search.
+ !!
+ !! Output:
+ !! - The index of the target element if found, otherwise -1.
+ recursive integer function ternary_search_array(arr, target, left, right) result(result_index)
+ implicit none
+ integer, intent(in) :: arr(:) ! Array to search within
+ integer, intent(in) :: target ! Target value to search for
+ integer, intent(in) :: left, right ! Left and right indices
+ integer :: mid1, mid2 ! Midpoints
+ integer :: new_left, new_right ! Temporary indices
+
+ ! Base case: if the range is invalid, return -1 (not found)
+ if (right < left) then
+ result_index = -1
+ return
+ end if
+
+ ! Divide array into three parts
+ mid1 = left + (right - left)/3
+ mid2 = right - (right - left)/3
+
+ ! Check if the target is at mid1 or mid2
+ if (arr(mid1) == target) then
+ result_index = mid1
+ return
+ else if (arr(mid2) == target) then
+ result_index = mid2
+ return
+ end if
+
+ ! Recursive search in the appropriate third of the array
+ if (target < arr(mid1)) then
+ new_right = mid1 - 1
+ result_index = ternary_search_array(arr, target, left, new_right)
+ else if (target > arr(mid2)) then
+ new_left = mid2 + 1
+ result_index = ternary_search_array(arr, target, new_left, right)
+ else
+ new_left = mid1 + 1
+ new_right = mid2 - 1
+ result_index = ternary_search_array(arr, target, new_left, new_right)
+ end if
+ end function ternary_search_array
+
+ !> Function-based ternary search to find the minimum of a unimodal function
+ !! This function finds the minimum point of a unimodal function using the ternary search algorithm.
+ !!
+ !! Input:
+ !! - f: The unimodal function to search.
+ !! - left, right: The range within which to search for the minimum.
+ !! - tol: The tolerance to determine convergence.
+ !!
+ !! Output:
+ !! - The point at which the function achieves its minimum value.
+ recursive real(8) function ternary_search_minimum(f, left, right, tol) result(minimum)
+ implicit none
+ interface
+ real(8) function f(x)
+ real(8), intent(in) :: x
+ end function f
+ end interface
+ real(8), intent(in) :: left, right, tol
+ real(8) :: mid1, mid2
+ real(8) :: l, r
+
+ l = left
+ r = right
+
+ ! Termination condition based on tolerance
+ do while (r - l > tol)
+ mid1 = l + (r - l)/3.0d0
+ mid2 = r - (r - l)/3.0d0
+
+ ! Compare function values at midpoints
+ if (f(mid1) < f(mid2)) then
+ r = mid2
+ else
+ l = mid1
+ end if
+ end do
+
+ ! The minimum point is approximately at the midpoint
+ minimum = (l + r)/2.0d0
+ end function ternary_search_minimum
+
+ !> Function-based ternary search to find the maximum of a unimodal function
+ !! This function finds the maximum point of a unimodal function using the ternary search algorithm.
+ !!
+ !! Input:
+ !! - f: The unimodal function to search.
+ !! - left, right: The range within which to search for the maximum.
+ !! - tol: The tolerance to determine convergence.
+ !!
+ !! Output:
+ !! - The point at which the function achieves its maximum value.
+ recursive real(8) function ternary_search_maximum(f, left, right, tol) result(maximum)
+ implicit none
+ interface
+ real(8) function f(x)
+ real(8), intent(in) :: x
+ end function f
+ end interface
+ real(8), intent(in) :: left, right, tol
+ real(8) :: mid1, mid2
+ real(8) :: l, r
+
+ l = left
+ r = right
+
+ ! Termination condition based on tolerance
+ do while (r - l > tol)
+ mid1 = l + (r - l)/3.0d0
+ mid2 = r - (r - l)/3.0d0
+
+ ! Compare function values at midpoints
+ if (f(mid1) > f(mid2)) then
+ r = mid2
+ else
+ l = mid1
+ end if
+ end do
+
+ ! The maximum point is approximately at the midpoint
+ maximum = (l + r)/2.0d0
+ end function ternary_search_maximum
+
+end module ternary_search