Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
80 views
in Technique[技术] by (71.8m points)

c - How to read array in different directions?

I'm really new and bad at programming in C as I just started learning. Please be patient with me. I am currently trying to solve this puzzle: https://www.codingame.com/ide/puzzle/hidden-word. In the website, you can click on the three lines with three dots symbol on a box labeled "test cases" to view the test cases, then click on each test case to see the grid of letters and numbers in the left box, and then the expected output in the right box.

I know what I have to do which is to search through the grid of letters horizontally, vertically, diagonally, and the reverse of them, remove the numbers, don't print the repeated letters and combine the rest of the letters, print it out as the expected output.

I know how to write some of the other parts except for the one most important part, which is described in the title. I don't know how to check the letters horizontally, vertically, diagonally, and the reverse of them as the test cases have different numbers of column and rows. I figured I should use array but I am really bad at writing array codes.

Again, I am new and not a native English speaker so most of the stuff I just referenced on the internet and modified them. I probably shouldn't manually put the input in an array myself as the code is already written in the background (I don't know how to call it) and I don't know how to do this better.

Here is my current code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
 
#define MAX_STR_LEN 41
 
int main()
{
    int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            char aWord[41];
            scanf("%s", aWord);
        }
        int h;
        int w;
        scanf("%d%d", &h, &w);
        for (int i = 0; i < h; i++) {
            char line[41];
            scanf("%s", line);
        }
        
        int i;
 
        int F[7][3] = {
            {'2', '', ''},
            {'B', 'A', 'C'},
            {'B', 'O', 'B'},
            {'3', '', '3'},
            {'B', 'A', 'C'},
            {'B', 'O', 'B'},
            {'R', 'E', 'D'}
        };
        
            for (i = 0; i < n; i++) {
                int string;
 
                scanf("%d", &F);
                
                // remove numbers
 
                // don't print repeated elements
 
                // combine the rest of the elements
                
                strcpy(string, F);
 
                // print the combined elements
 
            }
            
            return 0;
}

As you can see, I have attempted but failed miserably. Can someone guide me through it? You don't really have to help me write the code, you could just tell me where and what to learn to write this type of code or teach me how to write them please. Thanks in advance.

question from:https://stackoverflow.com/questions/65874095/how-to-read-array-in-different-directions

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You don't really have to help me write the code, you could just tell me where and what to learn to write this type of code or teach me how to write them please

Note: This is an abstract idea on how to solve the problem using a trie, combine them together to your own implementation

I have an idea on how to solve this. First, you need to know and be able to implement Trie datastructure in C. as you read the n number of words you have to build (append the words to) the trie.

For the grid, you have to create a 2d array of GridEntry as defined below

typedef struct {
    char c;
    bool crossed; //< #include <stdbool.h>
} GridEntry;

GridEntry grid[rows][columns]; //< don't just copy this, won't work

now you have to iterate each entry in the grid. if it's already crossed skip and go to the next entry, else try to match a word starting at that entry horizontally, vertically and diagonally using the trie. (how to match trie is given below)

for (int r = 0; r < rows; r++) {
    for (int c = 0;  c < columns; c++) {
        if (grid[r][c].crossed) continue;
        try_match_word(trie, grid, r, c);
    }
}

How to match a word with trie? try_match_word function

  • first, check if any word in the trie start with the current entry character
  • if not, no matches found return (from try_match_word) otherwise
  • iteratively pick a direction (horizontally, vertically and diagonally) move towards that direction (here is how to pick a direction)
// your direction is (x, y) = {(1, 1), (1, 0), (0, -1), ...}
for (int x = -1; x <= 1; x++) {
    for (int y = -1; y <= 1; y++) {
        if (x == 0 && y == 0) continue;
        // now (x, y) is the direction
        int r_end = -1, c_end = -1; // end coordinate of the word
    }
}
  • now you have to move through that direction until you find the grid edge or you match
    The longest word when it doesn't match a word anymore. (here is how you move through a grid)
int i = 0;
while (true) {
    int cx = c + i*x;
    int cy = r + i*y; // (cx, cy) is the current position in the grid

    // check boundary conditions here and break the loop;

    i++;
}
  • now before you pick the direction you have to keep a current trie pointer to track the current character of the word as you move through the grid you have to update the trie pointer to the next character's trie.
Trie* curr = trie->chars[grid[r][c].c]; //< current trie
if (curr == NULL) return; //< no matching word

// and inside the move loop (where we've declared cx, cy)
Trie* next = curr->chars[grid[cy][cx].c];
if (next == NULL) {
    if (curr->is_end) {
      r_end = cy, c_end = cx; // word ends here
    }
    break;
}
curr = next;
  • once you match a word you'll know it if a r_end, c_end are != -1. and you have to cross those characters from (c, r) to (c_end, r_end). move through the coordinate and mark crossed grid[cy][cx].crossed = true;

  • once you matching words from each cell, you have to re iterate through the entries and collect the characters which are not crossed make a string, and return it.

char answer[256]; int i = 0;
for (int r = 0; r < rows; r++) {
    for (int c = 0;  c < columns; c++) {
        if (grid[r][c].crossed) continue;
        answer[i++] = grid[r][c].c;
    }
}
answer[i] = '';
return answer;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...