mirror of
https://github.com/theoludwig/programming-challenges.git
synced 2024-12-08 00:45:29 +01:00
feat(solutions): add reverse-polish-notation/c/function
This commit is contained in:
parent
5f7ba3b5ae
commit
cc8bb07a96
@ -6,7 +6,7 @@ Created by [@Divlo](https://github.com/Divlo) on 29 September 2020.
|
|||||||
|
|
||||||
Your job is to create a calculator which evaluates expressions in Reverse Polish notation (a mathematical notation in which operators follow their operands. It does not need any parentheses as long as each operator has a fixed number of operands).
|
Your job is to create a calculator which evaluates expressions in Reverse Polish notation (a mathematical notation in which operators follow their operands. It does not need any parentheses as long as each operator has a fixed number of operands).
|
||||||
|
|
||||||
For example expression 5 1 2 + 4 / + 3 - (which is equivalent to 5 + ((1 + 2) / 4) - 3 in normal notation) should evaluate to 14.
|
For example expression 5 3 + (which is equivalent to 5 + 3 in normal notation) should evaluate to 8.
|
||||||
|
|
||||||
For your convenience, the input is formatted such that a space is provided between every token.
|
For your convenience, the input is formatted such that a space is provided between every token.
|
||||||
|
|
||||||
@ -16,6 +16,8 @@ Valid operations are +, -, \*, /.
|
|||||||
|
|
||||||
You may assume that there won't be exceptional situations (like stack underflow or division by zero).
|
You may assume that there won't be exceptional situations (like stack underflow or division by zero).
|
||||||
|
|
||||||
|
All the numbers are integers; you don't need to worry about floating point numbers.
|
||||||
|
|
||||||
## Source
|
## Source
|
||||||
|
|
||||||
- [Reverse polish notation - Codewars](https://www.codewars.com/kata/52f78966747862fc9a0009ae)
|
- [Reverse polish notation - Codewars](https://www.codewars.com/kata/52f78966747862fc9a0009ae)
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
# reverse-polish-notation/c/function
|
||||||
|
|
||||||
|
Created by [@Divlo](https://github.com/Divlo) on 12 October 2021.
|
@ -0,0 +1,10 @@
|
|||||||
|
#include "character.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void character_append(char* string, char character) {
|
||||||
|
size_t length = strlen(string);
|
||||||
|
string[length] = character;
|
||||||
|
string[length + 1] = '\0';
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef __CHARACTER__
|
||||||
|
#define __CHARACTER__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append a character to a string, assuming string points to an array
|
||||||
|
* with enough space.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* @param character
|
||||||
|
*/
|
||||||
|
void character_append(char* string, char character);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,19 @@
|
|||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "character.h"
|
||||||
|
|
||||||
|
char* input() {
|
||||||
|
char character;
|
||||||
|
size_t length = 1;
|
||||||
|
char* string = malloc(length * sizeof(char));
|
||||||
|
*string = '\0';
|
||||||
|
while ((character = getchar()) != '\n' && character != EOF) {
|
||||||
|
length++;
|
||||||
|
string = realloc(string, length * sizeof(char));
|
||||||
|
character_append(string, character);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __INPUT__
|
||||||
|
#define __INPUT__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a line from stdin.
|
||||||
|
*
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
char* input();
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,49 @@
|
|||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
bool is_integer(char* string) {
|
||||||
|
size_t string_length = strlen(string);
|
||||||
|
for (size_t index = 0; index < string_length; index++) {
|
||||||
|
if (!isdigit(string[index])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char* string = input();
|
||||||
|
struct Stack* stack = stack_initialization();
|
||||||
|
char* token = strtok(string, " ");
|
||||||
|
while (token != NULL) {
|
||||||
|
if (is_integer(token)) {
|
||||||
|
intptr_t number;
|
||||||
|
sscanf(token, "%ld", &number);
|
||||||
|
stack_push(stack, (void*)number);
|
||||||
|
} else {
|
||||||
|
intptr_t number1 = (intptr_t)stack_pop(stack);
|
||||||
|
intptr_t number2 = (intptr_t)stack_pop(stack);
|
||||||
|
intptr_t result = 0;
|
||||||
|
if (strcmp(token, "+") == 0) {
|
||||||
|
result = number2 + number1;
|
||||||
|
} else if (strcmp(token, "-") == 0) {
|
||||||
|
result = number2 - number1;
|
||||||
|
} else if (strcmp(token, "*") == 0) {
|
||||||
|
result = number2 * number1;
|
||||||
|
} else {
|
||||||
|
result = number2 / number1;
|
||||||
|
}
|
||||||
|
stack_push(stack, (void*)result);
|
||||||
|
}
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
printf("%ld\n", (intptr_t)stack_pop(stack));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct Stack *stack_initialization() {
|
||||||
|
struct Stack *stack = malloc(sizeof(*stack));
|
||||||
|
if (stack == NULL) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
stack->first = NULL;
|
||||||
|
stack->length = 0;
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack_push(struct Stack *stack, void *data) {
|
||||||
|
struct Node *node_new = malloc(sizeof(*node_new));
|
||||||
|
if (stack == NULL || data == NULL) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
node_new->data = data;
|
||||||
|
node_new->next = stack->first;
|
||||||
|
stack->first = node_new;
|
||||||
|
stack->length = stack->length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *stack_pop(struct Stack *stack) {
|
||||||
|
if (stack == NULL) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
struct Node *node = stack->first;
|
||||||
|
void *data = NULL;
|
||||||
|
if (node != NULL) {
|
||||||
|
stack->first = node->next;
|
||||||
|
data = node->data;
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
stack->length = stack->length - 1;
|
||||||
|
return data;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef __STACK__
|
||||||
|
#define __STACK__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// LIFO = Last In First Out
|
||||||
|
struct Stack {
|
||||||
|
struct Node *first;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
void *data;
|
||||||
|
struct Node *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Stack *stack_initialization();
|
||||||
|
|
||||||
|
void stack_push(struct Stack *stack, void *data);
|
||||||
|
|
||||||
|
void *stack_pop(struct Stack *stack);
|
||||||
|
|
||||||
|
#endif
|
@ -1 +1 @@
|
|||||||
3.5
|
1 3 +
|
@ -1 +1 @@
|
|||||||
3.5
|
4
|
@ -1 +1 @@
|
|||||||
1 3 +
|
5 3 *
|
@ -1 +1 @@
|
|||||||
4
|
15
|
@ -1 +1 @@
|
|||||||
1 3 *
|
1 3 -
|
@ -1 +1 @@
|
|||||||
3
|
-2
|
@ -1 +1 @@
|
|||||||
1 3 -
|
10 2 /
|
@ -1 +1 @@
|
|||||||
-2
|
5
|
@ -1 +1 @@
|
|||||||
4 2 /
|
5 3 + 12 8 + * 10 /
|
@ -1 +1 @@
|
|||||||
2
|
16
|
@ -1 +0,0 @@
|
|||||||
5 3 + 12 8 + * 10 /
|
|
@ -1 +0,0 @@
|
|||||||
16
|
|
Loading…
Reference in New Issue
Block a user