From 544f4927206621f1718d21af8e2acf71112516b1 Mon Sep 17 00:00:00 2001 From: David Leal Date: Wed, 30 Sep 2020 14:40:52 -0500 Subject: [PATCH 01/14] [feat/fix]: Add contributing guidelines and update templates (#610) * feat: Add contributing guidelines * fix: Use the correct links in PR/issue template * fix: Update README.md to point to correct links * fix: Update README.md * fix: Move contributing guidelines to root directory * fix: Update PR template --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + .github/pull_request_template.md | 7 +- CONTRIBUTING.md | 227 +++++++++++++++++++++++++++ README.md | 8 +- 4 files changed, 236 insertions(+), 7 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 6506be17..8d00ac28 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,6 +24,7 @@ assignees: '' ## Steps to Reproduce + 1. 2. 3. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 43ac0a37..882d005a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,9 +1,10 @@ #### Description of Change + #### References @@ -13,10 +14,10 @@ Contributors guide: https://github.com/TheAlgorithms/C-Plus-Plus/CONTRIBUTING.md - [ ] Added description of change -- [ ] Added file name matches [File name guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md#New-File-Name-guidelines) +- [ ] Added file name matches [File name guidelines](https://github.com/TheAlgorithms/C/blob/master/CONTRIBUTING.md#File-Name-guidelines) - [ ] Added tests and example, test must pass - [ ] Relevant documentation/comments is changed or added -- [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md#Commit-Guidelines) +- [ ] PR title follows semantic [commit guidelines](https://github.com/TheAlgorithms/C/blob/master/CONTRIBUTING.md#Commit-Guidelines) - [ ] Search previous suggestions before making a new one, as yours may be a duplicate. - [ ] I acknowledge that all my contributions will be made under the project's license. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..e1f689f1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,227 @@ +# CONTRIBUTION GUIDELINES + +## Before contributing + +Welcome to [TheAlgorithms/C](https://github.com/TheAlgorithms/C)! Before submitting pull requests, please make sure that you have **read the whole guidelines**. If you have any doubts about this contribution guide, please open [an issue](https://github.com/TheAlgorithms/C/issues/new/choose) and clearly state your concerns. + +## Contributing + +### Maintainer/developer + +If you are a maintainer of this repository, please consider the following: + +- It is a protocol to contribute via pull requests. + - Reviewers will advise and guide you up to make the code refined and documented. +- When reviewing pull requests, be sure to: + - Be kind. + - Be respectful. + - Make useful suggestions/comments. + - Be sure not to make invalid suggestions/comments. + - Guide and advise up the pull request author. + +### Contributor + +We are very happy that you consider implementing algorithms and data structures for others! This repository is referred to and used by learners from around the globe. Being one of our contributors, you agree and confirm that: + +- You did your own work. + - No plagiarism allowed. Any plagiarized work will not be merged. +- Your work will be distributed under the [GNU General Public License v3.0](https://github.com/TheAlgorithms/C/blob/master/LICENSE) once your pull request has been merged. +- You submitted work fulfils or mostly fulfils our styles and standards. + +**New implementation** New implementation are welcome! + +**Improving comments** and **adding tests** to existing algorithms are much appreciated. + +**Issues** Please avoid opening issues asking to be "assigned” to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request and it will be evaluated by project maintainers. + +### Making Changes + +#### Code + +- Please use the directory structure of the repository. +- File extension for code should be `*.h` `*.c` +- Organize your code using **`struct`** keywords +- If an implementation of the algorithm already exists, please refer to the [file-name section below](#file-name-guidelines). +- You can suggest reasonable changes to existing algorithms. +- Strictly use snake_case (underscore_separated) in filenames. +- If you have added or modified code, please make sure the code compiles before submitting. +- Our automated testing runs [__CMake__](https://cmake.org/) on all pull requests so please be sure that your code passes before submitting. +- Please conform to [doxygen](https://www.doxygen.nl/manual/docblocks.html) standard and document the code as much as possible. This not only facilitates the readers but also generates the correct info on website. +- **Be consistent in use of these guidelines.** + +#### Documentation + +- Make sure you put useful comments in your code. Do not comment things that are obvious. +- Please avoid creating new directories if at all possible. Try to fit your work into the existing directory structure. If you want to create a new directory, then please check if a similar category has been recently suggested or created by other pull requests. +- If you have modified/added documentation, please ensure that your language is concise and contains no grammar errors. +- Do not update README.md along with other changes, first create an issue and then link to that issue in your pull request to suggest specific changes required to README.md +- The repository follows [Doxygen](https://www.doxygen.nl/manual/docblocks.html) standards and auto-generates the [repository website](https://thealgorithms.github.io/C). Please ensure the code is documented in this structure. Sample implementation is given below. + +#### Test + +- Make sure to add examples and test cases in your main() function. +- If you find any algorithm or document without tests, please feel free to create a pull request or issue describing suggested changes. +- Please try to add one or more `test()` functions that will invoke the algorithm implementation on random test data with expected output. Use `assert()` function to confirm that the tests will pass. Requires adding the `assert.h` library. + +#### Typical structure of a program + +```c +/** + * @file + * @brief Add one line description here + * @details + * This is a multi line + * description containing links, references, + * math equations, etc + * @author [Name](https://github.com/handle) + * @see related_file.c, another_file.c + */ + +#include +#include + +/** + * @brief Struct documentation + */ +struct struct_name { + int variable; ///< short info of this variable + char message; ///< short info +}; + +/** + * Function documentation + * @param param1 one-line info about param1 + * @param param2 one-line info about param2 + * @returns `true` if ... + * @returns `false` if ... + */ +bool func(int param1, int param2) { + // function statements here + if (/*something bad*/) { + return false; + } + + return true; +} + +/** + * @brief Test function + * @returns void + */ +static void test() { + /* desciptions of the following test */ + assert(func(...) == ...); // this ensures that the algorithm works as expected + + // can have multiple checks +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the tests + // code here + return 0; +} +``` + +#### File name guidelines + +- Use lowercase words with ``"_"`` as separator +- For instance + +```markdown +MyNewCStruct.C is incorrect +my_new_c_struct.c is correct format +``` + +- It will be used to dynamically create a directory of files and implementation. +- File name validation will run on docker to ensure the validity. +- If an implementation of the algorithm already exists and your version is different from that implemented, please use incremental numeric digit as a suffix. For example, if `median_search.c` already exists in the `search` folder and you are contributing a new implementation, the filename should be `median_search2.c` and for a third implementation, `median_search3.c`. + +#### Directory guidelines + +- We recommend adding files to existing directories as much as possible. +- Use lowercase words with ``"_"`` as separator ( no spaces or ```"-"``` allowed ) +- For instance + +```markdown +SomeNew Fancy-Category is incorrect +some_new_fancy_category is correct +``` + +- Filepaths will be used to dynamically create a directory of our algorithms. +- Filepath validation will run on GitHub Actions to ensure compliance. + +#### Commit Guidelines + +- It is recommended to keep your changes grouped logically within individual commits. Maintainers find it easier to understand changes that are logically spilt across multiple commits. Try to modify just one or two files in the same directory. Pull requests that span multiple directories are often rejected. + +```bash +git add file_xyz.c +git commit -m "your message" +``` + +Examples of commit messages with semantic prefixes: + +```markdown +fix: xyz algorithm bug +feat: add xyx algorithm, struct xyz +test: add test for xyz algorithm +docs: add comments and explanation to xyz algorithm +``` + +Common prefixes: + +- fix: A bug fix +- feat: A new feature +- docs: Documentation changes +- test: Correct existing tests or add new ones + +### Pull Requests + +- Checkout our [pull request template](https://github.com/TheAlgorithms/C/blob/master/.github/pull_request_template.md) + +#### Building Locally + +Before submitting a pull request, build the code locally or using the convenient [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C) service. + +```bash +cmake -B build -S . +``` + +#### Static Code Analyzer + +We use [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) as a static code analyzer with a configuration in [.clang-tidy](.clang-tidy). + +```bash +clang-tidy --fix --quiet -p build subfolder/file_to_check.c -- +``` + +#### Code Formatter + +[__clang-format__](https://clang.llvm.org/docs/ClangFormat.html) is used for code forrmating. + +- Installation (only needs to be installed once.) + - Mac (using home-brew): `brew install clang-format` + - Mac (using macports): `sudo port install clang-10 +analyzer` + - Windows (MSYS2 64-bit): `pacman -S mingw-w64-x86_64-clang-tools-extra` + - Linux (Debian): `sudo apt-get install clang-format-10 clang-tidy-10` +- Running (all platforms): `clang-format -i -style="file" my_file.c` + +#### GitHub Actions + +- Enable GitHub Actions on your fork of the repository. +After enabling it will execute `clang-tidy` and `clang-format` after every a push (not a commit). + - Click on the tab "Actions", then click on the big green button to enable it. + +![GitHub Actions](https://user-images.githubusercontent.com/51391473/94609466-6e925100-0264-11eb-9d6f-3706190eab2b.png) + +- The result can create another commit if the actions made any changes on your behalf. +- Hence, it is better to wait and check the results of GitHub Actions after every push. +- Run `git pull` in your local clone if these actions made many changes in order to avoid merge conflicts. + +Most importantly, + +- Happy coding! diff --git a/README.md b/README.md index c05dc4bb..b7ca052f 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,23 @@ [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C) -[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C/context:cpp) +[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C/context:cpp) [![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms) -[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md) +[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)](https://github.com/TheAlgorithms/C/blob/master/CONTRIBUTING.md) ![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C?color=red&style=flat-square) [![Doxygen CI](https://github.com/TheAlgorithms/C/workflows/Doxygen%20CI/badge.svg)](https://TheAlgorithms.github.io/C) [![Awesome CI](https://github.com/TheAlgorithms/C/workflows/Awesome%20CI%20Workflow/badge.svg)](https://github.com/TheAlgorithms/C/actions?query=workflow%3A%22Awesome+CI+Workflow%22) ## Overview -The repository is a collection of open-source implementation of a variety of algorithms implemented in C and licensed under [GPLv3 License](https://github.com/TheAlgorithms/C/blob/master/LICENSE). The algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. +The repository is a collection of open-source implementation of a variety of algorithms implemented in C and licensed under [GPLv3 License](https://github.com/TheAlgorithms/C/blob/master/LICENSE). The algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. ## Features * The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C](https://en.wikipedia.org/wiki/C_(programming_language)). * Well documented source code with detailed explanations provide a valuable resource for educators and students alike. * Each source code is atomic using standard C library [`libc`](https://en.wikipedia.org/wiki/C_standard_library) and _no external libraries_ are required for their compilation and execution. Thus the fundamentals of the algorithms can be studied in much depth. -* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively. +* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively. * Strict adherence to [C11](https://en.wikipedia.org/wiki/C11_(C_standard_revision)) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc. with little to no changes. * Self-checks within programs ensure correct implementations with confidence. * Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications. From af6de4b7d44e81b39297740cbb0739d0e3f1bf45 Mon Sep 17 00:00:00 2001 From: Shezza221b <41204318+Shezza221b@users.noreply.github.com> Date: Thu, 1 Oct 2020 19:04:03 +0530 Subject: [PATCH 02/14] Update stack.c (#617) --- data_structures/stack.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data_structures/stack.c b/data_structures/stack.c index 026ca525..0bae7c52 100644 --- a/data_structures/stack.c +++ b/data_structures/stack.c @@ -13,6 +13,9 @@ //////////////////////////////////////////////////////////////////////////////// // DATA STRUCTURES +/** + * creating a stucture with 'data'(type:int), two pointers 'next','pre' (type: struct node) . + */ struct node { int data; From 6f385ed4a41db5128d8bcbfebb0721a8ed3dbf29 Mon Sep 17 00:00:00 2001 From: devraj4522 <55313450+devraj4522@users.noreply.github.com> Date: Thu, 1 Oct 2020 19:58:19 +0530 Subject: [PATCH 03/14] Update queue.c (#622) --- data_structures/queue.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/queue.c b/data_structures/queue.c index 231faf7e..b8f600ca 100644 --- a/data_structures/queue.c +++ b/data_structures/queue.c @@ -52,14 +52,14 @@ void enque(int x) { if (head == NULL) { - head = (struct node *)malloc(1 * sizeof(struct node)); + head = (struct node *)malloc(sizeof(struct node)); head->data = x; head->pre = NULL; tail = head; } else { - tmp = (struct node *)malloc(1 * sizeof(struct node)); + tmp = (struct node *)malloc(sizeof(struct node)); tmp->data = x; tmp->next = tail; tail = tmp; @@ -92,4 +92,4 @@ int deque() /** * Returns the size of the Queue. */ -int size() { return count; } \ No newline at end of file +int size() { return count; } From d3bb124b90f3f7aaa404ea1e59d21d6e667d64b7 Mon Sep 17 00:00:00 2001 From: Shezza221b <41204318+Shezza221b@users.noreply.github.com> Date: Thu, 1 Oct 2020 22:49:55 +0530 Subject: [PATCH 04/14] docs: Minor documentation improvements (data_structures/queue.c) (#616) --- data_structures/queue.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data_structures/queue.c b/data_structures/queue.c index b8f600ca..35020037 100644 --- a/data_structures/queue.c +++ b/data_structures/queue.c @@ -8,7 +8,10 @@ //////////////////////////////////////////////////////////////////////////////// // DATA STRUCTURES -struct node +/** + * Defining the structure of the node which contains 'data' (type : integer), two pointers 'next' and 'pre' (type : struct node). + */ +struct node { int data; struct node *next; From 812702ff45db3a51ee9571a1f7953d3244c70c52 Mon Sep 17 00:00:00 2001 From: David Leal Date: Thu, 1 Oct 2020 23:45:26 -0500 Subject: [PATCH 05/14] [fix/feat]: Added Code of Conduct --- CODE_OF_CONDUCT.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..535cbef3 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at 1anuppanwar@gmail.com, dynamitechetan@gmail.com, nikhilkala8@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see + From a050a48bfd622d100981d3f23932b3f648b401e2 Mon Sep 17 00:00:00 2001 From: Vishnu P <36571320+vishnu0pothan@users.noreply.github.com> Date: Fri, 2 Oct 2020 17:46:27 +0530 Subject: [PATCH 06/14] Added octal to binary conversion (#629) * Added octal to binary conversion * Update conversions/octal_to_binary.c Co-authored-by: David Leal * Update conversions/octal_to_binary.c Co-authored-by: David Leal * Changes updated * To trigger action * updating DIRECTORY.md * LGTM alert fixed. Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + conversions/octal_to_binary.c | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 conversions/octal_to_binary.c diff --git a/DIRECTORY.md b/DIRECTORY.md index f54d8fac..40588688 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -18,6 +18,7 @@ * [Decimal To Octal Recursion](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal_recursion.c) * [Hexadecimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal.c) * [Int To String](https://github.com/TheAlgorithms/C/blob/master/conversions/int_to_string.c) + * [Octal To Binary](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_binary.c) * [Octal To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_decimal.c) * [To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/to_decimal.c) diff --git a/conversions/octal_to_binary.c b/conversions/octal_to_binary.c new file mode 100644 index 00000000..51fd393b --- /dev/null +++ b/conversions/octal_to_binary.c @@ -0,0 +1,62 @@ +/** + * @brief Octal to binay conversion by scanning user input + * @details + * The octalTobinary function take the octal number as long + * return a long binary nuber after conversion + * @author [Vishnu P](https://github.com/vishnu0pothan) + */ +#include +#include + +/** + * @brief Converet octal number to binary + * @param octalnum octal value that need to convert + * @returns A binary number after conversion + */ +long octalToBinary(int octalnum) +{ + int decimalnum = 0, i = 0; + long binarynum = 0; + + /* This loop converts octal number "octalnum" to the + * decimal number "decimalnum" + */ + while(octalnum != 0) + { + decimalnum = decimalnum + (octalnum%10) * pow(8,i); + i++; + octalnum = octalnum / 10; + } + + //i is re-initialized + i = 1; + + /* This loop converts the decimal number "decimalnum" to the binary + * number "binarynum" + */ + while (decimalnum != 0) + { + binarynum = binarynum + (long)(decimalnum % 2) * i; + decimalnum = decimalnum / 2; + i = i * 10; + } + + //Returning the binary number that we got from octal number + return binarynum; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() +{ + int octalnum; + + printf("Enter an octal number: "); + scanf("%d", &octalnum); + + //Calling the function octaltoBinary + printf("Equivalent binary number is: %ld", octalToBinary(octalnum)); + return 0; +} From bad50992fd4b9cef9738993c23ce826473e835c1 Mon Sep 17 00:00:00 2001 From: vinayak Date: Fri, 16 Oct 2020 18:31:45 +0530 Subject: [PATCH 07/14] insertion_sort_recursive (#647) * insertion_sort_recursive * feat: add insertion sort recursive algorithm * Update sorting/insertion_sort_recursive.c Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update sorting/insertion_sort_recursive.c Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update insertion_sort_recursive.c * Update sorting/insertion_sort_recursive.c Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update sorting/insertion_sort_recursive.c Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update sorting/insertion_sort_recursive.c Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- sorting/insertion_sort_recursive.c | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 sorting/insertion_sort_recursive.c diff --git a/sorting/insertion_sort_recursive.c b/sorting/insertion_sort_recursive.c new file mode 100644 index 00000000..ff79ea2b --- /dev/null +++ b/sorting/insertion_sort_recursive.c @@ -0,0 +1,71 @@ +/** + * @file + * @brief [Insertion sort](https://en.wikipedia.org/wiki/Insertion_sort) + * algorithm implementation. + */ +#include +#include +#include +#include + +/** + * @addtogroup sorting Sorting algorithms + * @{ + */ +/** + * Insertion sort algorithm implements using Recursion + * @param arr array to be sorted + * @param size size of array + */ +void RecursionInsertionSort(int *arr, int size) +{ + if(size <= 0) + { + return; + } + + // marking recursive call to reach starting element + RecursionInsertionSort(arr,size-1); + + int key = arr[size-1]; + int j = size-2; + // swapping logic for insertion sort + while(j >= 0 && arr[j] > key) + { + arr[j+1] = arr[j]; + j--; + } + arr[j+1] = key; +} +/** @} */ +/** Test function + * @returns None + */ +static void test() +{ + const int size = rand() % 500; /* random array size */ + int *arr = (int *)calloc(size, sizeof(int)); + + /* generate size random numbers from -50 to 49 */ + for (int i = 0; i < size; i++) + { + arr[i] = (rand() % 100) - 50;/* signed random numbers */ + } + RecursionInsertionSort(arr, size); + for (int i = 0; i < size ; ++i) + { + assert(arr[i] <= arr[i + 1]); + } + free(arr); +} + +/** Main function + * @returns integer 0 + */ +int main(int argc, const char *argv[]) +{ + /* Intializes random number generator */ + srand(time(NULL)); + test(); + return 0; +} From d0d67ff78984de4752a1ed0100c83b8f57b860f4 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Fri, 16 Oct 2020 13:02:49 +0000 Subject: [PATCH 08/14] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 40588688..e9c9426f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -366,6 +366,7 @@ * [Gnome Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/gnome_sort.c) * [Heap Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/heap_sort.c) * [Insertion Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort.c) + * [Insertion Sort Recursive](https://github.com/TheAlgorithms/C/blob/master/sorting/insertion_sort_recursive.c) * [Merge Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/merge_sort.c) * [Merge Sort Nr](https://github.com/TheAlgorithms/C/blob/master/sorting/merge_sort_nr.c) * [Multikey Quick Sort](https://github.com/TheAlgorithms/C/blob/master/sorting/multikey_quick_sort.c) From a24d17f57e6d0e439752d68acdc1ba75202cfa32 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:02:04 -0400 Subject: [PATCH 09/14] feat: guidelines for reviewers (#671) --- REVIEWER_CODE.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 REVIEWER_CODE.md diff --git a/REVIEWER_CODE.md b/REVIEWER_CODE.md new file mode 100644 index 00000000..933d43e6 --- /dev/null +++ b/REVIEWER_CODE.md @@ -0,0 +1,13 @@ +# Guidelines for reviewers and maintainers + +Following are some guidelines for contributors who are providing reviews to the pull-requests. + +1. On any given pull-request, there only one reviewer should be active at a time. Once the reviewer is done, others may add short comments or any further reviews as needed. Again, one at a time. +2. Assigning reviewers should be avoided unless the pull-request is for a particular task the reviewer is more proficient in. +3. Any contributor who has had their code merged into the repo can provide with reviews as they have gone through the repo standards at least once before. The reviewer will be on a first-come-first serve basis. +4. Most repositories have a check-list in the description for pull-requests. Many times, the contributors are not following them and simply remove the checklist or checkthem without taking the time to review the checklist items. These contributors are almost always copying the code from somewhere. These should be pointed out politely and reviews should be blocked until the contributor updates the basic code structure per the checklist and the repo standards. +5. The reviewers should label every pull-request appropriately - including "invalid" as the case may be. +6. Some pull-requests have existing duplicate code or duplicate pull-requests or sometimes, a novice might create a new pull-request for every new commit. This is a daunting task but one of the responsibility of a reviewer. +7. Discourage creating branches on the repo but rather fork the repo to the respective userspace and contribute from that fork. +8. Some repos - C & C++ - have collaboration with GitPod wherein the code and the contribution can be executed and tested online with relative simplicity. It also contains tools necessary to perform debug and CI checks without installing any tools. Encourage contributors to utilize the feature. Reviewers can test the contributed algorithms online without worrying about forks and branches. +9. There should not be any hurry to merge pull-requests. Since the repos are educational, better to get the contributions right even if it takes a bit longer to review. Encourage patience and develop debugging skills of contributors. From adcbc39e3c1cf6fecff71442b68f01dc57346d19 Mon Sep 17 00:00:00 2001 From: Lza-etc <68897171+Lza-etc@users.noreply.github.com> Date: Tue, 20 Oct 2020 04:01:01 +0530 Subject: [PATCH 10/14] Rename CircularLinkedList.C to circular_linked_list.c (#679) --- .../linked_list/{CircularLinkedList.C => circular_linked_list.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename data_structures/linked_list/{CircularLinkedList.C => circular_linked_list.c} (100%) diff --git a/data_structures/linked_list/CircularLinkedList.C b/data_structures/linked_list/circular_linked_list.c similarity index 100% rename from data_structures/linked_list/CircularLinkedList.C rename to data_structures/linked_list/circular_linked_list.c From d6abe9fbbf1d2cc03691842143a9297ba0b1064d Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 19 Oct 2020 22:31:51 +0000 Subject: [PATCH 11/14] updating DIRECTORY.md --- DIRECTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index e9c9426f..29c21461 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -70,7 +70,7 @@ * [Min Heap](https://github.com/TheAlgorithms/C/blob/master/data_structures/heap/min_heap.c) * Linked List * [Ascendingpriorityqueue](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/ascendingpriorityqueue.c) - * [Circularlinkedlist](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/CircularLinkedList.C) + * [Circular Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/circular_linked_list.c) * [Merge Linked Lists](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/merge_linked_lists.c) * [Middle Element In List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/middle_element_in_list.c) * [Queue Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/queue_linked_list.c) From 74e81de85ab2ecf4ef5ec60593f50a516f9afc59 Mon Sep 17 00:00:00 2001 From: Gabriel Mota Bromonschenkel Lima Date: Tue, 20 Oct 2020 13:50:48 -0300 Subject: [PATCH 12/14] Doubly linked list, simple code. (#673) * Doubly linked list, simple code. #633 * organizing code a bit more * add link in DIRECTORY.md and more comments/cleaning. * remove global variables and redundancy. * add Wikipedia reference * add documentation comments in all functions/headers * add update in file brief Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * remove part of file @details Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- DIRECTORY.md | 1 + .../linked_list/doubly_linked_list.c | 293 ++++++++++++++++++ 2 files changed, 294 insertions(+) create mode 100644 data_structures/linked_list/doubly_linked_list.c diff --git a/DIRECTORY.md b/DIRECTORY.md index 29c21461..ecd19b0a 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -71,6 +71,7 @@ * Linked List * [Ascendingpriorityqueue](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/ascendingpriorityqueue.c) * [Circular Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/circular_linked_list.c) + * [Doubly Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/doubly_linked_list.c) * [Merge Linked Lists](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/merge_linked_lists.c) * [Middle Element In List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/middle_element_in_list.c) * [Queue Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/queue_linked_list.c) diff --git a/data_structures/linked_list/doubly_linked_list.c b/data_structures/linked_list/doubly_linked_list.c new file mode 100644 index 00000000..8a3d9c48 --- /dev/null +++ b/data_structures/linked_list/doubly_linked_list.c @@ -0,0 +1,293 @@ +/** + * @file + * @brief Implementation of [Doubly linked list](https://en.wikipedia.org/wiki/Doubly_linked_list) + * @details + * A doubly linked list is a data structure with a sequence + * of components called nodes. Within that nodes there are + * three elements: a value recorded, a pointer to the next + * node, and a pointer to the previous node. + * + * In this implementation, the functions of creating the list, + * inserting by position, deleting by position, searching + * for value, printing the list, and an example of how the + * list works were coded. + * + * @author [Gabriel Mota Bromonschenkel Lima](https://github.com/GabrielMotaBLima) + */ +#include +#include + +/** + * @brief Doubly linked list struct + */ +typedef struct list +{ + double value; ///< value saved on each node + struct list *next, *prev; ///< directing to other nodes or NULL +} List; + +/** + * @brief Create list function, a new list containing one node will be created + * @param value a value to be saved into the first list node + * @returns new_list the list created + */ +List *create(double value); + +/** + * @brief Insertion by position into the list function + * @param list a doubly linked List + * @param value a value to be inserted into the list + * @param pos a position into the list for value insertion + * @returns list the input list with a node more or the same list + */ +List *insert(List *list, double value, int pos); + +/** + * @brief Deletion by position into the list function + * @param list a doubly linked List + * @param pos a position into the list for value Deletion + * @returns list the input list with deleted values or the same list + */ +List *delete(List *list, int pos); + +/** + * @brief Search value into the list function + * @param list a doubly linked list + * @param value a value to be looked for into the list + * @returns `1` if the looked up value exists + * @returns `0` if the looked up value doesn't exist + */ +int search(List *list, double value); + +/** + * @brief Print list function + * @param list a doubly linked List + * @returns void + */ +void print(List *list); + +/** + * @brief Example function + * @returns void + */ +void example(); + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() +{ + // examples for better understanding + example(); + // code here + return 0; +} + +/** + * @brief Create list function, a new list containing one node will be created + * @param value a value to be saved into the first list node + * @returns new_list the list created + */ +List *create(double value) +{ + List *new_list = (List *)malloc(sizeof(List)); + new_list->value = value; + new_list->next = NULL; + new_list->prev = NULL; + return new_list; +} + +/** + * @brief Insertion by position into the list function + * @param list a doubly linked List + * @param value a value to be inserted into the list + * @param pos a position into the list for value insertion + * @returns list the input list with a node more or the same list + */ +List *insert(List *list, double value, int pos) +{ + // list NULL case + if (list == NULL) + { + list = create(value); + return list; + } + + // position existing case + if (pos > 0) + { + List *cpy = list, *tmp = cpy; + int flag = 1, index = 1, size = 0; + + while (tmp != NULL) + { + size++; + tmp = tmp->next; + } + + // first position case + if (pos == 1) + { + List *new_node = create(value); + new_node->next = cpy; + cpy->prev = new_node; + list = new_node; + return list; + } + + // position existing in list range case + if (size + 2 > pos) + { + while (cpy->next != NULL && index < pos) + { + flag++; + index++; + cpy = cpy->next; + } + + List *new_node = (List *)malloc(sizeof(List)); + new_node->value = value; + + // position into list with no poiting for NULL + if (flag == pos) + { + cpy->prev->next = new_node; + new_node->next = cpy; + new_node->prev = cpy->prev; + cpy->prev = new_node; + } + + // last position case + if (flag < pos) + { + new_node->next = cpy->next; + new_node->prev = cpy; + cpy->next = new_node; + } + } + return list; + } +} + +/** + * @brief Deletion by position into the list function + * @param list a doubly linked List + * @param pos a position into the list for value Deletion + * @returns list the input list with deleted values or the same list + */ +List *delete(List *list, int pos) +{ + // list NULL case + if (list == NULL) + return list; + + // position existing case + if (pos > 0) + { + List *cpy = list, *tmp = cpy; + int flag = 1, index = 1, size = 0; + + while (tmp != NULL) + { + size++; + tmp = tmp->next; + } + + // first position case + if (pos == 1) + { + if (size == 1) + return NULL; + cpy = cpy->next; + cpy->prev = NULL; + return cpy; + } + + // position existing in list range case + if (size + 2 > pos) + { + while (cpy->next != NULL && index < pos) + { + flag++; + index++; + cpy = cpy->next; + } + + if (flag == pos) + { + // position into list with no poiting for NULL + if (cpy->next != NULL) + { + cpy->prev->next = cpy->next; + cpy->next->prev = cpy->prev; + } + + // last position case + else + cpy->prev->next = NULL; + } + } + return list; + } +} + +/** + * @brief Search value into the list function + * @param list a doubly linked list + * @param value a value to be looked for into the list + * @returns `1` if the looked up value exists + * @returns `0` if the looked up value doesn't exist + */ +int search(List *list, double value) +{ + if (list == NULL) + return 0; + if (list->value == value) + return 1; + search(list->next, value); +} + +/** + * @brief Print list function + * @param list a doubly linked List + * @returns void + */ +void print(List *list) +{ + if (list != NULL) + { + printf("%f\t", list->value); + print(list->next); + } +} + +/** + * @brief Example function + * @returns void + */ +void example() +{ + List *my_list = NULL; + double node_value = 0; + int searching; + + my_list = create(node_value); + my_list = insert(my_list, 3, 1); + my_list = insert(my_list, 5, 3); + my_list = insert(my_list, 10, 3); + my_list = insert(my_list, 20, 3); + + print(my_list); + searching = search(my_list, 20); + printf("\n%d\n", searching); + + my_list = delete (my_list, 1); + my_list = delete (my_list, 1); + my_list = delete (my_list, 1); + my_list = delete (my_list, 1); + + print(my_list); + searching = search(my_list, 20); + printf("\n%d\n", searching); +} From 778f317e8296f5d7e712e3b6cc096101f6fe6a63 Mon Sep 17 00:00:00 2001 From: Gabriel Mota Bromonschenkel Lima Date: Tue, 20 Oct 2020 13:51:47 -0300 Subject: [PATCH 13/14] Rename redblacktree.c to red_black_tree.c (#684) * Rename redblacktree.c to red_black_tree.c * updating DIRECTORY.md * add renaming avl.c and ascendingpriorityqueue.c * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 6 +++--- data_structures/binary_trees/{avl.c => avl_tree.c} | 0 .../binary_trees/{redblacktree.c => red_black_tree.c} | 0 ...{ascendingpriorityqueue.c => ascending_priority_queue.c} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename data_structures/binary_trees/{avl.c => avl_tree.c} (100%) rename data_structures/binary_trees/{redblacktree.c => red_black_tree.c} (100%) rename data_structures/linked_list/{ascendingpriorityqueue.c => ascending_priority_queue.c} (100%) diff --git a/DIRECTORY.md b/DIRECTORY.md index ecd19b0a..98526b9d 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -28,11 +28,11 @@ * [Carray](https://github.com/TheAlgorithms/C/blob/master/data_structures/array/carray.h) * [Carray Tests](https://github.com/TheAlgorithms/C/blob/master/data_structures/array/carray_tests.c) * Binary Trees - * [Avl](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/avl.c) + * [Avl Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/avl_tree.c) * [Binary Search Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/binary_search_tree.c) * [Create Node](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/create_node.c) * [Recursive Traversals](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/recursive_traversals.c) - * [Redblacktree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/redblacktree.c) + * [Red Black Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/red_black_tree.c) * [Segment Tree](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/segment_tree.c) * [Threaded Binary Trees](https://github.com/TheAlgorithms/C/blob/master/data_structures/binary_trees/threaded_binary_trees.c) * Dictionary @@ -69,7 +69,7 @@ * [Max Heap](https://github.com/TheAlgorithms/C/blob/master/data_structures/heap/max_heap.c) * [Min Heap](https://github.com/TheAlgorithms/C/blob/master/data_structures/heap/min_heap.c) * Linked List - * [Ascendingpriorityqueue](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/ascendingpriorityqueue.c) + * [Ascending Priority Queue](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/ascending_priority_queue.c) * [Circular Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/circular_linked_list.c) * [Doubly Linked List](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/doubly_linked_list.c) * [Merge Linked Lists](https://github.com/TheAlgorithms/C/blob/master/data_structures/linked_list/merge_linked_lists.c) diff --git a/data_structures/binary_trees/avl.c b/data_structures/binary_trees/avl_tree.c similarity index 100% rename from data_structures/binary_trees/avl.c rename to data_structures/binary_trees/avl_tree.c diff --git a/data_structures/binary_trees/redblacktree.c b/data_structures/binary_trees/red_black_tree.c similarity index 100% rename from data_structures/binary_trees/redblacktree.c rename to data_structures/binary_trees/red_black_tree.c diff --git a/data_structures/linked_list/ascendingpriorityqueue.c b/data_structures/linked_list/ascending_priority_queue.c similarity index 100% rename from data_structures/linked_list/ascendingpriorityqueue.c rename to data_structures/linked_list/ascending_priority_queue.c From b8da721481fa8f5bba2fbac51961bab7730bbb54 Mon Sep 17 00:00:00 2001 From: Chayoung You Date: Wed, 21 Oct 2020 11:00:03 +0900 Subject: [PATCH 14/14] feat: Add another hexadecimal to octal conversion (#658) * Add another hexadecimal to octal conversion * Apply suggestions Also changed the return type of `hex_to_oct` to `const char *`, as it returns an address of static variable. * Update comment of hexadecimal_to_octal2.c * updating DIRECTORY.md * Apply suggestions Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + conversions/hexadecimal_to_octal2.c | 119 ++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 conversions/hexadecimal_to_octal2.c diff --git a/DIRECTORY.md b/DIRECTORY.md index 98526b9d..7f1268af 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -17,6 +17,7 @@ * [Decimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal.c) * [Decimal To Octal Recursion](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal_recursion.c) * [Hexadecimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal.c) + * [Hexadecimal To Octal2](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal2.c) * [Int To String](https://github.com/TheAlgorithms/C/blob/master/conversions/int_to_string.c) * [Octal To Binary](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_binary.c) * [Octal To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_decimal.c) diff --git a/conversions/hexadecimal_to_octal2.c b/conversions/hexadecimal_to_octal2.c new file mode 100644 index 00000000..842e8e94 --- /dev/null +++ b/conversions/hexadecimal_to_octal2.c @@ -0,0 +1,119 @@ +/** + * @file + * @brief Convert hexadecimal number to octal number (with decimal intermediary) + * @details + * The input is valid from 0 to 0xFFFF_FFFF_FFFF_FFFF. + * + * At first, this program converts a hex string to an unsigned long long + * decimal, and then to an octal string. + * + * When there is an invalid character in input string, this program stops + * parsing and converts the string until that character. + * + * @see hexadecimal_to_octal.c + */ + +#include /// for printf() and fgets() +#include /// for memset() + +/** + * @brief Convert a hexadecimal number to octal number. + * @param hex Hexadecimal number to convert. + * @returns A pointer to the converted octal string. + */ +const char *hex_to_oct(const char *hex) +{ +#define MAX_OCT_STR_LEN 23 /* 17_7777_7777_7777_7777_7777 */ + static char octal[MAX_OCT_STR_LEN]; + memset(octal, '\0', MAX_OCT_STR_LEN); // Initialize as NULL string + + unsigned long long decimal = 0; + int i = 0; + int len; + + if (hex == NULL) + { + // Return an empty string + return octal; + } + + /* Hexadecimal to decimal conversion */ + while (*hex != '\n' && *hex != '\0') + { + char ch = *hex; + + if (ch >= '0' && ch <= '9') + { + ch -= '0'; + } + else if (ch >= 'a' && ch <= 'f') + { + ch = ch - 'a' + 10; + } + else if (ch >= 'A' && ch <= 'F') + { + ch = ch - 'A' + 10; + } + else + { + printf("Invalid hexadecimal input: %c\n", ch); + break; + } + + decimal *= 16; + decimal += ch; + hex++; + } + + /* Decimal to octal conversion */ + if (decimal == 0) + { + octal[0] = '0'; + len = 1; + } + else + { + i = 0; + while (decimal > 0) + { + octal[i] = '0' + decimal % 8; + i++; + decimal /= 8; + } + + len = i; + } + + octal[len] = '\0'; + + /* Reverse the octal string */ + for (i = 0; i < len / 2; i++) + { + char tmp = octal[i]; + octal[i] = octal[len - i - 1]; + octal[len - i - 1] = tmp; + } + + return octal; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() +{ +#define MAX_HEX_STR_LEN 17 /* FFFF_FFFF_FFFF_FFFF */ + char hex[MAX_HEX_STR_LEN]; + + /* Input hexadecimal number from user */ + printf("Enter any hexadecimal number: "); + fgets(hex, MAX_HEX_STR_LEN, stdin); + + const char *octal = hex_to_oct(hex); + + printf("Hexadecimal number = %s\n", hex); + printf("Octal number = %s\n", octal); + + return 0; +}