Merge branch 'master' into add_codeowners

This commit is contained in:
David Leal 2023-07-02 19:41:38 -06:00 committed by GitHub
commit 56dcbfce22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 507 additions and 68 deletions

View File

@ -92,6 +92,8 @@ jobs:
build:
name: Compile checks
runs-on: ${{ matrix.os }}
permissions:
pull-requests: write
needs: [MainSequence]
strategy:
matrix:
@ -100,5 +102,17 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
- run: cmake -B ./build -S .
- run: cmake --build build
- run: |
cmake -B ./build -S .
cmake --build build
- name: Label on PR fail
uses: actions/github-script@v6
if: ${{ failure() && matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' }}
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['Autochecks are failing']
})

View File

@ -5,8 +5,11 @@ on:
push:
paths:
- "leetcode/src/**.c"
branches:
- master
jobs:
build:
if: github.repository == 'TheAlgorithms/C' # We only need this to run in our repository.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@ -21,17 +24,22 @@ jobs:
- name: Write LeetCode DIRECTORY.md
run: |
python3 scripts/leetcode_directory_md.py 2>&1 | tee leetcode/DIRECTORY.md
- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v4
id: commit-push
with:
commit_message: "docs: updating `leetcode/DIRECTORY.md`"
branch: "leetcode-directory-${{ github.sha }}"
create_branch: true
- name: Creating and merging the PR
- name: Setup Git configurations
shell: bash
if: steps.commit-push.outputs.changes_detected == 'true'
run: |
gh pr create --base ${GITHUB_REF##*/} --head leetcode-directory-${{ github.sha }} --title 'docs: updating `leetcode/DIRECTORY.md`' --body 'Updated LeetCode directory (see the diff. for changes).'
git config --global user.name github-actions[bot]
git config --global user.email 'github-actions@users.noreply.github.com'
- name: Committing changes
shell: bash
run: |
git checkout -b leetcode-directory-${{ github.sha }}
git commit -m "docs: updating `leetcode/DIRECTORY.md`
git push origin leetcode-directory-${{ github.sha }}:leetcode-directory-${{ github.sha }}
- name: Creating the pull request
shell: bash
run: |
if [[ `git status --porcelain` ]]; then
gh pr create --base ${GITHUB_REF##*/} --head leetcode-directory-${{ github.sha }} --title 'docs: updating `leetcode/DIRECTORY.md`' --body 'Updated LeetCode directory (see the diff. for changes).'
fi
env:
GH_TOKEN: ${{ github.token }}

View File

@ -65,6 +65,7 @@ add_subdirectory(process_scheduling_algorithms)
add_subdirectory(numerical_methods)
add_subdirectory(math)
add_subdirectory(cipher)
add_subdirectory(dynamic_programming)
## Configure Doxygen documentation system
cmake_policy(SET CMP0054 NEW)

View File

@ -107,6 +107,7 @@
* [Queue](https://github.com/TheAlgorithms/C/blob/HEAD/data_structures/queue/queue.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/HEAD/data_structures/stack.c)
* Stack
* [Dynamic Stack](https://github.com/TheAlgorithms/C/blob/HEAD/data_structures/stack/dynamic_stack.c)
* [Main](https://github.com/TheAlgorithms/C/blob/HEAD/data_structures/stack/main.c)
* [Parenthesis](https://github.com/TheAlgorithms/C/blob/HEAD/data_structures/stack/parenthesis.c)
* [Stack](https://github.com/TheAlgorithms/C/blob/HEAD/data_structures/stack/stack.c)
@ -238,6 +239,7 @@
* [Qr Decomposition](https://github.com/TheAlgorithms/C/blob/HEAD/numerical_methods/qr_decomposition.c)
* [Qr Eigen Values](https://github.com/TheAlgorithms/C/blob/HEAD/numerical_methods/qr_eigen_values.c)
* [Realtime Stats](https://github.com/TheAlgorithms/C/blob/HEAD/numerical_methods/realtime_stats.c)
* [Secant Method](https://github.com/TheAlgorithms/C/blob/HEAD/numerical_methods/secant_method.c)
* [Simpsons 1 3Rd Rule](https://github.com/TheAlgorithms/C/blob/HEAD/numerical_methods/simpsons_1_3rd_rule.c)
* [Variance](https://github.com/TheAlgorithms/C/blob/HEAD/numerical_methods/variance.c)

View File

@ -1,37 +1,68 @@
/**
* Modified 24/05/2023, Indrranil Pawar
*
* C program that converts a binary number to its decimal equivalent.
* @brief Converts a number from [Binary to Decimal](https://en.wikipedia.org/wiki/Binary-coded_decimal).
* @details
*
* Binary to decimal conversion is a process to convert a number
* having a binary representation to its equivalent decimal representation.
*
* The base of both number systems is different.
* Binary number system is base 2 number system while decimal number system is base 10 number system.
* The numbers used in binary number system are 0 and 1 while decimal number system has numbers from 0 to 9.
* The conversion of binary number to decimal number is done by multiplying
* each digit of the binary number, starting from the rightmost digit, with the power of 2 and adding the result.
*
* @author [Anup Kumar Pawar](https://github.com/AnupKumarPanwar)
* @author [David Leal](https://github.com/Panquesito7)
*/
#include <stdio.h>
#include <stdio.h> /// for IO operations
#include <assert.h> /// for assert
#include <math.h> /// for pow
#include <inttypes.h> /// for uint64_t
int main()
{
int binary_number, decimal_number = 0, temp = 1;
/**
* @brief Converts the given binary number
* to its equivalent decimal number/value.
* @param number The binary number to be converted
* @returns The decimal equivalent of the binary number
*/
int convert_to_decimal(uint64_t number) {
int decimal_number = 0, i = 0;
// Input the binary number
printf("Enter any binary number: ");
scanf("%d", &binary_number);
// Convert binary to decimal
while (binary_number > 0)
{
// Extract the rightmost digit of the binary number
int digit = binary_number % 10;
// Multiply the rightmost digit with the corresponding power of 2 and add to the decimal number
decimal_number += digit * temp;
// Remove the rightmost digit from the binary number
binary_number /= 10;
// Increase the power of 2 for the next digit
temp *= 2;
while (number > 0) {
decimal_number += (number % 10) * pow(2, i);
number = number / 10;
i++;
}
// Output the decimal equivalent
printf("Decimal equivalent: %d\n", decimal_number);
return decimal_number;
}
/**
* @brief Self-test implementations
* @returns void
*/
static void tests() {
assert(convert_to_decimal(111) == 7);
assert(convert_to_decimal(101) == 5);
assert(convert_to_decimal(1010) == 10);
assert(convert_to_decimal(1101) == 13);
assert(convert_to_decimal(100001) == 33);
assert(convert_to_decimal(10101001) == 169);
assert(convert_to_decimal(111010) == 58);
assert(convert_to_decimal(100000000) == 256);
assert(convert_to_decimal(10000000000) == 1024);
assert(convert_to_decimal(101110111) == 375);
printf("All tests have successfully passed!\n");
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
tests(); // run self-test implementations
return 0;
}

View File

@ -30,13 +30,13 @@ int List_length(L list)
{
int n;
for (n = 0; list; list = list->next) n++;
return n;
return n - 1;
}
/* Convert list to array */
void **List_toArray(L list)
{
int i, n = List_length(list);
int i, n = List_length(list) + 1;
void **array = (void **)malloc((n + 1) * sizeof(*array));
for (i = 0; i < n; i++)

View File

@ -0,0 +1,250 @@
/**
* @file
*
* @brief
* Dynamic [Stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)),
* just like Dynamic Array, is a stack data structure whose the length or
* capacity (maximum number of elements that can be stored) increases or
* decreases in real time based on the operations (like insertion or deletion)
* performed on it.
*
* In this implementation, functions such as PUSH, POP, PEEK, show_capacity,
* isempty, and stack_size are coded to implement dynamic stack.
*
* @author [SahilK-027](https://github.com/SahilK-027)
*
*/
#include <assert.h> /// to verify assumptions made by the program and print a diagnostic message if this assumption is false.
#include <inttypes.h> /// to provide a set of integer types with universally consistent definitions that are operating system-independent
#include <stdio.h> /// for IO operations
#include <stdlib.h> /// for including functions involving memory allocation such as `malloc`
/**
* @brief DArrayStack Structure of stack.
*/
typedef struct DArrayStack
{
int capacity, top; ///< to store capacity and top of the stack
int *arrPtr; ///< array pointer
} DArrayStack;
/**
* @brief Create a Stack object
*
* @param cap Capacity of stack
* @return DArrayStack* Newly created stack object pointer
*/
DArrayStack *create_stack(int cap)
{
DArrayStack *ptr;
ptr = (DArrayStack *)malloc(sizeof(DArrayStack));
ptr->capacity = cap;
ptr->top = -1;
ptr->arrPtr = (int *)malloc(sizeof(int) * cap);
printf("\nStack of capacity %d is successfully created.\n", ptr->capacity);
return (ptr);
}
/**
* @brief As this is stack implementation using dynamic array this function will
* expand the size of the stack by twice as soon as the stack is full.
*
* @param ptr Stack pointer
* @param cap Capacity of stack
* @return DArrayStack*: Modified stack
*/
DArrayStack *double_array(DArrayStack *ptr, int cap)
{
int newCap = 2 * cap;
int *temp;
temp = (int *)malloc(sizeof(int) * newCap);
for (int i = 0; i < (ptr->top) + 1; i++)
{
temp[i] = ptr->arrPtr[i];
}
free(ptr->arrPtr);
ptr->arrPtr = temp;
ptr->capacity = newCap;
return ptr;
}
/**
* @brief As this is stack implementation using dynamic array this function will
* shrink the size of stack by twice as soon as the stack's capacity and size
* has significant difference.
*
* @param ptr Stack pointer
* @param cap Capacity of stack
* @return DArrayStack*: Modified stack
*/
DArrayStack *shrink_array(DArrayStack *ptr, int cap)
{
int newCap = cap / 2;
int *temp;
temp = (int *)malloc(sizeof(int) * newCap);
for (int i = 0; i < (ptr->top) + 1; i++)
{
temp[i] = ptr->arrPtr[i];
}
free(ptr->arrPtr);
ptr->arrPtr = temp;
ptr->capacity = newCap;
return ptr;
}
/**
* @brief The push function pushes the element onto the stack.
*
* @param ptr Stack pointer
* @param data Value to be pushed onto stack
* @return int Position of top pointer
*/
int push(DArrayStack *ptr, int data)
{
if (ptr->top == (ptr->capacity) - 1)
{
ptr = double_array(ptr, ptr->capacity);
ptr->top++;
ptr->arrPtr[ptr->top] = data;
}
else
{
ptr->top++;
ptr->arrPtr[ptr->top] = data;
}
printf("Successfully pushed : %d\n", data);
return ptr->top;
}
/**
* @brief The pop function to pop an element from the stack.
*
* @param ptr Stack pointer
* @return int Popped value
*/
int pop(DArrayStack *ptr)
{
if (ptr->top == -1)
{
printf("Stack is empty UNDERFLOW \n");
return -1;
}
int ele = ptr->arrPtr[ptr->top];
ptr->arrPtr[ptr->top] = 0;
ptr->top = (ptr->top - 1);
if ((ptr->capacity) % 2 == 0)
{
if (ptr->top <= (ptr->capacity / 2) - 1)
{
ptr = shrink_array(ptr, ptr->capacity);
}
}
printf("Successfully popped: %d\n", ele);
return ele;
}
/**
* @brief To retrieve or fetch the first element of the Stack or the element
* present at the top of the Stack.
*
* @param ptr Stack pointer
* @return int Top of the stack
*/
int peek(DArrayStack *ptr)
{
if (ptr->top == -1)
{
printf("Stack is empty UNDERFLOW \n");
return -1;
}
return ptr->arrPtr[ptr->top];
}
/**
* @brief To display the current capacity of the stack.
*
* @param ptr Stack pointer
* @return int Current capacity of the stack
*/
int show_capacity(DArrayStack *ptr) { return ptr->capacity; }
/**
* @brief The function is used to check whether the stack is empty or not and
* return true or false accordingly.
*
* @param ptr Stack pointer
* @return int returns 1 -> true OR returns 0 -> false
*/
int isempty(DArrayStack *ptr)
{
if (ptr->top == -1)
{
return 1;
}
return 0;
}
/**
* @brief Used to get the size of the Stack or the number of elements present in
* the Stack.
*
* @param ptr Stack pointer
* @return int size of stack
*/
int stack_size(DArrayStack *ptr) { return ptr->top + 1; }
/**
* @brief Self-test implementations
* @returns void
*/
static void test()
{
DArrayStack *NewStack;
int capacity = 1;
NewStack = create_stack(capacity);
uint64_t arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
printf("\nTesting Empty stack: ");
assert(stack_size(NewStack) == 0);
assert(isempty(NewStack) == 1);
printf("Size of an empty stack is %d\n", stack_size(NewStack));
printf("\nTesting PUSH operation:\n");
for (int i = 0; i < 12; ++i)
{
int topVal = push(NewStack, arr[i]);
printf("Size: %d, Capacity: %d\n\n", stack_size(NewStack),
show_capacity(NewStack));
assert(topVal == i);
assert(peek(NewStack) == arr[i]);
assert(stack_size(NewStack) == i + 1);
assert(isempty(NewStack) == 0);
}
printf("\nTesting POP operation:\n");
for (int i = 11; i > -1; --i)
{
peek(NewStack);
assert(peek(NewStack) == arr[i]);
int ele = pop(NewStack);
assert(ele == arr[i]);
assert(stack_size(NewStack) == i);
}
printf("\nTesting Empty stack size: ");
assert(stack_size(NewStack) == 0);
assert(isempty(NewStack) == 1);
printf("Size of an empty stack is %d\n", stack_size(NewStack));
printf("\nTesting POP operation on empty stack: ");
assert(pop(NewStack) == -1);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
test(); // run self-test implementations
return 0;
}

View File

@ -0,0 +1,18 @@
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. The RELATIVE flag makes it easier to extract an executable's name
# automatically.
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c )
foreach( testsourcefile ${APP_SOURCES} )
string( REPLACE ".c" "" testname ${testsourcefile} ) # File type. Example: `.c`
add_executable( ${testname} ${testsourcefile} )
if(OpenMP_C_FOUND)
target_link_libraries(${testname} OpenMP::OpenMP_C)
endif()
if(MATH_LIBRARY)
target_link_libraries(${testname} ${MATH_LIBRARY})
endif()
install(TARGETS ${testname} DESTINATION "bin/dynamic_programming") # Folder name. Do NOT include `<>`
endforeach( testsourcefile ${APP_SOURCES} )

View File

@ -1,12 +1,15 @@
/**
* @file
* @brief [Longest Common Subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem) algorithm
* @brief [Longest Common
* Subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem)
* algorithm
* @details
* From Wikipedia: The longest common subsequence (LCS) problem is the problem
* of finding the longest subsequence common to all sequences in a set of sequences
* (often just two sequences).
* of finding the longest subsequence common to all sequences in a set of
* sequences (often just two sequences).
* @author [Kurtz](https://github.com/itskurtz)
*/
#include <stdio.h> /* for io operations */
#include <stdlib.h> /* for memory management & exit */
#include <string.h> /* for string manipulation & ooperations */
@ -15,13 +18,13 @@
enum {LEFT, UP, DIAG};
/**
* @breif Computes LCS between s1 and s2 using a dynamic-programming approach
* @param1 s1 first null-terminated string
* @param2 s2 second null-terminated string
* @param3 l1 length of s1
* @param4 l2 length of s2
* @param5 L matrix of size l1 x l2
* @param6 B matrix of size l1 x l2
* @brief Computes LCS between s1 and s2 using a dynamic-programming approach
* @param s1 first null-terminated string
* @param s2 second null-terminated string
* @param l1 length of s1
* @param l2 length of s2
* @param L matrix of size l1 x l2
* @param B matrix of size l1 x l2
* @returns void
*/
void lcslen(const char *s1, const char *s2, int l1, int l2, int **L, int **B) {
@ -31,8 +34,8 @@ void lcslen(const char *s1, const char *s2, int l1, int l2, int **L, int **B) {
/* loop over the simbols in my sequences
save the directions according to the LCS */
for (i = 1; i <= l1; ++i)
for (j = 1; j <= l2; ++j)
for (i = 1; i <= l1; ++i) {
for (j = 1; j <= l2; ++j) {
if (s1[i-1] == s2[j-1]) {
L[i][j] = 1 + L[i-1][j-1];
B[i][j] = DIAG;
@ -44,16 +47,18 @@ void lcslen(const char *s1, const char *s2, int l1, int l2, int **L, int **B) {
else {
L[i][j] = L[i-1][j];
B[i][j] = UP;
}
}
}
}
}
/**
* @breif Builds the LCS according to B using a traceback approach
* @param1 s1 first null-terminated string
* @param2 l1 length of s1
* @param3 l2 length of s2
* @param4 L matrix of size l1 x l2
* @param5 B matrix of size l1 x l2
* @brief Builds the LCS according to B using a traceback approach
* @param s1 first null-terminated string
* @param l1 length of s1
* @param l2 length of s2
* @param L matrix of size l1 x l2
* @param B matrix of size l1 x l2
* @returns lcs longest common subsequence
*/
char *lcsbuild(const char *s1, int l1, int l2, int **L, int **B) {
@ -76,13 +81,18 @@ char *lcsbuild(const char *s1, int l1, int l2, int **L, int **B) {
i = i - 1;
j = j - 1;
}
else if (B[i][j] == LEFT)
j = j - 1;
else
i = i - 1;
else if (B[i][j] == LEFT)
{
j = j - 1;
}
else
{
i = i - 1;
}
}
return lcs;
}
/**
* @brief Self-test implementations
* @returns void
@ -132,9 +142,11 @@ static void test() {
printf("LCS len:%3d\n", L[l1][l2]);
printf("LCS: %s\n", lcs);
free(lcs);
for (j = 0; j <= l1; j++)
free(L[j]), free(B[j]);
free(lcs);
for (j = 0; j <= l1; j++)
{
free(L[j]), free(B[j]);
}
free(L);
free(B);

View File

@ -55,7 +55,7 @@ int matrixChainOrder(int l,const int *p, int *s) {
void printSolution(int l,int *s,int i,int j) {
if(i == j) {
printf("A%d",i);
return
return;
}
putchar('(');
printSolution(l,s,i,s[i * l + j]);

23
leetcode/src/69.c Normal file
View File

@ -0,0 +1,23 @@
//using the binary search method is one of the efficient ones for this problem statement.
int mySqrt(int x){
int start=0;
int end=x;
long long int ans=0;
while(start <= end){
long long int mid=(start+end)/2;
long long int val=mid*mid;
if( val == x){
return mid;
}
//if mid is less than the square root of the number(x) store the value of mid in ans.
if( val < x){
ans = mid;
start = mid+1;
}
//if mid is greater than the square root of the number(x) then ssign the value mid-1 to end.
if( val > x){
end = mid-1;
}
}
return ans;
}

View File

@ -0,0 +1,80 @@
/**
* @file
* @brief [Secant Method](https://en.wikipedia.org/wiki/Secant_method) implementation. Find a
* continuous function's root by using a succession of roots of secant lines to
* approximate it, starting from the given points' secant line.
* @author [Samuel Pires](https://github.com/disnoca)
*/
#include <assert.h> /// for assert
#include <math.h> /// for fabs
#include <stdio.h> /// for io operations
#define TOLERANCE 0.0001 // root approximation result tolerance
#define NMAX 100 // maximum number of iterations
/**
* @brief Continuous function for which we want to find the root
* @param x Real input variable
* @returns The evaluation result of the function using the input value
*/
double func(double x)
{
return x * x - 3.; // x^2 = 3 - solution is sqrt(3)
}
/**
* @brief Root-finding method for a continuous function given two points
* @param x0 One of the starting secant points
* @param x1 One of the starting secant points
* @param tolerance Determines how accurate the returned value is. The returned
* value will be within `tolerance` of the actual root
* @returns `root of the function` if secant method succeed within the
* maximum number of iterations
* @returns `-1` if secant method fails
*/
double secant_method(double x0, double x1, double tolerance)
{
int n = 1; // step counter
while (n++ < NMAX)
{
// calculate secant line root
double x2 = x1 - func(x1) * (x1 - x0) / (func(x1) - func(x0));
// update values
x0 = x1;
x1 = x2;
// return value if it meets tolerance
if (fabs(x1 - x0) < tolerance)
return x2;
}
return -1; // method failed (maximum number of steps exceeded)
}
/**
* @brief Self-test implementations
* @returns void
*/
static void test()
{
// compares root values found by the secant method within the tolerance
assert(secant_method(0.2, 0.5, TOLERANCE) - sqrt(3) < TOLERANCE);
assert(fabs(secant_method(-2, -5, TOLERANCE)) - sqrt(3) < TOLERANCE);
assert(secant_method(-3, 2, TOLERANCE) - sqrt(3) < TOLERANCE);
assert(fabs(secant_method(1, -1.5, TOLERANCE)) - sqrt(3) < TOLERANCE);
printf("All tests have successfully passed!\n");
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
test(); // run self-test implementations
return 0;
}