Skip to content

Instantly share code, notes, and snippets.

@cls

cls/codons.c

Last active May 9, 2020
Embed
What would you like to do?
Counting DNA codons. Mostly an exploration of multidimensional array pointers. (No input checking.)
#include <stdio.h>
#define CHAR_TO_BASE(C) (((C) >> 1) & 3)
enum base {
A = CHAR_TO_BASE('A'),
C = CHAR_TO_BASE('C'),
G = CHAR_TO_BASE('G'),
T = CHAR_TO_BASE('T'),
};
#define BASE_TO_CHAR(X) ((X) == T ? 'T' : 'A' | ((X) << 1))
_Static_assert(BASE_TO_CHAR(A) == 'A', "A must be correctly represented");
_Static_assert(BASE_TO_CHAR(C) == 'C', "C must be correctly represented");
_Static_assert(BASE_TO_CHAR(G) == 'G', "G must be correctly represented");
_Static_assert(BASE_TO_CHAR(T) == 'T', "T must be correctly represented");
static void count_codons(int (*)[4][4], const char *);
static void print_codons(const int (*)[4][4]);
int
main(int argc, char **argv)
{
int counts[4][4][4] = {0};
for (int i = 1; i < argc; i++)
count_codons(counts, argv[i]);
print_codons((const int (*)[4][4])counts);
return 0;
}
void
count_codons(int (*counts)[4][4], const char *s)
{
if (!s[0] || !s[1])
return;
enum base x = CHAR_TO_BASE(s[0]);
enum base y = CHAR_TO_BASE(s[1]);
enum base z;
for (const char *p = &s[2]; *p; x = y, y = z, p++) {
z = CHAR_TO_BASE(*p);
counts[x][y][z]++;
}
}
void
print_codons(const int (*counts)[4][4])
{
for (int x = 0; x < 4; x++) {
const char xc = BASE_TO_CHAR(x);
const int (*xcounts)[4] = counts[x];
for (int y = 0; y < 4; y++) {
const char yc = BASE_TO_CHAR(y);
const int *xycounts = xcounts[y];
for (int z = 0; z < 4; z++) {
const char zc = BASE_TO_CHAR(z);
const int xyzcount = xycounts[z];
if (xyzcount > 0) {
printf("%c%c%c: %d\n", xc, yc, zc, xyzcount);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment