What is the C-equivalent of a Python filter (function, iterable)?

I am trying to convert the following Python line to C. The problem is that the wording for me is very complicated. cubies is an array with a length equal to 120 lowercase characters. Here is an example:

fc = ""
try :
    # Pos 1
    fc += filter(lambda a : 'y' in a and 'b'  in a and 'o' in a, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'o'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'o'  in a and 'g' in a, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'b'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'g'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'b'  in a and 'r' in a, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'y' in a and 'r'  in a and 'g' in a, cubies)[0]
    # Pos 9
    fc += filter(lambda a : 'o' in a and 'b'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'o' in a and 'g'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'b' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'g' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    # Pos 13
    fc += filter(lambda a : 'w' in a and 'b'  in a and 'o' in a, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'o'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'o'  in a and 'g' in a, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'b'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'g'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'b'  in a and 'r' in a, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'r'  in a and a.count('n') == 4, cubies)[0]
    fc += filter(lambda a : 'w' in a and 'r'  in a and 'g' in a, cubies)[0]
except IndexError :
    sys.exit("IndexError raised")

I tried using several Python converters for C, such as Cython, but they were all either complex or their code too long to be practical for C noob like me.

If someone can point me in the right direction of documentation that would be helpful, or if you feel very kind, write me an example function in C.

+4
source share
4

python:

def find_matching(pattern):
    try:
        # Find the first cube where the cubie faces are a shuffled
        # version of the search faces"
        return next(c for c in cubies if sorted(c) == sorted(pattern))

    except StopIteration:
        # next raises StopIteration if it cannot find anything
        raise ValueError("Could not find pattern {}".format(pattern))


fc = ""
# Pos 1
fc += find_matching('ybonnn')
fc += find_matching('yonnnn')
fc += find_matching('yognnn')
fc += find_matching('ybnnnn')
fc += find_matching('ygnnnn')
fc += find_matching('ybrnnn')
fc += find_matching('yrnnnn')
fc += find_matching('yrgnnn')
# Pos 9
fc += find_matching('obnnnn')
fc += find_matching('ognnnn')
fc += find_matching('brnnnn')
fc += find_matching('grnnnn')
# Pos 13
fc += find_matching('wbonnn')
fc += find_matching('wonnnn')
fc += find_matching('wognnn')
fc += find_matching('wbnnnn')
fc += find_matching('wgnnnn')
fc += find_matching('wbrnnn')
fc += find_matching('wrnnnn')
fc += find_matching('wrgnnn')

, , :

,

,

+3

filter, Python ( ) (, ) . , , .

, C :

char *result;
int i;

for(i=0; i<120; i++) { // where 120 is the length of the array
    if(strchr(cubies[i], 'y') && strchr(cubies[i], 'b') && strchr(cubies[i], 'o')) {
        // Condition passes, set result
        result = cubies[i];
        break;
    }
}
if(i == 120) {
    // No condition passed: throw an error
    fprintf(stderr, "Error: condition failed");
    exit(1);
}

, , sprintf result fc, .

+2

. ( .)

char* fc = NULL;
int fclen = 0;

void appendtofc(const char* str)
{
    if (!str)
        return;

    int len = strlen(str);
    fc = realloc(fc, fclen + len + 1);
    if (!fc)
        /* handle error */;
    strcpy(fc + fclen, str);
    fclen += len;
}

const char* match3(const char** arr, int n, char c1, char c2, char c3)
{
    for (int i = 0; i < n; i++)
    {
        int needc = 7;
        for (const char* p = arr[i]; *p; p++)
        {
            if (*p == c1)
                needc &= ~1;
            else if (*p == c2)
                needc &= ~2;
            else if (*p == c3)
                needc &= ~4;

            if (!needc)
                return arr[i];
        }
    }
    return NULL;
}

const char* match2plus4n(const char** arr, int n, char c1, char c2)
{
    for (int i = 0; i < n; i++)
    {
        int needc = 3, needn = 4;
        for (const char* p = arr[i]; *p; p++)
        {
            if (*p == c1)
                needc &= ~1;
            else if (*p == c2)
                needc &= ~2;

            if (*p == 'n')
                needn--;

            if (!needc && !needn)
                return arr[i];
        }
    }
    return NULL;
}

void appendcubies(const char** cubies, int ncubies)
{
    appendtofc(match3(cubies, ncubies, 'y', 'b', 'o'));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'o'));
    appendtofc(match3(cubies, ncubies, 'y', 'o', 'g'));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'b'));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'g'));
    appendtofc(match3(cubies, ncubies, 'y', 'b', 'r' ));
    appendtofc(match2plus4n(cubies, ncubies, 'y', 'r'));
    appendtofc(match3(cubies, ncubies, 'y', 'r' , 'g' ));
    // Pos 9
    appendtofc(match2plus4n(cubies, ncubies, 'o', 'b'));
    appendtofc(match2plus4n(cubies, ncubies, 'o', 'g'));
    appendtofc(match2plus4n(cubies, ncubies, 'b', 'r'));
    appendtofc(match2plus4n(cubies, ncubies, 'g', 'r'));
    // Pos 13
    appendtofc(match3(cubies, ncubies, 'w', 'b' , 'o' ));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'o'));
    appendtofc(match3(cubies, ncubies, 'w', 'o' , 'g' ));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'b'));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'g'));
    appendtofc(match3(cubies, ncubies, 'w', 'b' , 'r' ));
    appendtofc(match2plus4n(cubies, ncubies, 'w', 'r'));
    appendtofc(match3(cubies, ncubies, 'w', 'r' , 'g' ));
}
+1

C does not have functional programming. If you can use C ++ instead, I would say the closest one remove_ifwith a lambda expression. Here is a demo:

#include <iostream>
#include <list>
#include <string>

using std::string;

int main(int argc, char** argv) {
  std::list<string> cubies = {"hello", "world", "bar", "baz"};
  cubies.remove_if([](const string& s){
    return s.find("a") != string::npos;
  });

  for (const string& s : cubies) {
    std::cout << s << std::endl;
  }
  return 0;
}

Output:

$ clang++ -std=c++11 cubies.cc 
$ ./a.out 
hello
world
-2
source

Source: https://habr.com/ru/post/1535096/


All Articles