Skip to content
Snippets Groups Projects
Commit 65a7f238 authored by Yiming Bao's avatar Yiming Bao
Browse files

Replace letter-boxed.c

parent fc9696d3
Branches main
No related tags found
No related merge requests found
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
struct node_t {
char* str;
struct node_t* next;
};
static char* str_dup(const char * s) {
char* r = (char*) malloc(strlen(s) + 1);
assert(r);
strcpy(r, s);
return r;
}
void list_destroy(struct node_t* head) {
while (head) {
struct node_t* nxt = head->next;
free(head->str);
free(head);
head = nxt;
}
}
struct node_t* list_find_ch(struct node_t* head, char ch) {
while (head && strchr(head->str, ch) == NULL) {
head = head->next;
}
return head;
}
struct node_t* list_find_str(struct node_t* head, const char* str) {
while (head && strcmp(head->str, str) != 0) {
head = head->next;
}
return head;
}
int list_size(struct node_t* head) {
int size = 0;
while (head) {
head = head->next;
size++;
}
return size;
}
struct node_t* list_prepend(struct node_t* head, const char* str) {
struct node_t* node = (struct node_t*) malloc(sizeof(struct node_t));
assert(node);
node->str = str_dup(str);
node->next = head;
return node;
}
struct node_t* list_append(struct node_t* head, const char* str) {
struct node_t* node = (struct node_t*) malloc(sizeof(struct node_t));
assert(node);
node->str = str_dup(str);
node->next = NULL;
if (head == NULL) {
head = node;
}
else {
struct node_t* cur = head;
while (cur->next)
cur = cur->next;
cur->next = node;
}
return head;
}
struct node_t* read_file(const char* dict_filename) {
struct node_t* list = NULL;
FILE* fp = fopen(dict_filename, "rb");
// open file failed
if (fp == NULL) {
exit(1);
}
char buf[1024];
while (fscanf(fp, "%s", buf) == 1) {
list = list_prepend(list, buf);
}
fclose(fp);
return list;
}
// remove the trailing \n and \r
void clear_line(char* line) {
int i;
for (i = 0; line[i]; i++)
if (line[i] == '\r' || line[i] == '\n')
line[i] = 0;
}
int check_line(struct node_t* board_list, const char* line, int freq[26], struct node_t* dict_list) {
struct node_t* prev_node = NULL;
int i;
for (i = 0; line[i]; i++) {
if (list_find_str(dict_list, line) == NULL) return -3;
freq[line[i] - 'a'] = 0;
struct node_t* node = list_find_ch(board_list, line[i]);
if (node == NULL) return -2;
if (node == prev_node) return -1;
prev_node = node;
}
return 0;
}
int check_board_duplicate(struct node_t* head, int freq[26]) {
int i;
while (head) {
for (i = 0; head->str[i]; i++)
freq[head->str[i] - 'a']++;
head = head->next;
}
for (i = 0; i < 26; i++)
if (freq[i] > 1)
return -1;
return 0;
}
int main(int argc, char* argv[]) {
int i, ret;
const char* board_filename = "1.board";
const char* dict_filename = "dict.txt";
// wrong number of arguments
if (argc != 3) {
return 1;
}
board_filename = argv[1];
dict_filename = argv[2];
// frequency of each letter.
int freq[26];
for (i = 0; i < 26; i++) {
freq[i] = 0; // initialize with 0.
}
struct node_t* board_list = read_file(board_filename);
// (1) If the board is invalid (less than 3 sides)
if (list_size(board_list) < 3) {
printf("Invalid board\n");
return 1;
}
// (2) If a board contains a letter more than once
if (check_board_duplicate(board_list, freq) == -1) {
printf("Invalid board\n");
return 1;
}
struct node_t* dict_list = read_file(dict_filename);
char prev_last_ch = 0;
char line[1024];
while (fgets(line, 1024, stdin)) {
clear_line(line);
// (7) If the first character of a word in the solution is not the same as the last character
if (prev_last_ch != 0 && prev_last_ch != line[0]) {
printf("First letter of word does not match last letter of previous word\n");
return 0;
}
ret = check_line(board_list, line, freq, dict_list);
// (3) If the solution uses a letter not present on the board
if (ret == -2) {
printf("Used a letter not present on the board\n");
return 0;
}
// (5) If the solution illegally uses letters on the same side of the board consecutively
if (ret == -1) {
printf("Same-side letter used consecutively\n");
return 0;
}
// (6) If the solution uses a word not found in the dictionary
if (ret == -3) {
printf("Word not found in dictionary\n");
return 0;
}
prev_last_ch = line[strlen(line) - 1];
}
list_destroy(dict_list);
list_destroy(board_list);
// (4) If the solution does not use all the letters on the board
for (i = 0; i < 26; i++) {
if (freq[i] > 0) {
printf("Not all letters used\n");
return 0;
}
}
printf("Correct\n");
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment