Update 'sk1/program.c'
This commit is contained in:
parent
621105b2f0
commit
48c03ecf41
316
sk1/program.c
316
sk1/program.c
@ -1,178 +1,172 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct node{
|
enum action {TUK, INK, DEK, BREK, GLEK, PUK, KUK, op, cl, FUK};
|
||||||
struct node* children[256];
|
|
||||||
unsigned char size;
|
|
||||||
unsigned char character;
|
|
||||||
unsigned char pos;
|
|
||||||
|
|
||||||
//Not used in encoding
|
|
||||||
struct node* parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct node* node;
|
void run_tukafuk(const char* code);
|
||||||
|
int convert_code(enum action* commands, const char* code);
|
||||||
void compress(FILE* in, FILE* out);
|
void run_code(enum action* commands, int size);
|
||||||
void decompress(FILE* in, FILE* out);
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
if(argc < 4){
|
|
||||||
printf("Choose option and files!\n");
|
if(argc < 2){
|
||||||
printf("Options:\n\tc for compress\n\td for decompress\n");
|
printf("Please provide file with source code\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* in = fopen(argv[2], "r");
|
char commands[999999];
|
||||||
FILE* out = fopen(argv[3], "w");
|
|
||||||
|
|
||||||
if(argv[1][0] == 'c'){
|
FILE* file = fopen(argv[1], "r");
|
||||||
compress(in, out);
|
fread(commands, 1, 999999, file);
|
||||||
|
|
||||||
|
run_tukafuk(commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_tukafuk(const char* code){
|
||||||
|
enum action *commands = calloc(999999, sizeof(enum action));
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
int size = convert_code(commands, code);
|
||||||
|
|
||||||
|
run_code(commands, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_code(enum action* commands, int size){
|
||||||
|
char memory[1000] = {0};
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
int ended = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
if(commands[i] == INK){
|
||||||
|
memory[pos] += 1;
|
||||||
|
}
|
||||||
|
else if(commands[i] == DEK){
|
||||||
|
memory[pos] -= 1;
|
||||||
|
}
|
||||||
|
else if(commands[i] == BREK){
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
else if(commands[i] == GLEK){
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
else if(commands[i] == PUK){
|
||||||
|
putchar(memory[pos]);
|
||||||
|
}
|
||||||
|
else if(commands[i] == KUK){
|
||||||
|
memory[pos] = getchar();
|
||||||
|
}
|
||||||
|
else if(commands[i] == op && memory[pos] == 0){
|
||||||
|
int closed = 1;
|
||||||
|
while(closed > 0){
|
||||||
|
i++;
|
||||||
|
if(commands[i] == op){
|
||||||
|
closed++;
|
||||||
|
}
|
||||||
|
else if(commands[i] == cl){
|
||||||
|
closed--;
|
||||||
|
}
|
||||||
|
if(i > size){
|
||||||
|
printf("Error with opening bracket!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(commands[i] == cl && memory[pos] != 0){
|
||||||
|
int opened = 1;
|
||||||
|
while(opened > 0){
|
||||||
|
i--;
|
||||||
|
if(commands[i] == cl){
|
||||||
|
opened++;
|
||||||
|
}
|
||||||
|
else if(commands[i] == op){
|
||||||
|
opened--;
|
||||||
|
}
|
||||||
|
if(i < 0){
|
||||||
|
printf("Error with opening bracket!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(commands[i] == FUK){
|
||||||
|
ended = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ended){
|
||||||
|
printf("No FUK at the end :(\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int convert_code(enum action* commands, const char* code){
|
||||||
|
int pos = 0;
|
||||||
|
int offset = 0;
|
||||||
|
int add_offset = 0;
|
||||||
|
char buff[100];
|
||||||
|
|
||||||
|
int size = strlen(code);
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
int res = sscanf(code + offset ,"%s%n", buff, &add_offset);
|
||||||
|
if(res == 0 || strcmp(buff, "TUK") == 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1){
|
||||||
|
if(offset >= size){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int res = sscanf(code + offset ,"%s%n", buff, &add_offset);
|
||||||
|
|
||||||
|
if(res == 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += add_offset;
|
||||||
|
|
||||||
|
if(strcmp(buff, "TUK") == 0){
|
||||||
|
commands[pos] = TUK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "INK") == 0){
|
||||||
|
commands[pos] = INK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "DEK") == 0){
|
||||||
|
commands[pos] = DEK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "BREK") == 0){
|
||||||
|
commands[pos] = BREK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "GLEK") == 0){
|
||||||
|
commands[pos] = GLEK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "PUK") == 0){
|
||||||
|
commands[pos] = PUK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "KUK") == 0){
|
||||||
|
commands[pos] = KUK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "[") == 0){
|
||||||
|
commands[pos] = op;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "]") == 0){
|
||||||
|
commands[pos] = cl;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "FUK") == 0){
|
||||||
|
commands[pos] = FUK;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "[") == 0){
|
||||||
|
commands[pos] = op;
|
||||||
|
}
|
||||||
|
else if(strcmp(buff, "]") == 0){
|
||||||
|
commands[pos] = cl;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
decompress(in, out);
|
pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(in);
|
|
||||||
fclose(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
node create_node(unsigned char character, unsigned char pos){
|
|
||||||
node new = malloc(sizeof(struct node));
|
|
||||||
new->character = character;
|
|
||||||
new->pos = pos;
|
|
||||||
new->size = 0;
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
node find_parent_enc(node root, unsigned char character){
|
|
||||||
for(int i = 0; i < root->size; i++){
|
|
||||||
if(root->children[i]->character == character){
|
|
||||||
return root->children[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void recursive_free(node tree){
|
|
||||||
if(tree != NULL){
|
|
||||||
for(int i = 0; i < tree->size; i++){
|
|
||||||
recursive_free(tree->children[i]);
|
|
||||||
}
|
|
||||||
free(tree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_tree(node tree){
|
|
||||||
for(int i = 0; i < tree->size; i++){
|
|
||||||
recursive_free(tree->children[i]);
|
|
||||||
}
|
|
||||||
tree->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void enc_write(unsigned char pos, char character, FILE* out){
|
|
||||||
fputc(pos, out);
|
|
||||||
fputc(character, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void compress(FILE* in, FILE* out){
|
|
||||||
node root = create_node(0, 0);
|
|
||||||
|
|
||||||
unsigned char pos = 1;
|
|
||||||
unsigned char character;
|
|
||||||
|
|
||||||
node parent = root;
|
|
||||||
|
|
||||||
|
|
||||||
while(fread(&character, 1, 1, in) > 0){
|
|
||||||
node parent_copy = parent;
|
|
||||||
parent = find_parent_enc(parent_copy, character);
|
|
||||||
if(parent == NULL){
|
|
||||||
node new = create_node(character, pos);
|
|
||||||
parent_copy->children[parent_copy->size] = new;
|
|
||||||
enc_write(parent_copy->pos, parent_copy->children[parent_copy->size]->character, out);
|
|
||||||
parent_copy->size += 1;
|
|
||||||
pos++;
|
pos++;
|
||||||
if(pos >= 255){
|
|
||||||
pos = 1;
|
|
||||||
free_tree(root);
|
|
||||||
}
|
}
|
||||||
parent = root;
|
return pos;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parent != root){
|
|
||||||
fputc(parent->pos, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_tree(root);
|
|
||||||
free(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
node find_parent_dec(unsigned char pos, node tree){
|
|
||||||
if(pos == 0 || tree == NULL){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if(tree->pos == pos){
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < tree->size; i++){
|
|
||||||
node child = find_parent_dec(pos, tree->children[i]);
|
|
||||||
if(child != NULL){
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dec_write(node element, FILE* out){
|
|
||||||
if(element->parent != NULL){
|
|
||||||
dec_write(element->parent, out);
|
|
||||||
fputc(element->character, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void decompress(FILE* in, FILE* out){
|
|
||||||
int res = 0;
|
|
||||||
node root = create_node(0, 0);
|
|
||||||
|
|
||||||
unsigned short pos = 1;
|
|
||||||
unsigned char character;
|
|
||||||
unsigned char parent_pos;
|
|
||||||
|
|
||||||
while(fread(&parent_pos, 1, 1, in) > 0 && fread(&character, 1, 1, in) > 0){
|
|
||||||
node parent = find_parent_dec(parent_pos, root);
|
|
||||||
if(parent == NULL){
|
|
||||||
parent = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
node new = create_node(character, pos);
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
new->parent = parent;
|
|
||||||
parent->children[parent->size] = new;
|
|
||||||
parent->size += 1;
|
|
||||||
parent_pos = 0;
|
|
||||||
|
|
||||||
dec_write(new, out);
|
|
||||||
if(pos >= 255){
|
|
||||||
free_tree(root);
|
|
||||||
res++;
|
|
||||||
pos = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parent_pos != 0){
|
|
||||||
node last = find_parent_dec(parent_pos, root);
|
|
||||||
dec_write(last, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_tree(root);
|
|
||||||
free(root);
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user