diff --git a/DIRECTORY.md b/DIRECTORY.md
index 185bae95..15a1b99e 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -76,6 +76,7 @@
   * [Coin Change](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/coin_change.ts)
   * [Knapsack](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/knapsack.ts)
   * [Lcs](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/lcs.ts)
+  * [Sudoku Solver](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/dynamic_programming/sudoku_solver.ts)
 
 ## Graph
   * [Bellman Ford](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/graph/bellman_ford.ts)
@@ -156,6 +157,8 @@
 
 ## Search
   * [Binary Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/binary_search.ts)
+  * [Exponential Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/exponential_search.ts)
+  * [Fibonacci Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/fibonacci_search.ts)
   * [Interpolation Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/interpolation_search.ts)
   * [Jump Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/jump_search.ts)
   * [Linear Search](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/search/linear_search.ts)
diff --git a/dynamic_programming/sudoku_solver.ts b/dynamic_programming/sudoku_solver.ts
new file mode 100644
index 00000000..5135fd08
--- /dev/null
+++ b/dynamic_programming/sudoku_solver.ts
@@ -0,0 +1,39 @@
+const isValid = (
+  board: string[][],
+  row: number,
+  col: number,
+  k: string
+): boolean => {
+  for (let i = 0; i < 9; i++) {
+    const m = 3 * Math.floor(row / 3) + Math.floor(i / 3)
+    const n = 3 * Math.floor(col / 3) + (i % 3)
+    if (board[row][i] === k || board[i][col] === k || board[m][n] === k) {
+      return false
+    }
+  }
+  return true
+}
+
+const sudokuSolver = (data: string[][]): string[][] | null => {
+  for (let i = 0; i < 9; i++) {
+    for (let j = 0; j < 9; j++) {
+      if (data[i][j] === '.') {
+        for (let k = 1; k <= 9; k++) {
+          if (isValid(data, i, j, `${k}`)) {
+            data[i][j] = `${k}`
+            const result = sudokuSolver(data)
+            if (result) {
+              return result
+            } else {
+              data[i][j] = '.'
+            }
+          }
+        }
+        return null
+      }
+    }
+  }
+  return data
+}
+
+export { sudokuSolver }
diff --git a/dynamic_programming/test/sudoku_solver.test.ts b/dynamic_programming/test/sudoku_solver.test.ts
new file mode 100644
index 00000000..adf10fb1
--- /dev/null
+++ b/dynamic_programming/test/sudoku_solver.test.ts
@@ -0,0 +1,44 @@
+import { sudokuSolver } from '../sudoku_solver'
+
+describe('Sudoku Solver', () => {
+  test('should solve sudoku', () => {
+    const data: string[][] = [
+      ['5', '3', '.', '.', '7', '.', '.', '.', '.'],
+      ['6', '.', '.', '1', '9', '5', '.', '.', '.'],
+      ['.', '9', '8', '.', '.', '.', '.', '6', '.'],
+      ['8', '.', '.', '.', '6', '.', '.', '.', '3'],
+      ['4', '.', '.', '8', '.', '3', '.', '.', '1'],
+      ['7', '.', '.', '.', '2', '.', '.', '.', '6'],
+      ['.', '6', '.', '.', '.', '.', '2', '8', '.'],
+      ['.', '.', '.', '4', '1', '9', '.', '.', '5'],
+      ['.', '.', '.', '.', '8', '.', '.', '7', '9']
+    ]
+    const expected: string[][] = [
+      ['5', '3', '4', '6', '7', '8', '9', '1', '2'],
+      ['6', '7', '2', '1', '9', '5', '3', '4', '8'],
+      ['1', '9', '8', '3', '4', '2', '5', '6', '7'],
+      ['8', '5', '9', '7', '6', '1', '4', '2', '3'],
+      ['4', '2', '6', '8', '5', '3', '7', '9', '1'],
+      ['7', '1', '3', '9', '2', '4', '8', '5', '6'],
+      ['9', '6', '1', '5', '3', '7', '2', '8', '4'],
+      ['2', '8', '7', '4', '1', '9', '6', '3', '5'],
+      ['3', '4', '5', '2', '8', '6', '1', '7', '9']
+    ]
+    expect(sudokuSolver(data)).toStrictEqual(expected)
+  })
+
+  test('should return null if sudoku is invalid', () => {
+    const data: string[][] = [
+      ['5', '3', '.', '.', '7', '.', '.', '.', '.'],
+      ['6', '.', '.', '1', '9', '5', '.', '.', '.'],
+      ['.', '9', '8', '.', '6', '.', '.', '6', '.'],
+      ['8', '.', '.', '.', '6', '.', '.', '.', '3'],
+      ['4', '.', '.', '8', '.', '3', '.', '.', '1'],
+      ['7', '.', '.', '.', '2', '.', '.', '.', '6'],
+      ['.', '6', '.', '.', '.', '.', '2', '8', '.'],
+      ['.', '.', '.', '4', '1', '9', '.', '.', '5'],
+      ['.', '.', '.', '.', '8', '.', '.', '7', '9']
+    ]
+    expect(sudokuSolver(data)).toBe(null)
+  })
+})