Best shuffle

Shuffle the characters of a string in such a way that as many of the character values are in a different position as possible.

A shuffle that produces a randomized result among the best choices is to be preferred. A deterministic approach that produces the same sequence every time is acceptable as an alternative.

Display the result as follows:

 original string, shuffled string, (score)

The score gives the number of positions whose character value did ''not'' change.

;Example:
 tree, eetr, (0)

;Test cases:
 abracadabra
 seesaw
 elk
 grrrrrr
 up
 a

;Related tasks
*   [[Anagrams/Deranged anagrams]]
*   [[Permutations/Derangements]]

Solution:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <limits.h>

#define DEBUG

void best_shuffle(const char* txt, char* result) {
    const size_t len = strlen(txt);
    if (len == 0)
        return;

#ifdef DEBUG
    // txt and result must have the same length
    assert(len == strlen(result));
#endif

    // how many of each character?
    size_t counts[UCHAR_MAX];
    memset(counts, '\0', UCHAR_MAX * sizeof(int));
    size_t fmax = 0;
    for (size_t i = 0; i < len; i++) {
        counts[(unsigned char)txt[i]]++;
        const size_t fnew = counts[(unsigned char)txt[i]];
        if (fmax < fnew)
             fmax = fnew;
    }
    assert(fmax > 0 && fmax <= len);

    // all character positions, grouped by character
    size_t *ndx1 = malloc(len * sizeof(size_t));
    if (ndx1 == NULL)
        exit(EXIT_FAILURE);
    for (size_t ch = 0, i = 0; ch < UCHAR_MAX; ch++)
       if (counts[ch])
            for (size_t j = 0; j < len; j++)
                if (ch == (unsigned char)txt[j]) {
                    ndx1[i] = j;
                    i++;
                }

    // regroup them for cycles
    size_t *ndx2 = malloc(len * sizeof(size_t));
    if (ndx2 == NULL)
        exit(EXIT_FAILURE);
    for (size_t i = 0, n = 0, m = 0; i < len; i++) {
        ndx2[i] = ndx1[n];
        n += fmax;
        if (n >= len) {
            m++;
            n = m;
        }
    }

    // how long can our cyclic groups be?
    const size_t grp = 1 + (len - 1) / fmax;
    assert(grp > 0 && grp <= len);

    // how many of them are full length?
    const size_t lng = 1 + (len - 1) % fmax;
    assert(lng > 0 && lng <= len);

    // rotate each group
    for (size_t i = 0, j = 0; i < fmax; i++) {
        const size_t first = ndx2[j];
        const size_t glen = grp - (i < lng ? 0 : 1);
        for (size_t k = 1; k < glen; k++)
            ndx1[j + k - 1] = ndx2[j + k];
        ndx1[j + glen - 1] = first;
        j += glen;
    }

    // result is original permuted according to our cyclic groups
    result[len] = '\0';
    for (size_t i = 0; i < len; i++)
        result[ndx2[i]] = txt[ndx1[i]];

    free(ndx1);
    free(ndx2);
}

void display(const char* txt1, const char* txt2) {
    const size_t len = strlen(txt1);
    assert(len == strlen(txt2));
    int score = 0;
    for (size_t i = 0; i < len; i++)
        if (txt1[i] == txt2[i])
            score++;
    (void)printf("%s, %s, (%u)\n", txt1, txt2, score);
}

int main() {
    const char* data[] = {"abracadabra", "seesaw", "elk", "grrrrrr",
                          "up", "a", "aabbbbaa", "", "xxxxx"};
    const size_t data_len = sizeof(data) / sizeof(data[0]);
    for (size_t i = 0; i < data_len; i++) {
        const size_t shuf_len = strlen(data[i]) + 1;
        char shuf[shuf_len];

#ifdef DEBUG
        memset(shuf, 0xFF, sizeof shuf);
        shuf[shuf_len - 1] = '\0';
#endif

        best_shuffle(data[i], shuf);
        display(data[i], shuf);
    }

    return EXIT_SUCCESS;
}


Bin given limits

Solution:
#include <stdio.h>
#include <stdlib.h>

size_t upper_bound(const int* array, size_t n, int value) {
    size_t start = 0;
    while (n > 0) {
        size_t step = n / 2;
        size_t index = start + step;
        if (value >= array[index]) {
            start = index + 1;
            n -= step + 1;
        } else {
            n = step;
        }
    }
    return start;
}

int* bins(const int* limits, size_t nlimits, const int* data, size_t ndata) {
    int* result = calloc(nlimits + 1, sizeof(int));
    if (result == NULL)
        return NULL;
    for (size_t i = 0; i < ndata; ++i)
        ++result[upper_bound(limits, nlimits, data[i])];
    return result;
}

void print_bins(const int* limits, size_t n, const int* bins) {
    if (n == 0)
        return;
    printf("           < %3d: %2d\n", limits[0], bins[0]);
    for (size_t i = 1; i < n; ++i)
        printf(">= %3d and < %3d: %2d\n", limits[i - 1], limits[i], bins[i]);
    printf(">= %3d          : %2d\n", limits[n - 1], bins[n]);
}

int main() {
    const int limits1[] = {23, 37, 43, 53, 67, 83};
    const int data1[] = {95, 21, 94, 12, 99, 4,  70, 75, 83, 93, 52, 80, 57,
                         5,  53, 86, 65, 17, 92, 83, 71, 61, 54, 58, 47, 16,
                         8,  9,  32, 84, 7,  87, 46, 19, 30, 37, 96, 6,  98,
                         40, 79, 97, 45, 64, 60, 29, 49, 36, 43, 55};

    printf("Example 1:\n");
    size_t n = sizeof(limits1) / sizeof(int);
    int* b = bins(limits1, n, data1, sizeof(data1) / sizeof(int));
    if (b == NULL) {
        fprintf(stderr, "Out of memory\n");
        return EXIT_FAILURE;
    }
    print_bins(limits1, n, b);
    free(b);

    const int limits2[] = {14, 18, 249, 312, 389, 392, 513, 591, 634, 720};
    const int data2[] = {
        445, 814, 519, 697, 700, 130, 255, 889, 481, 122, 932, 77,  323, 525,
        570, 219, 367, 523, 442, 933, 416, 589, 930, 373, 202, 253, 775, 47,
        731, 685, 293, 126, 133, 450, 545, 100, 741, 583, 763, 306, 655, 267,
        248, 477, 549, 238, 62,  678, 98,  534, 622, 907, 406, 714, 184, 391,
        913, 42,  560, 247, 346, 860, 56,  138, 546, 38,  985, 948, 58,  213,
        799, 319, 390, 634, 458, 945, 733, 507, 916, 123, 345, 110, 720, 917,
        313, 845, 426, 9,   457, 628, 410, 723, 354, 895, 881, 953, 677, 137,
        397, 97,  854, 740, 83,  216, 421, 94,  517, 479, 292, 963, 376, 981,
        480, 39,  257, 272, 157, 5,   316, 395, 787, 942, 456, 242, 759, 898,
        576, 67,  298, 425, 894, 435, 831, 241, 989, 614, 987, 770, 384, 692,
        698, 765, 331, 487, 251, 600, 879, 342, 982, 527, 736, 795, 585, 40,
        54,  901, 408, 359, 577, 237, 605, 847, 353, 968, 832, 205, 838, 427,
        876, 959, 686, 646, 835, 127, 621, 892, 443, 198, 988, 791, 466, 23,
        707, 467, 33,  670, 921, 180, 991, 396, 160, 436, 717, 918, 8,   374,
        101, 684, 727, 749};

    printf("\nExample 2:\n");
    n = sizeof(limits2) / sizeof(int);
    b = bins(limits2, n, data2, sizeof(data2) / sizeof(int));
    if (b == NULL) {
        fprintf(stderr, "Out of memory\n");
        return EXIT_FAILURE;
    }
    print_bins(limits2, n, b);
    free(b);

    return EXIT_SUCCESS;
}


Bioinformatics/Sequence mutation

Given a string of characters A, C, G, and T representing a DNA sequence write a routine to mutate the sequence, (string) by:
# Choosing a random base position in the sequence.
# Mutate the sequence by  doing one of either:
## '''S'''wap the base at that position by changing it to one of A, C, G, or T. (which has a chance of swapping the base for the same base)
## '''D'''elete the chosen base at the position.
## '''I'''nsert another base randomly chosen from A,C, G, or T into the sequence at that position.
# Randomly generate a test DNA sequence of at least 200 bases
# "Pretty print" the sequence and a count of its size, and the count of each base in the sequence
# Mutate the sequence ten times.
# "Pretty print" the sequence after all mutations, and a count of its size, and the count of each base in the sequence.

;Extra credit:
* Give more information on the individual mutations applied.
* Allow mutations to be weighted and/or chosen.

Solution:
#include<stdlib.h>
#include<stdio.h>
#include<time.h>

typedef struct genome{
    char base;
    struct genome *next;
}genome;

typedef struct{
    char mutation;
    int position;
}genomeChange;

typedef struct{
    int adenineCount,thymineCount,cytosineCount,guanineCount;
}baseCounts;

genome *strand;
baseCounts baseData;
int genomeLength = 100, lineLength = 50;

int numDigits(int num){
    int len = 1;

    while(num>10){
        num /= 10;
        len++;
    }
    return len;
}

void generateStrand(){

    int baseChoice = rand()%4, i;
    genome *strandIterator, *newStrand;

    baseData.adenineCount = 0;
    baseData.thymineCount = 0;
    baseData.cytosineCount = 0;
    baseData.guanineCount = 0;

    strand = (genome*)malloc(sizeof(genome));
    strand->base = baseChoice==0?'A':(baseChoice==1?'T':(baseChoice==2?'C':'G'));
    baseChoice==0?baseData.adenineCount++:(baseChoice==1?baseData.thymineCount++:(baseChoice==2?baseData.cytosineCount++:baseData.guanineCount++));
    strand->next = NULL;

    strandIterator = strand;

    for(i=1;i<genomeLength;i++){
        baseChoice = rand()%4;

        newStrand = (genome*)malloc(sizeof(genome));
        newStrand->base = baseChoice==0?'A':(baseChoice==1?'T':(baseChoice==2?'C':'G'));
        baseChoice==0?baseData.adenineCount++:(baseChoice==1?baseData.thymineCount++:(baseChoice==2?baseData.cytosineCount++:baseData.guanineCount++));
        newStrand->next = NULL;

        strandIterator->next = newStrand;
        strandIterator = newStrand;
    }
}

genomeChange generateMutation(int swapWeight, int insertionWeight, int deletionWeight){
    int mutationChoice = rand()%(swapWeight + insertionWeight + deletionWeight);

    genomeChange mutationCommand;

    mutationCommand.mutation = mutationChoice<swapWeight?'S':((mutationChoice>=swapWeight && mutationChoice<swapWeight+insertionWeight)?'I':'D');
    mutationCommand.position = rand()%genomeLength;

    return mutationCommand;
}

void printGenome(){
    int rows, width = numDigits(genomeLength), len = 0,i,j;
	lineLength = (genomeLength<lineLength)?genomeLength:lineLength;

	rows = genomeLength/lineLength + (genomeLength%lineLength!=0);

    genome* strandIterator = strand;

    printf("\n\nGenome : \n--------\n");

    for(i=0;i<rows;i++){
        printf("\n%*d%3s",width,len,":");

        for(j=0;j<lineLength && strandIterator!=NULL;j++){
                printf("%c",strandIterator->base);
                strandIterator = strandIterator->next;
        }
        len += lineLength;
    }

    while(strandIterator!=NULL){
            printf("%c",strandIterator->base);
            strandIterator = strandIterator->next;
    }

    printf("\n\nBase Counts\n-----------");

    printf("\n%*c%3s%*d",width,'A',":",width,baseData.adenineCount);
    printf("\n%*c%3s%*d",width,'T',":",width,baseData.thymineCount);
    printf("\n%*c%3s%*d",width,'C',":",width,baseData.cytosineCount);
    printf("\n%*c%3s%*d",width,'G',":",width,baseData.guanineCount);

	printf("\n\nTotal:%*d",width,baseData.adenineCount + baseData.thymineCount + baseData.cytosineCount + baseData.guanineCount);

    printf("\n");
}

void mutateStrand(int numMutations, int swapWeight, int insertionWeight, int deletionWeight){
    int i,j,width,baseChoice;
    genomeChange newMutation;
    genome *strandIterator, *strandFollower, *newStrand;

    for(i=0;i<numMutations;i++){
        strandIterator = strand;
        strandFollower = strand;
        newMutation = generateMutation(swapWeight,insertionWeight,deletionWeight);
        width = numDigits(genomeLength);

        for(j=0;j<newMutation.position;j++){
            strandFollower = strandIterator;
            strandIterator = strandIterator->next;
        }

        if(newMutation.mutation=='S'){
            if(strandIterator->base=='A'){
                strandIterator->base='T';
                printf("\nSwapping A at position : %*d with T",width,newMutation.position);
            }
            else if(strandIterator->base=='A'){
                strandIterator->base='T';
                printf("\nSwapping A at position : %*d with T",width,newMutation.position);
            }
            else if(strandIterator->base=='C'){
                strandIterator->base='G';
                printf("\nSwapping C at position : %*d with G",width,newMutation.position);
            }
            else{
                strandIterator->base='C';
                printf("\nSwapping G at position : %*d with C",width,newMutation.position);
            }
        }

        else if(newMutation.mutation=='I'){
            baseChoice = rand()%4;

            newStrand = (genome*)malloc(sizeof(genome));
            newStrand->base = baseChoice==0?'A':(baseChoice==1?'T':(baseChoice==2?'C':'G'));
            printf("\nInserting %c at position : %*d",newStrand->base,width,newMutation.position);
            baseChoice==0?baseData.adenineCount++:(baseChoice==1?baseData.thymineCount++:(baseChoice==2?baseData.cytosineCount++:baseData.guanineCount++));
            newStrand->next = strandIterator;
            strandFollower->next = newStrand;
            genomeLength++;
        }

        else{
            strandFollower->next = strandIterator->next;
            strandIterator->next = NULL;
            printf("\nDeleting %c at position : %*d",strandIterator->base,width,newMutation.position);
            free(strandIterator);
            genomeLength--;
        }
    }
}

int main(int argc,char* argv[])
{
    int numMutations = 10, swapWeight = 10, insertWeight = 10, deleteWeight = 10;

    if(argc==1||argc>6){
                printf("Usage : %s <Genome Length> <Optional number of mutations> <Optional Swapping weight> <Optional Insertion weight> <Optional Deletion weight>\n",argv[0]);
                return 0;
    }

    switch(argc){
        case 2: genomeLength = atoi(argv[1]);
                break;
        case 3: genomeLength = atoi(argv[1]);
                numMutations = atoi(argv[2]);
                break;
        case 4: genomeLength = atoi(argv[1]);
                numMutations = atoi(argv[2]);
                swapWeight   = atoi(argv[3]);
                break;
        case 5: genomeLength = atoi(argv[1]);
                numMutations = atoi(argv[2]);
                swapWeight   = atoi(argv[3]);
                insertWeight = atoi(argv[4]);
                break;
        case 6: genomeLength = atoi(argv[1]);
                numMutations = atoi(argv[2]);
                swapWeight   = atoi(argv[3]);
                insertWeight = atoi(argv[4]);
                deleteWeight = atoi(argv[5]);
                break;
    };

    srand(time(NULL));
    generateStrand();

	printf("\nOriginal:");
    printGenome();
    mutateStrand(numMutations,swapWeight,insertWeight,deleteWeight);

	printf("\n\nMutated:");
	printGenome();

    return 0;
}


Bioinformatics/base count

Given this string representing ordered DNA bases:

CGTAAAAAATTACAACGTCCTTTGGCTATCTCTTAAACTCCTGCTAAATG
CTCGTGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTG
AGGACAAAGGTCAAGATGGAGCGCATCGAACGCAATAAGGATCATTTGAT
GGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTT
CGATTCTGCTTATAACACTATGTTCTTATGAAATGGATGTTCTGAGTTGG
TCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATA
TTTAATTTTTCTATATAGCGATCTGTATTTAAGCAATTCATTTAGGTTAT
CGCCGCGATGCTCGGTTCGGACCGCCAAGCATCTGGCTCCACTGCTAGTG
TCCTAAATTTGAATGGCAAACACAAATAAGATTTAGCAATTCGTGTAGAC
GACCGGGGACTTGCATGATGGGAGCAGCTTTGTTAAACTACGAACGTAAT

;Task:
:*   "Pretty print" the sequence followed by a summary of the counts of each of the bases:   ('''A''', '''C''', '''G''', and '''T''')   in the sequence
:*   print the total count of each base in the string.

Solution:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>

typedef struct genome{
    char* strand;
    int length;
    struct genome* next;
}genome;

genome* genomeData;
int totalLength = 0, Adenine = 0, Cytosine = 0, Guanine = 0, Thymine = 0;

int numDigits(int num){
    int len = 1;

    while(num>10){
        num = num/10;
        len++;
    }

    return len;
}

void buildGenome(char str[100]){
    int len = strlen(str),i;
    genome *genomeIterator, *newGenome;

    totalLength += len;

    for(i=0;i<len;i++){
        switch(str[i]){
            case 'A': Adenine++;
                break;
            case 'T': Thymine++;
                break;
            case 'C': Cytosine++;
                break;
            case 'G': Guanine++;
                break;
        };
    }

    if(genomeData==NULL){
        genomeData = (genome*)malloc(sizeof(genome));

        genomeData->strand = (char*)malloc(len*sizeof(char));
        strcpy(genomeData->strand,str);
        genomeData->length = len;

        genomeData->next = NULL;
    }

    else{
        genomeIterator = genomeData;

        while(genomeIterator->next!=NULL)
            genomeIterator = genomeIterator->next;

        newGenome = (genome*)malloc(sizeof(genome));

        newGenome->strand = (char*)malloc(len*sizeof(char));
        strcpy(newGenome->strand,str);
        newGenome->length = len;

        newGenome->next = NULL;
        genomeIterator->next = newGenome;
    }
}

void printGenome(){
    genome* genomeIterator = genomeData;

    int width = numDigits(totalLength), len = 0;

    printf("Sequence:\n");

    while(genomeIterator!=NULL){
        printf("\n%*d%3s%3s",width+1,len,":",genomeIterator->strand);
        len += genomeIterator->length;

        genomeIterator = genomeIterator->next;
    }

    printf("\n\nBase Count\n----------\n\n");

    printf("%3c%3s%*d\n",'A',":",width+1,Adenine);
    printf("%3c%3s%*d\n",'T',":",width+1,Thymine);
    printf("%3c%3s%*d\n",'C',":",width+1,Cytosine);
    printf("%3c%3s%*d\n",'G',":",width+1,Guanine);
    printf("\n%3s%*d\n","Total:",width+1,Adenine + Thymine + Cytosine + Guanine);

    free(genomeData);
}

int main(int argc,char** argv)
{
    char str[100];
    int counter = 0, len;

    if(argc!=2){
        printf("Usage : %s <Gene file name>\n",argv[0]);
        return 0;
    }

    FILE *fp = fopen(argv[1],"r");

    while(fscanf(fp,"%s",str)!=EOF)
        buildGenome(str);
    fclose(fp);

    printGenome();

    return 0;
}


Bitcoin/address validation

Write a program that takes a bitcoin address as argument,
and checks whether or not this address is valid.

A bitcoin address uses a base58 encoding, which uses an alphabet of the characters 0 .. 9, A ..Z, a .. z, but without the four characters:
:::*   0   zero
:::*   O   uppercase oh
:::*   I   uppercase eye
:::*   l   lowercase ell

With this encoding, a bitcoin address encodes 25 bytes:
* the first byte is the version number, which will be zero for this task ;
* the next twenty bytes are a [[RIPEMD-160]] digest, but you don't have to know that for this task:  you can consider them a pure arbitrary data ;
* the last four bytes are a checksum check.  They are the first four bytes of a double [[SHA-256]] digest of the previous 21 bytes.

To check the bitcoin address, you must read the first twenty-one bytes, compute the checksum, and check that it corresponds to the last four bytes.

The program can either return a boolean value or throw an exception when not valid.

You can use a digest library for [[SHA-256]].

;Example of a bitcoin address:

 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i

It doesn't belong to anyone and is part of the test suite of the bitcoin software.
You can change a few characters in this string and check that it'll fail the test.

Solution:
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>

const char *coin_err;
#define bail(s) { coin_err = s; return 0; }

int unbase58(const char *s, unsigned char *out) {
	static const char *tmpl = "123456789"
		"ABCDEFGHJKLMNPQRSTUVWXYZ"
		"abcdefghijkmnopqrstuvwxyz";
	int i, j, c;
	const char *p;

	memset(out, 0, 25);
	for (i = 0; s[i]; i++) {
		if (!(p = strchr(tmpl, s[i])))
			bail("bad char");

		c = p - tmpl;
		for (j = 25; j--; ) {
			c += 58 * out[j];
			out[j] = c % 256;
			c /= 256;
		}

		if (c) bail("address too long");
	}

	return 1;
}

int valid(const char *s) {
	unsigned char dec[32], d1[SHA256_DIGEST_LENGTH], d2[SHA256_DIGEST_LENGTH];

	coin_err = "";
	if (!unbase58(s, dec)) return 0;

	SHA256(SHA256(dec, 21, d1), SHA256_DIGEST_LENGTH, d2);

	if (memcmp(dec + 21, d2, 4))
		bail("bad digest");

	return 1;
}

int main (void) {
	const char *s[] = {
		"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9",
		"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",
		"1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9",
		"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I",
		0 };
	int i;
	for (i = 0; s[i]; i++) {
		int status = valid(s[i]);
		printf("%s: %s\n", s[i], status ? "Ok" : coin_err);
	}

	return 0;
}


Bitcoin/public point to address

elliptic curve public point into a short ASCII string.  The purpose of this task is to perform such a conversion.

The encoding steps are:
* take the X and Y coordinates of the given public point, and concatenate them in order to have a 64 byte-longed string ;
* add one byte prefix equal to 4 (it is a convention for this way of encoding a public point) ;
* compute the [[SHA-256]] of this string ;
* compute the [[RIPEMD-160]] of this SHA-256 digest ;
* compute the checksum of the concatenation of the version number digit (a single zero byte) and this RIPEMD-160 digest, as described in [[bitcoin/address validation]] ;
* Base-58 encode (see below) the concatenation of the version number (zero in this case), the ripemd digest and the checksum

The base-58 encoding is based on an alphabet of alphanumeric characters (numbers, upper case and lower case, in that order) but without the four characters 0, O, l and I.

Here is an example public point:
X = 0x50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352
Y = 0x2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6

The corresponding address should be:
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

Nb.  The leading '1' is not significant as 1 is zero in base-58.  It is however often added to the bitcoin address for various reasons.  There can actually be several of them.  You can ignore this and output an address without the leading 1.

''Extra credit:'' add a verification procedure about the public point, making sure it belongs to the secp256k1 elliptic curve

Solution:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>

#define COIN_VER 0
const char *coin_err;

typedef unsigned char byte;

int is_hex(const char *s) {
	int i;
	for (i = 0; i < 64; i++)
		if (!isxdigit(s[i])) return 0;
	return 1;
}

void str_to_byte(const char *src, byte *dst, int n) {
	while (n--) sscanf(src + n * 2, "%2hhx", dst + n);
}

char* base58(byte *s, char *out) {
	static const char *tmpl = "123456789"
		"ABCDEFGHJKLMNPQRSTUVWXYZ"
		"abcdefghijkmnopqrstuvwxyz";
	static char buf[40];

	int c, i, n;
	if (!out) out = buf;

	out[n = 34] = 0;
	while (n--) {
		for (c = i = 0; i < 25; i++) {
			c = c * 256 + s[i];
			s[i] = c / 58;
			c %= 58;
		}
		out[n] = tmpl[c];
	}

	for (n = 0; out[n] == '1'; n++);
	memmove(out, out + n, 34 - n);

	return out;
}

char *coin_encode(const char *x, const char *y, char *out) {
	byte s[65];
	byte rmd[5 + RIPEMD160_DIGEST_LENGTH];

	if (!is_hex(x) || !(is_hex(y))) {
		coin_err = "bad public point string";
		return 0;
	}

	s[0] = 4;
	str_to_byte(x, s + 1, 32);
	str_to_byte(y, s + 33, 32);

	rmd[0] = COIN_VER;
	RIPEMD160(SHA256(s, 65, 0), SHA256_DIGEST_LENGTH, rmd + 1);

	memcpy(rmd + 21, SHA256(SHA256(rmd, 21, 0), SHA256_DIGEST_LENGTH, 0), 4);

	return base58(rmd, out);
}

int main(void) {
	puts(coin_encode(
		"50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352",
		"2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6",
		0));
	return 0;
}


Bitwise IO

The aim of this task is to write functions (or create a class if yourlanguage is Object Oriented and you prefer) for reading and writing sequences of
bits, most significant bit first. While the output of a asciiprint "STRING" is the ASCII byte sequence
"S", "T", "R", "I", "N", "G", the output of a "print" of the bits sequence
0101011101010 (13 bits) must be 0101011101010; real I/O is performed always
''quantized'' by byte (avoiding endianness issues and relying on underlying
buffering for performance), therefore you must obtain as output the bytes
0101 0111 0101 0'''000''' (bold bits are padding bits), i.e. in hexadecimal 57 50.

As test, you can implement a '''rough''' (e.g. don't care about error handling or
other issues) compression/decompression program for ASCII sequences
of bytes, i.e. bytes for which the most significant bit is always unused, so that you can write
seven bits instead of eight (each 8 bytes of input, we write 7 bytes of output).

These bit oriented I/O functions can be used to implement compressors and
decompressors; e.g. Dynamic and Static Huffman encodings use variable length
bits sequences, while LZW (see [[LZW compression]]) use fixed or variable ''words''
nine (or more) bits long.

* Limits in the maximum number of bits that can be written/read in a single read/write operation are allowed.
* Errors handling is not mandatory

Solution:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

typedef uint8_t byte;
typedef struct {
    FILE *fp;
    uint32_t accu;
    int bits;
} bit_io_t, *bit_filter;

bit_filter b_attach(FILE *f)
{
    bit_filter b = malloc(sizeof(bit_io_t));
    b->bits = b->accu = 0;
    b->fp = f;
    return b;
}

void b_write(byte *buf, size_t n_bits, size_t shift, bit_filter bf)
{
    uint32_t accu = bf->accu;
    int bits = bf->bits;

    buf += shift / 8;
    shift %= 8;

    while (n_bits || bits >= 8) {
        while (bits >= 8) {
            bits -= 8;
            fputc(accu >> bits, bf->fp);
            accu &= (1 << bits) - 1;
        }
        while (bits < 8 && n_bits) {
            accu = (accu << 1) | (((128 >> shift) & *buf) >> (7 - shift));
            --n_bits;
            bits++;
            if (++shift == 8) {
                shift = 0;
                buf++;
            }
        }
    }
    bf->accu = accu;
    bf->bits = bits;
}

size_t b_read(byte *buf, size_t n_bits, size_t shift, bit_filter bf)
{
    uint32_t accu = bf->accu;
    int bits = bf->bits;
    int mask, i = 0;

    buf += shift / 8;
    shift %= 8;

    while (n_bits) {
        while (bits && n_bits) {
            mask = 128 >> shift;
            if (accu & (1 << (bits - 1))) *buf |= mask;
            else *buf &= ~mask;

            n_bits--;
            bits--;

            if (++shift >= 8) {
                shift = 0;
                buf++;
            }
        }
        if (!n_bits) break;
        accu = (accu << 8) | fgetc(bf->fp);
        bits += 8;
    }
    bf->accu = accu;
    bf->bits = bits;

    return i;
}

void b_detach(bit_filter bf)
{
    if (bf->bits) {
        bf->accu <<= 8 - bf->bits;
        fputc(bf->accu, bf->fp);
    }
    free(bf);
}

int main()
{
    unsigned char s[] = "abcdefghijk";
    unsigned char s2[11] = {0};
    int i;

    FILE *f = fopen("test.bin", "wb");
    bit_filter b = b_attach(f);
    /* for each byte in s, write 7 bits skipping 1 */
    for (i = 0; i < 10; i++) b_write(s + i, 7, 1, b);
    b_detach(b);
    fclose(f);

    /* read 7 bits and expand to each byte of s2 skipping 1 bit */
    f = fopen("test.bin", "rb");
    b = b_attach(f);
    for (i = 0; i < 10; i++) b_read(s2 + i, 7, 1, b);
    b_detach(b);
    fclose(f);

    printf("%10s\n", s2); /* should be the same first 10 bytes as in s */

    return 0;
}


Box the compass

Avast me hearties!
There be many a land lubber that knows naught of the pirate ways and gives direction by degree!
They know not how to box the compass!

;Task description:
# Create a function that takes a heading in degrees and returns the correct 32-point compass heading.
# Use the function to print and display a table of Index, Compass point, and Degree; rather like the corresponding columns from, the first table of the wikipedia article, but use only the following 33 headings as input:
:[0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]. (They should give the same order of points but are spread throughout the ranges of acceptance).

;Notes;
* The headings and indices can be calculated from this pseudocode:
for i in 0..32 inclusive:
    heading = i * 11.25
    case i %3:
      if 1: heading += 5.62; break
      if 2: heading -= 5.62; break
    end
    index = ( i mod 32) + 1
* The column of indices can be thought of as an enumeration of the thirty two cardinal points (see talk page)..

Solution:
#include <stdio.h>

int main()
{
        int i, j;
        double degrees[] = { 0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5,
                84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88,
                168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12,
                253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5,
                354.37, 354.38 };
        const char * names =  "North                 "
                              "North by east         "
                              "North-northeast       "
                              "Northeast by north    "
                              "Northeast             "
                              "Northeast by east     "
                              "East-northeast        "
                              "East by north         "
                              "East                  "
                              "East by south         "
                              "East-southeast        "
                              "Southeast by east     "
                              "Southeast             "
                              "Southeast by south    "
                              "South-southeast       "
                              "South by east         "
                              "South                 "
                              "South by west         "
                              "South-southwest       "
                              "Southwest by south    "
                              "Southwest             "
                              "Southwest by west     "
                              "West-southwest        "
                              "West by south         "
                              "West                  "
                              "West by north         "
                              "West-northwest        "
                              "Northwest by west     "
                              "Northwest             "
                              "Northwest by north    "
                              "North-northwest       "
                              "North by west         "
                              "North                 ";

        for (i = 0; i < 33; i++) {
                j = .5 + degrees[i] * 32 / 360;

                printf("%2d  %.22s  %6.2f\n", (j % 32) + 1, names + (j % 32) * 22,
                        degrees[i]);
        }

        return 0;
}


CSV data manipulation

CSV spreadsheet files are suitable for storing tabular data in a relatively portable way.

The CSV format is flexible but somewhat ill-defined.

For present purposes, authors may assume that the data fields contain no commas, backslashes, or quotation marks.

;Task:
Read a CSV file, change some values and save the changes back to a file.

For this task we will use the following CSV file:

 C1,C2,C3,C4,C5
 1,5,9,13,17
 2,6,10,14,18
 3,7,11,15,19
 4,8,12,16,20

Suggestions

 Show how to add a column, headed 'SUM', of the sums of the rows.
 If possible, illustrate the use of built-in or standard functions, methods, or libraries, that handle generic CSV files.

Solution:
#define TITLE "CSV data manipulation"
#define URL "http://rosettacode.org/wiki/CSV_data_manipulation"

#define _GNU_SOURCE
#define bool int
#include <stdio.h>
#include <stdlib.h> /* malloc...*/
#include <string.h> /* strtok...*/
#include <ctype.h>
#include <errno.h>

/**
 * How to read a CSV file ?
 */

typedef struct {
	char * delim;
	unsigned int rows;
	unsigned int cols;
	char ** table;
} CSV;

/**
 * Utility function to trim whitespaces from left & right of a string
 */
int trim(char ** str) {
	int trimmed;
	int n;
	int len;

	len = strlen(*str);
	n = len - 1;
	/* from right */
	while((n>=0) && isspace((*str)[n])) {
		(*str)[n] = '\0';
		trimmed += 1;
		n--;
	}

	/* from left */
	n = 0;
	while((n < len) && (isspace((*str)[0]))) {
		(*str)[0] = '\0';
		*str = (*str)+1;
		trimmed += 1;
		n++;
	}
	return trimmed;
}

/**
 * De-allocate csv structure
 */
int csv_destroy(CSV * csv) {
	if (csv == NULL) { return 0; }
	if (csv->table != NULL) { free(csv->table); }
	if (csv->delim != NULL) { free(csv->delim); }
	free(csv);
	return 0;
}

/**
 * Allocate memory for a CSV structure
 */
CSV * csv_create(unsigned int cols, unsigned int rows) {
	CSV * csv;

	csv = malloc(sizeof(CSV));
	csv->rows = rows;
	csv->cols = cols;
	csv->delim = strdup(",");

	csv->table = malloc(sizeof(char *) * cols * rows);
	if (csv->table == NULL) { goto error; }

	memset(csv->table, 0, sizeof(char *) * cols * rows);

	return csv;

error:
	csv_destroy(csv);
	return NULL;
}

/**
 * Get value in CSV table at COL, ROW
 */
char * csv_get(CSV * csv, unsigned int col, unsigned int row) {
	unsigned int idx;
	idx = col + (row * csv->cols);
	return csv->table[idx];
}

/**
 * Set value in CSV table at COL, ROW
 */
int csv_set(CSV * csv, unsigned int col, unsigned int row, char * value) {
	unsigned int idx;
	idx = col + (row * csv->cols);
	csv->table[idx] = value;
	return 0;
}

void csv_display(CSV * csv) {
	int row, col;
	char * content;
	if ((csv->rows == 0) || (csv->cols==0)) {
		printf("[Empty table]\n");
		return ;
	}

	printf("\n[Table cols=%d rows=%d]\n", csv->cols, csv->rows);
	for (row=0; row<csv->rows; row++) {
		printf("[|");
		for (col=0; col<csv->cols; col++) {
			content = csv_get(csv, col, row);
            printf("%s\t|", content);
		}
        printf("]\n");
	}
	printf("\n");
}

/**
 * Resize CSV table
 */
int csv_resize(CSV * old_csv, unsigned int new_cols, unsigned int new_rows) {
	unsigned int cur_col,
				 cur_row,
				 max_cols,
				 max_rows;
	CSV * new_csv;
	char * content;
	bool in_old, in_new;

	/* Build a new (fake) csv */
	new_csv = csv_create(new_cols, new_rows);
	if (new_csv == NULL) { goto error; }

	new_csv->rows = new_rows;
	new_csv->cols = new_cols;

	max_cols = (new_cols > old_csv->cols)? new_cols : old_csv->cols;
	max_rows = (new_rows > old_csv->rows)? new_rows : old_csv->rows;

	for (cur_col=0; cur_col<max_cols; cur_col++) {
		for (cur_row=0; cur_row<max_rows; cur_row++) {
			in_old = (cur_col < old_csv->cols) && (cur_row < old_csv->rows);
			in_new = (cur_col < new_csv->cols) && (cur_row < new_csv->rows);

			if (in_old && in_new) {
				/* re-link data */
				content = csv_get(old_csv, cur_col, cur_row);
				csv_set(new_csv, cur_col, cur_row, content);
			} else if (in_old) {
				/* destroy data */
				content = csv_get(old_csv, cur_col, cur_row);
				free(content);
			} else { /* skip */ }
		}
	}
	/* on rows */
	free(old_csv->table);
	old_csv->rows = new_rows;
	old_csv->cols = new_cols;
	old_csv->table = new_csv->table;
	new_csv->table = NULL;
	csv_destroy(new_csv);

	return 0;

error:
	printf("Unable to resize CSV table: error %d - %s\n", errno, strerror(errno));
	return -1;
}

/**
 * Open CSV file and load its content into provided CSV structure
 **/
int csv_open(CSV * csv, char * filename) {
	FILE * fp;
	unsigned int m_rows;
	unsigned int m_cols, cols;
	char line[2048];
	char * lineptr;
	char * token;

	fp = fopen(filename, "r");
	if (fp == NULL) { goto error; }

	m_rows = 0;
	m_cols = 0;
	while(fgets(line, sizeof(line), fp) != NULL) {
 		m_rows += 1;
 		cols = 0;
 		lineptr = line;
 		while ((token = strtok(lineptr, csv->delim)) != NULL) {
 			lineptr = NULL;
 			trim(&token);
            cols += 1;
        	if (cols > m_cols) { m_cols = cols; }
            csv_resize(csv, m_cols, m_rows);
            csv_set(csv, cols-1, m_rows-1, strdup(token));
        }
	}

	fclose(fp);
	csv->rows = m_rows;
	csv->cols = m_cols;
	return 0;

error:
	fclose(fp);
	printf("Unable to open %s for reading.", filename);
	return -1;
}

/**
 * Open CSV file and save CSV structure content into it
 **/
int csv_save(CSV * csv, char * filename) {
	FILE * fp;
	int row, col;
	char * content;

	fp = fopen(filename, "w");
	for (row=0; row<csv->rows; row++) {
		for (col=0; col<csv->cols; col++) {
			content = csv_get(csv, col, row);
            fprintf(fp, "%s%s", content,
            		((col == csv->cols-1) ? "" : csv->delim) );
		}
        fprintf(fp, "\n");
	}

	fclose(fp);
	return 0;
}

/**
 * Test
 */
int main(int argc, char ** argv) {
	CSV * csv;

	printf("%s\n%s\n\n",TITLE, URL);

	csv = csv_create(0, 0);
	csv_open(csv, "fixtures/csv-data-manipulation.csv");
	csv_display(csv);

	csv_set(csv, 0, 0, "Column0");
	csv_set(csv, 1, 1, "100");
	csv_set(csv, 2, 2, "200");
	csv_set(csv, 3, 3, "300");
	csv_set(csv, 4, 4, "400");
	csv_display(csv);

	csv_save(csv, "tmp/csv-data-manipulation.result.csv");
	csv_destroy(csv);

	return 0;
}


CSV to HTML translation

Consider a simplified CSV format where all rows are separated by a newline
and all columns are separated by commas.

No commas are allowed as field data, but the data may contain
other characters and character sequences that would
normally be   ''escaped''   when converted to HTML

;Task:
Create a function that takes a string representation of the CSV data
and returns a text string of an HTML table representing the CSV data.

Use the following  data as the CSV text to convert, and show your output.
: Character,Speech
: The multitude,The messiah! Show us the messiah!
: Brians mother,Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!
: The multitude,Who are you?
: Brians mother,I'm his mother; that's who!
: The multitude,Behold his mother! Behold his mother!

;Extra credit:
''Optionally'' allow special formatting for the first row of the table as if it is the tables header row
(via  preferably; CSS if you must).

Solution:
#include <stdio.h>

const char *input =
	"Character,Speech\n"
	"The multitude,The messiah! Show us the messiah!\n"
	"Brians mother,<angry>Now you listen here! He's not the messiah; "
		"he's a very naughty boy! Now go away!</angry>\n"
	"The multitude,Who are you?\n"
	"Brians mother,I'm his mother; that's who!\n"
	"The multitude,Behold his mother! Behold his mother!";

int main()
{
	const char *s;
	printf("
\n
");
	for (s = input; *s; s++) {
		switch(*s) {
		case '\n': printf("
\n
"); break;
		case ',':  printf("	"); break;
		case '<':  printf("<"); break;
		case '>':  printf(">"); break;
		case '&':  printf("&"); break;
		default:   putchar(*s);
		}
	}
	puts("
\n
");

	return 0;
}


Calculating the value of e

Calculate the value of   ''e''.

(''e''   is also known as   ''Euler's number''   and   ''Napier's constant''.)

See details: Calculating the value of e

Solution:
#include <stdio.h>
#include <math.h>

int main(void)
{
    double e;

    puts("The double precision in C give about 15 significant digits.\n"
         "Values below are presented with 16 digits after the decimal point.\n");

    // The most direct way to compute Euler constant.
    //
    e = exp(1);
    printf("Euler constant e = %.16lf\n", e);

    // The fast and independed method: e = lim (1 + 1/n)**n
    //
    e = 1.0 + 0x1p-26;
    for (int i = 0; i < 26; i++)
        e *= e;
    printf("Euler constant e = %.16lf\n", e);

    // Taylor expansion e = 1 + 1/1 + 1/2 + 1/2/3 + 1/2/3/4 + 1/2/3/4/5 + ...
    // Actually Kahan summation may improve the accuracy, but is not necessary.
    //
    const int N = 1000;
    double a[1000];
    a[0] = 1.0;
    for (int i = 1; i < N; i++)
    {
        a[i] = a[i-1] / i;
    }
    e = 1.;
    for (int i = N - 1; i > 0; i--)
        e += a[i];
    printf("Euler constant e = %.16lf\n", e);

    return 0;
}


Call a function

Demonstrate the different syntax and semantics provided for calling a function.

This may include:
:*   Calling a function that requires no arguments
:*   Calling a function with a fixed number of arguments
:*   Calling a function with optional arguments
:*   Calling a function with a variable number of arguments
:*   Calling a function with named arguments
:*   Using a function in statement context
:*   Using a function in first-class context within an expression
:*   Obtaining the return value of a function
:*   Distinguishing built-in functions and user-defined functions
:*   Distinguishing subroutines and functions
;*   Stating whether arguments are passed by value or by reference
;*   Is partial application possible and how

This task is ''not'' about defining functions.

Solution:
/* function with no argument */
f();

/* fix number of arguments */
g(1, 2, 3);

/* Optional arguments: err...
   Feel free to make sense of the following.  I can't. */
int op_arg();
int main()
{
	op_arg(1);
	op_arg(1, 2);
	op_arg(1, 2, 3);
	return 0;
}
int op_arg(int a, int b)
{
	printf("%d %d %d\n", a, b, (&b)[1]);
	return a;
}  /* end of sensible code */

/* Variadic function: how the args list is handled solely depends on the function */
void h(int a, ...)
{
	va_list ap;
	va_start(ap);
	...
}
/* call it as: (if you feed it something it doesn't expect, don't count on it working) */
h(1, 2, 3, 4, "abcd", (void*)0);

/* named arguments: this is only possible through some pre-processor abuse
*/
struct v_args {
    int arg1;
    int arg2;
    char _sentinel;
};

void _v(struct v_args args)
{
    printf("%d, %d\n", args.arg1, args.arg2);
}

#define v(...) _v((struct v_args){__VA_ARGS__})

v(.arg2 = 5, .arg1 = 17); // prints "17,5"
/* NOTE the above implementation gives us optional typesafe optional arguments as well (unspecified arguments are initialized to zero)*/
v(.arg2=1); // prints "0,1"
v();  // prints "0,0"

/* as a first-class object (i.e. function pointer) */
printf("%p", f); /* that's the f() above */

/* return value */
double a = asin(1);

/* built-in functions: no such thing. Compiler may interally give special treatment
   to bread-and-butter functions such as memcpy(), but that's not a C built-in per se */

/* subroutines: no such thing. You can goto places, but I doubt that counts. */

/* Scalar values are passed by value by default. However, arrays are passed by reference. */
/* Pointers *sort of* work like references, though. */


Canonicalize CIDR

Implement a function or program that, given a range of IPv4 addresses in CIDR notation (dotted-decimal/network-bits), will return/output the same range in canonical form.

That is, the IP address portion of the output CIDR block must not contain any set (1) bits in the host part of the address.

;Example:
Given   '''87.70.141.1/22''',    your code should output    '''87.70.140.0/22'''

;Explanation:
An Internet Protocol version 4 address is a 32-bit value, conventionally represented as a number in base 256 using dotted-decimal notation, where each base-256 digit is given in decimal and the digits are separated by periods. Logically, this 32-bit value represents two components: the leftmost (most-significant) bits determine the network portion of the address, while the rightmost (least-significant) bits determine the host portion. Classless Internet Domain Routing block notation indicates where the boundary between these two components is for a given address by adding a slash followed by the number of bits in the network portion.

In general, CIDR blocks stand in for the entire set of IP addresses sharing the same network component, so it's common to see access control lists that specify individual IP addresses using /32 to indicate that only the one address is included. Software accepting this notation as input often expects it to be entered in canonical form, in which the host bits are all zeroes. But network admins sometimes skip this step and just enter the address of a specific host on the subnet with the network size, resulting in a non-canonical entry.

The example address, 87.70.141.1/22, represents binary 0101011101000110100011 / 0100000001, with the / indicating the network/host division. To canonicalize, clear all the bits to the right of the / and convert back to dotted decimal: 0101011101000110100011 / 0000000000 - 87.70.140.0.

;More examples for testing

        36.18.154.103/12    -  36.16.0.0/12
        62.62.197.11/29     -  62.62.197.8/29
        67.137.119.181/4    -  64.0.0.0/4
        161.214.74.21/24    -  161.214.74.0/24
        184.232.176.184/18  -  184.232.128.0/18

Solution:
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>

typedef struct cidr_tag {
    uint32_t address;
    unsigned int mask_length;
} cidr_t;

// Convert a string in CIDR format to an IPv4 address and netmask,
// if possible. Also performs CIDR canonicalization.
bool cidr_parse(const char* str, cidr_t* cidr) {
    int a, b, c, d, m;
    if (sscanf(str, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m) != 5)
        return false;
    if (m < 1 || m > 32
        || a < 0 || a > UINT8_MAX
        || b < 0 || b > UINT8_MAX
        || c < 0 || c > UINT8_MAX
        || d < 0 || d > UINT8_MAX)
        return false;
    uint32_t mask = ~((1 << (32 - m)) - 1);
    uint32_t address = (a << 24) + (b << 16) + (c << 8) + d;
    address &= mask;
    cidr->address = address;
    cidr->mask_length = m;
    return true;
}

// Write a string in CIDR notation into the supplied buffer.
void cidr_format(const cidr_t* cidr, char* str, size_t size) {
    uint32_t address = cidr->address;
    unsigned int d = address & UINT8_MAX;
    address >>= 8;
    unsigned int c = address & UINT8_MAX;
    address >>= 8;
    unsigned int b = address & UINT8_MAX;
    address >>= 8;
    unsigned int a = address & UINT8_MAX;
    snprintf(str, size, "%u.%u.%u.%u/%u", a, b, c, d,
             cidr->mask_length);
}

int main(int argc, char** argv) {
    const char* tests[] = {
        "87.70.141.1/22",
        "36.18.154.103/12",
        "62.62.197.11/29",
        "67.137.119.181/4",
        "161.214.74.21/24",
        "184.232.176.184/18"
    };
    for (int i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
        cidr_t cidr;
        if (cidr_parse(tests[i], &cidr)) {
            char out[32];
            cidr_format(&cidr, out, sizeof(out));
            printf("%-18s -> %s\n", tests[i], out);
        } else {
            fprintf(stderr, "%s: invalid CIDR\n", tests[i]);
        }
    }
    return 0;
}


Cartesian product of two or more lists

Show one or more idiomatic ways of generating the Cartesian product of two arbitrary lists in your language.

Demonstrate that your function/method correctly returns:
::{1, 2} x {3, 4} = {(1, 3), (1, 4), (2, 3), (2, 4)}

and, in contrast:
::{3, 4} x {1, 2} = {(3, 1), (3, 2), (4, 1), (4, 2)}

Also demonstrate, using your function/method, that the product of an empty list with any other list is empty.
:: {1, 2} x {} = {}
:: {} x {1, 2} = {}

For extra credit, show or write a function returning the n-ary product of an arbitrary number of lists, each of arbitrary length. Your function might, for example, accept a single argument which is itself a list of lists, and return the n-ary product of those lists.

Use your n-ary Cartesian product function to show the following products:
:: {1776, 1789} x {7, 12} x {4, 14, 23} x {0, 1}
:: {1, 2, 3} x {30} x {500, 100}
:: {1, 2, 3} x {} x {500, 100}

Solution:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>

void cartesianProduct(int** sets, int* setLengths, int* currentSet, int numSets, int times){
	int i,j;

	if(times==numSets){
		printf("(");
		for(i=0;i<times;i++){
			printf("%d,",currentSet[i]);
		}
		printf("\b),");
	}
	else{
		for(j=0;j<setLengths[times];j++){
			currentSet[times] = sets[times][j];
			cartesianProduct(sets,setLengths,currentSet,numSets,times+1);
		}
	}
}

void printSets(int** sets, int* setLengths, int numSets){
	int i,j;

	printf("\nNumber of sets : %d",numSets);

	for(i=0;i<numSets+1;i++){
		printf("\nSet %d : ",i+1);
		for(j=0;j<setLengths[i];j++){
			printf(" %d ",sets[i][j]);
		}
	}
}

void processInputString(char* str){
	int **sets, *currentSet, *setLengths, setLength, numSets = 0, i,j,k,l,start,counter=0;
	char *token,*holder,*holderToken;

	for(i=0;str[i]!=00;i++)
		if(str[i]=='x')
			numSets++;

	if(numSets==0){
			printf("\n%s",str);
			return;
	}

	currentSet = (int*)calloc(sizeof(int),numSets + 1);

	setLengths = (int*)calloc(sizeof(int),numSets + 1);

	sets = (int**)malloc((numSets + 1)*sizeof(int*));

	token = strtok(str,"x");

	while(token!=NULL){
		holder = (char*)malloc(strlen(token)*sizeof(char));

		j = 0;

		for(i=0;token[i]!=00;i++){
			if(token[i]>='0' && token[i]<='9')
				holder[j++] = token[i];
			else if(token[i]==',')
				holder[j++] = ' ';
		}
		holder[j] = 00;

		setLength = 0;

		for(i=0;holder[i]!=00;i++)
			if(holder[i]==' ')
				setLength++;

		if(setLength==0 && strlen(holder)==0){
			printf("\n{}");
			return;
		}

		setLengths[counter] = setLength+1;

		sets[counter] = (int*)malloc((1+setLength)*sizeof(int));

		k = 0;

		start = 0;

		for(l=0;holder[l]!=00;l++){
			if(holder[l+1]==' '||holder[l+1]==00){
				holderToken = (char*)malloc((l+1-start)*sizeof(char));
				strncpy(holderToken,holder + start,l+1-start);
				sets[counter][k++] = atoi(holderToken);
				start = l+2;
			}
		}

		counter++;
		token = strtok(NULL,"x");
	}

	printf("\n{");
	cartesianProduct(sets,setLengths,currentSet,numSets + 1,0);
	printf("\b}");

}

int main(int argC,char* argV[])
{
	if(argC!=2)
		printf("Usage : %s <Set product expression enclosed in double quotes>",argV[0]);
	else
		processInputString(argV[1]);

	return 0;
}


Catalan numbers/Pascal's triangle

Print out the first   '''15'''   Catalan numbers by extracting them from Pascal's triangle.

;See:
*   Catalan Numbers and the Pascal Triangle.      This method enables calculation of Catalan Numbers using only addition and subtraction.

*   Catalan's Triangle for a Number Triangle that generates Catalan Numbers using only addition.
*   Sequence A000108 on OEIS has a lot of information on Catalan Numbers.

;Related Tasks:
[[Pascal's triangle]]

Solution:
//This code implements the print of 15 first Catalan's Numbers
//Formula used:
//  __n__
//   | |  (n + k) / k  n>0
//   k=2

#include <stdio.h>
#include <stdlib.h>

//the number of Catalan's Numbers to be printed
const int N = 15;

int main()
{
    //loop variables (in registers)
    register int k, n;

    //necessarily ull for reach big values
    unsigned long long int num, den;

    //the nmmber
    int catalan;

    //the first is not calculated for the formula
    printf("1 ");

    //iterating from 2 to 15
    for (n=2; n<=N; ++n) {
        //initializaing for products
        num = den = 1;
        //applying the formula
        for (k=2; k<=n; ++k) {
            num *= (n+k);
            den *= k;
            catalan = num /den;
        }

        //output
        printf("%d ", catalan);
    }

    //the end
    printf("\n");
    return 0;
}


Catamorphism

''Reduce'' is a function or method that is used to take the values in an array or a list and apply a function to successive members of the list to produce (or reduce them to), a single value.

;Task:
Show how ''reduce'' (or ''foldl'' or ''foldr'' etc), work (or would be implemented) in your language.

;See also:
* Wikipedia article:   Fold
* Wikipedia article:   Catamorphism

Solution:
#include <stdio.h>

typedef int (*intFn)(int, int);

int reduce(intFn fn, int size, int *elms)
{
    int i, val = *elms;
    for (i = 1; i < size; ++i)
        val = fn(val, elms[i]);
    return val;
}

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }

int main(void)
{
    int nums[] = {1, 2, 3, 4, 5};
    printf("%d\n", reduce(add, 5, nums));
    printf("%d\n", reduce(sub, 5, nums));
    printf("%d\n", reduce(mul, 5, nums));
    return 0;
}


Chaos game

The Chaos Game is a method of generating the attractor of an iterated function system (IFS).

One of the best-known and simplest examples creates a fractal, using a polygon and an initial point selected at random.

;Task
Play the Chaos Game using the corners of an equilateral triangle as the reference points.   Add a starting point at random (preferably inside the triangle).   Then add the next point halfway between the starting point and one of the reference points.   This reference point is chosen at random.

After a sufficient number of iterations, the image of a Sierpinski Triangle should emerge.

;See also
* The Game of Chaos

Solution:
#include<graphics.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<time.h>

#define pi M_PI

int main(){

	time_t t;
	double side, vertices[3][3],seedX,seedY,windowSide;
	int i,iter,choice;

	printf("Enter triangle side length : ");
	scanf("%lf",&side);

	printf("Enter number of iterations : ");
	scanf("%d",&iter);

	windowSide = 10 + 2*side;

	initwindow(windowSide,windowSide,"Sierpinski Chaos");

	for(i=0;i<3;i++){
		vertices[i][0] = windowSide/2 + side*cos(i*2*pi/3);
		vertices[i][1] = windowSide/2 + side*sin(i*2*pi/3);
		putpixel(vertices[i][0],vertices[i][1],15);
	}

	srand((unsigned)time(&t));

	seedX = rand()%(int)(vertices[0][0]/2 + (vertices[1][0] + vertices[2][0])/4);
	seedY = rand()%(int)(vertices[0][1]/2 + (vertices[1][1] + vertices[2][1])/4);

	putpixel(seedX,seedY,15);

	for(i=0;i<iter;i++){
		choice = rand()%3;

		seedX = (seedX + vertices[choice][0])/2;
		seedY = (seedY + vertices[choice][1])/2;

		putpixel(seedX,seedY,15);
	}

	getch();

	closegraph();

	return 0;
}


Check input device is a terminal

Demonstrate how to check whether the input device is a terminal or not.

;Related task:
*   [[Check output device is a terminal]]

Solution:
#include <unistd.h>	//for isatty()
#include <stdio.h>	//for fileno()

int main(void)
{
	puts(isatty(fileno(stdin))
		? "stdin is tty"
		: "stdin is not tty");
	return 0;
}


Check output device is a terminal

Demonstrate how to check whether the output device is a terminal or not.

;Related task:
*   [[Check input device is a terminal]]

Solution:
#include <unistd.h>   // for isatty()
#include <stdio.h>    // for fileno()

int main()
{
    puts(isatty(fileno(stdout))
          ? "stdout is tty"
          : "stdout is not tty");
    return 0;
}


Chinese remainder theorem

Suppose   n_1,   n_2,   \ldots,   n_k   are positive [[integer]]s that are pairwise co-prime.

Then, for any given sequence of integers   a_1,   a_2,   \dots,   a_k,   there exists an integer   x   solving the following system of simultaneous congruences:

::: \begin{align}
  x &\equiv a_1 \pmod{n_1} \\
  x &\equiv a_2 \pmod{n_2} \\
    &{}\  \  \vdots \\
  x &\equiv a_k \pmod{n_k}
\end{align}

Furthermore, all solutions   x   of this system are congruent modulo the product,    N=n_1n_2\ldots n_k.

;Task:
Write a program to solve a system of linear congruences by applying the   Chinese Remainder Theorem.

If the system of equations cannot be solved, your program must somehow indicate this.

(It may throw an exception or return a special false value.)

Since there are infinitely many solutions, the program should return the unique solution   s   where   0 \leq s \leq n_1n_2\ldots n_k.

''Show the functionality of this program'' by printing the result such that the   n's   are   [3,5,7]   and the   a's   are   [2,3,2].

'''Algorithm''':   The following algorithm only applies if the   n_i's   are pairwise co-prime.

Suppose, as above, that a solution is required for the system of congruences:

::: x \equiv a_i \pmod{n_i} \quad\mathrm{for}\; i = 1, \ldots, k

Again, to begin, the product   N = n_1n_2 \ldots n_k   is defined.

Then a solution   x   can be found as follows:

For each   i,   the integers   n_i   and   N/n_i   are co-prime.

Using the   Extended Euclidean algorithm,   we can find integers   r_i   and   s_i   such that   r_i n_i + s_i N/n_i = 1.

Then, one solution to the system of simultaneous congruences is:

::: x = \sum_{i=1}^k a_i s_i N/n_i

and the minimal solution,

::: x \pmod{N}.

Solution:
#include <stdio.h>

// returns x where (a * x) % b == 1
int mul_inv(int a, int b)
{
	int b0 = b, t, q;
	int x0 = 0, x1 = 1;
	if (b == 1) return 1;
	while (a > 1) {
		q = a / b;
		t = b, b = a % b, a = t;
		t = x0, x0 = x1 - q * x0, x1 = t;
	}
	if (x1 < 0) x1 += b0;
	return x1;
}

int chinese_remainder(int *n, int *a, int len)
{
	int p, i, prod = 1, sum = 0;

	for (i = 0; i < len; i++) prod *= n[i];

	for (i = 0; i < len; i++) {
		p = prod / n[i];
		sum += a[i] * mul_inv(p, n[i]) * p;
	}

	return sum % prod;
}

int main(void)
{
	int n[] = { 3, 5, 7 };
	int a[] = { 2, 3, 2 };

	printf("%d\n", chinese_remainder(n, a, sizeof(n)/sizeof(n[0])));
	return 0;
}


Circles of given radius through two points

2 circles with a given radius through 2 points in 2D space.

Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.
;Exceptions:
# r==0.0 should be treated as never describing circles (except in the case where the points are coincident).
# If the points are coincident then an infinite number of circles with the point on their circumference can be drawn, unless r==0.0 as well which then collapses the circles to a point.
# If the points form a diameter then return two identical circles ''or'' return a single circle, according to which is the most natural mechanism for the implementation language.
# If the points are too far apart then no circles can be drawn.

;Task detail:
* Write a function/subroutine/method/... that takes two points and a radius and returns the two circles through those points, ''or some indication of special cases where two, possibly equal, circles cannot be returned''.
* Show here the output for the following inputs:

      p1                p2           r
0.1234, 0.9876    0.8765, 0.2345    2.0
0.0000, 2.0000    0.0000, 0.0000    1.0
0.1234, 0.9876    0.1234, 0.9876    2.0
0.1234, 0.9876    0.8765, 0.2345    0.5
0.1234, 0.9876    0.1234, 0.9876    0.0

;Related task:
*   [[Total circles area]].

;See also:
*   Finding the Center of a Circle from 2 Points and Radius from Math forum @ Drexel

Solution:
#include<stdio.h>
#include<math.h>

typedef struct{
	double x,y;
	}point;

double distance(point p1,point p2)
{
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

void findCircles(point p1,point p2,double radius)
{
	double separation = distance(p1,p2),mirrorDistance;

	if(separation == 0.0)
	{
		radius == 0.0 ? printf("\nNo circles can be drawn through (%.4f,%.4f)",p1.x,p1.y):
							 printf("\nInfinitely many circles can be drawn through (%.4f,%.4f)",p1.x,p1.y);
	}

	else if(separation == 2*radius)
	{
		printf("\nGiven points are opposite ends of a diameter of the circle with center (%.4f,%.4f) and radius %.4f",(p1.x+p2.x)/2,(p1.y+p2.y)/2,radius);
	}

	else if(separation > 2*radius)
	{
		printf("\nGiven points are farther away from each other than a diameter of a circle with radius %.4f",radius);
	}

	else
	{
		mirrorDistance =sqrt(pow(radius,2) - pow(separation/2,2));

		printf("\nTwo circles are possible.");
		printf("\nCircle C1 with center (%.4f,%.4f), radius %.4f and Circle C2 with center (%.4f,%.4f), radius %.4f",(p1.x+p2.x)/2 + mirrorDistance*(p1.y-p2.y)/separation,(p1.y+p2.y)/2 + mirrorDistance*(p2.x-p1.x)/separation,radius,(p1.x+p2.x)/2 - mirrorDistance*(p1.y-p2.y)/separation,(p1.y+p2.y)/2 - mirrorDistance*(p2.x-p1.x)/separation,radius);
	}
}

int main()
{
    int i;

    point cases[] =
    {	{0.1234, 0.9876},    {0.8765, 0.2345},
	{0.0000, 2.0000},    {0.0000, 0.0000},
	{0.1234, 0.9876},    {0.1234, 0.9876},
	{0.1234, 0.9876},    {0.8765, 0.2345},
	{0.1234, 0.9876},    {0.1234, 0.9876}
    };

    double radii[] = {2.0,1.0,2.0,0.5,0.0};

    for(i=0;i<5;i++)
    {
	printf("\nCase %d)",i+1);
	findCircles(cases[2*i],cases[2*i+1],radii[i]);
    }

    return 0;
}


Closures/Value capture

Create a list of ten functions, in the simplest manner possible   (anonymous functions are encouraged),   such that the function at index   '' i ''    (you may choose to start    '' i ''    from either    '''0'''    or    '''1'''),     when run, should return the square of the index,   that is,    '' i '' 2.

Display the result of running any but the last function, to demonstrate that the function indeed remembers its value.

;Goal:
Demonstrate how to create a series of independent closures based on the same template but maintain separate copies of the variable closed over.

In imperative languages, one would generally use a loop with a mutable counter variable.

For each function to maintain the correct number, it has to capture the ''value'' of the variable at the time it was created, rather than just a reference to the variable, which would have a different value by the time the function was run.

See also: [[Multiple distinct objects]]

Solution:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>

typedef int (*f_int)();

#define TAG 0xdeadbeef
int _tmpl() {
	volatile int x = TAG;
	return x * x;
}

#define PROT (PROT_EXEC | PROT_WRITE)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS)
f_int dupf(int v)
{
	size_t len = (void*)dupf - (void*)_tmpl;
	f_int ret = mmap(NULL, len, PROT, FLAGS, 0, 0);
	char *p;
	if(ret == MAP_FAILED) {
		perror("mmap");
		exit(-1);
	}
	memcpy(ret, _tmpl, len);
	for (p = (char*)ret; p < (char*)ret + len - sizeof(int); p++)
		if (*(int *)p == TAG) *(int *)p = v;
	return ret;
}

int main()
{
	f_int funcs[10];
	int i;
	for (i = 0; i < 10; i++) funcs[i] = dupf(i);

	for (i = 0; i < 9; i++)
		printf("func[%d]: %d\n", i, funcs[i]());

	return 0;
}


Colorful numbers

A '''colorful number''' is a non-negative base 10 integer where the product of every sub group of consecutive digits is unique.

;E.G.

24753 is a colorful number. 2, 4, 7, 5, 3, (2x4)8, (4x7)28, (7x5)35, (5x3)15, (2x4x7)56, (4x7x5)140, (7x5x3)105, (2x4x7x5)280, (4x7x5x3)420, (2x4x7x5x3)840

Every product is unique.

2346 is '''not''' a colorful number. 2, 3, 4, '''6''', (2x3)'''6''', (3x4)12, (4x6)24, (2x3x4)48, (3x4x6)72, (2x3x4x6)144

The product '''6''' is repeated.

Single digit numbers '''are''' considered to be colorful. A colorful number larger than 9 cannot contain a repeated digit, the digit 0 or the digit 1. As a consequence, there is a firm upper limit for colorful numbers; no colorful number can have more than 8 digits.

;Task

* Write a routine (subroutine, function, procedure, whatever it may be called in your language) to test if a number is a colorful number or not.
* Use that routine to find all of the colorful numbers less than 100.
* Use that routine to find the largest possible colorful number.

;Stretch

* Find and display the count of colorful numbers in each order of magnitude.
* Find and show the total count of '''all''' colorful numbers.

''Colorful numbers have no real number theory application. They are more a recreational math puzzle than a useful tool.''

Solution:
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

bool colorful(int n) {
    // A colorful number cannot be greater than 98765432.
    if (n < 0 || n > 98765432)
        return false;
    int digit_count[10] = {};
    int digits[8] = {};
    int num_digits = 0;
    for (int m = n; m > 0; m /= 10) {
        int d = m % 10;
        if (n > 9 && (d == 0 || d == 1))
            return false;
        if (++digit_count[d] > 1)
            return false;
        digits[num_digits++] = d;
    }
    // Maximum number of products is (8 x 9) / 2.
    int products[36] = {};
    for (int i = 0, product_count = 0; i < num_digits; ++i) {
        for (int j = i, p = 1; j < num_digits; ++j) {
            p *= digits[j];
            for (int k = 0; k < product_count; ++k) {
                if (products[k] == p)
                    return false;
            }
            products[product_count++] = p;
        }
    }
    return true;
}

static int count[8];
static bool used[10];
static int largest = 0;

void count_colorful(int taken, int n, int digits) {
    if (taken == 0) {
        for (int d = 0; d < 10; ++d) {
            used[d] = true;
            count_colorful(d < 2 ? 9 : 1, d, 1);
            used[d] = false;
        }
    } else {
        if (colorful(n)) {
            ++count[digits - 1];
            if (n > largest)
                largest = n;
        }
        if (taken < 9) {
            for (int d = 2; d < 10; ++d) {
                if (!used[d]) {
                    used[d] = true;
                    count_colorful(taken + 1, n * 10 + d, digits + 1);
                    used[d] = false;
                }
            }
        }
    }
}

int main() {
    setlocale(LC_ALL, "");

    clock_t start = clock();

    printf("Colorful numbers less than 100:\n");
    for (int n = 0, count = 0; n < 100; ++n) {
        if (colorful(n))
            printf("%2d%c", n, ++count % 10 == 0 ? '\n' : ' ');
    }

    count_colorful(0, 0, 0);
    printf("\n\nLargest colorful number: %'d\n", largest);

    printf("\nCount of colorful numbers by number of digits:\n");
    int total = 0;
    for (int d = 0; d < 8; ++d) {
        printf("%d   %'d\n", d + 1, count[d]);
        total += count[d];
    }
    printf("\nTotal: %'d\n", total);

    clock_t end = clock();
    printf("\nElapsed time: %f seconds\n",
           (end - start + 0.0) / CLOCKS_PER_SEC);
    return 0;
}


Colour bars/Display

Display a series of vertical color bars across the width of the display.

The color bars should either use:
:::*   the system palette,   or
:::*   the sequence of colors:
::::::*   black
::::::*   red
::::::*   green
::::::*   blue
::::::*   magenta
::::::*   cyan
::::::*   yellow
::::::*   white

Solution:
#include<conio.h>

#define COLOURS 8

int main()
{
	int colour=0,i,j,MAXROW,MAXCOL;
	struct text_info tInfo;
	gettextinfo(&tInfo);
	MAXROW = tInfo.screenheight;
	MAXCOL = tInfo.screenwidth;
	textbackground(BLACK);     //8 colour constants are defined
	clrscr();

	for(colour=0;colour<COLOURS;colour++)
	{
		getch();                              //waits for a key hit
		gotoxy(1+colour*MAXCOL/COLOURS,1);
		textbackground(colour);
		for(j=0;j<MAXROW;j++){
			for(i=0;i<MAXCOL/COLOURS;i++){
				cprintf(" ");
			}
		gotoxy(1+colour*MAXCOL/COLOURS,1+j);
		}
	}

	getch();
	textbackground(BLACK);

	return 0;
}


Comma quibbling

Comma quibbling is a task originally set by Eric Lippert in his blog.

;Task:

Write a function to generate a string output which is the concatenation of input words from a list/sequence where:
# An input of no words produces the output string of just the two brace characters "{}".
# An input of just one word, e.g. ["ABC"], produces the output string of the word inside the two braces, e.g. "{ABC}".
# An input of two words, e.g. ["ABC", "DEF"], produces the output string of the two words inside the two braces with the words separated by the string " and ", e.g. "{ABC and DEF}".
# An input of three or more words, e.g. ["ABC", "DEF", "G", "H"], produces the output string of all but the last word separated by ", " with the last word separated by " and " and all within braces; e.g. "{ABC, DEF, G and H}".

Test your function with the following series of inputs showing your output here on this page:
* []                       # (No input words).
* ["ABC"]
* ["ABC", "DEF"]
* ["ABC", "DEF", "G", "H"]

Note: Assume words are non-empty strings of uppercase characters for this task.

Solution:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *quib(const char **strs, size_t size)
{

    size_t len = 3 + ((size > 1) ? (2 * size + 1) : 0);
    size_t i;

    for (i = 0; i < size; i++)
        len += strlen(strs[i]);

    char *s = malloc(len * sizeof(*s));
    if (!s)
    {
        perror("Can't allocate memory!\n");
        exit(EXIT_FAILURE);
    }

    strcpy(s, "{");
    switch (size) {
        case 0:  break;
        case 1:  strcat(s, strs[0]);
                 break;
        default: for (i = 0; i < size - 1; i++)
                 {
                     strcat(s, strs[i]);
                     if (i < size - 2)
                         strcat(s, ", ");
                     else
                         strcat(s, " and ");
                 }
                 strcat(s, strs[i]);
                 break;
    }
    strcat(s, "}");
    return s;
}

int main(void)
{
    const char *test[] = {"ABC", "DEF", "G", "H"};
    char *s;

    for (size_t i = 0; i < 5; i++)
    {
        s = quib(test, i);
        printf("%s\n", s);
        free(s);
    }
    return EXIT_SUCCESS;
}


Command-line arguments

{{selection|Short Circuit|Console Program Basics}} Retrieve the list of command-line arguments given to the program. For programs that only print the arguments when run directly, see [[Scripted main]].
See also [[Program name]].

For parsing command line arguments intelligently, see [[Parsing command-line arguments]].

Example command line:

 myprogram -c "alpha beta" -h "gamma"

Solution:
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
  int i;
  (void) printf("This program is named %s.\n", argv[0]);
  for (i = 1; i < argc; ++i)
    (void) printf("the argument #%d is %s\n", i, argv[i]);
  return EXIT_SUCCESS;
}


Compare a list of strings

Given a   list   of arbitrarily many strings, show how to:

*   test if they are all lexically '''equal'''
*   test if every string is lexically '''less than''' the one after it  ''(i.e. whether the list is in strict ascending order)''

Each of those two tests should result in a single true or false value, which could be used as the condition of an    if    statement or similar.

If the input list has less than two elements, the tests should always return true.

There is ''no'' need to provide a complete program and output.

Assume that the strings are already stored in an array/list/sequence/tuple variable (whatever is most idiomatic) with the name   strings,   and just show the expressions for performing those two tests on it (plus of course any includes and custom functions etc. that it needs),   with as little distractions as possible.

Try to write your solution in a way that does not modify the original list,   but if it does then please add a note to make that clear to readers.

If you need further guidance/clarification,   see [[#Perl]] and [[#Python]] for solutions that use implicit short-circuiting loops,   and [[#Raku]] for a solution that gets away with simply using a built-in language feature.

Solution:
#include <stdbool.h>
#include <string.h>

static bool
strings_are_equal(const char **strings, size_t nstrings)
{
    for (size_t i = 1; i < nstrings; i++)
        if (strcmp(strings[0], strings[i]) != 0)
            return false;
    return true;
}

static bool
strings_are_in_ascending_order(const char **strings, size_t nstrings)
{
    for (size_t i = 1; i < nstrings; i++)
        if (strcmp(strings[i - 1], strings[i]) >= 0)
            return false;
    return true;
}


Compile-time calculation

Some programming languages allow calculation of values at compile time.

;Task:
Calculate    10!    (ten factorial)   at compile time.

Print the result when the program is run.

Discuss what limitations apply to compile-time calculations in your language.

Solution:
#include <stdio.h>
#include <order/interpreter.h>

#define ORDER_PP_DEF_8fac ORDER_PP_FN( \
8fn(8X, 8seq_fold(8times, 1, 8seq_iota(1, 8inc(8X)))) )

int main(void) {
	printf("10! = %d\n", ORDER_PP( 8to_lit( 8fac(10) ) ) );
	return 0;
}


Compiler/AST interpreter

The C and Python versions can be considered reference implementations.

;Related Tasks

* Lexical Analyzer task
* Syntax Analyzer task
* Code Generator task
* Virtual Machine Interpreter task

__TOC__

Solution:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>

#define da_dim(name, type)  type *name = NULL;          \
                            int _qy_ ## name ## _p = 0;  \
                            int _qy_ ## name ## _max = 0
#define da_rewind(name)     _qy_ ## name ## _p = 0
#define da_redim(name)      do {if (_qy_ ## name ## _p >= _qy_ ## name ## _max) \
                                name = realloc(name, (_qy_ ## name ## _max += 32) * sizeof(name[0]));} while (0)
#define da_append(name, x)  do {da_redim(name); name[_qy_ ## name ## _p++] = x;} while (0)
#define da_len(name)        _qy_ ## name ## _p
#define da_add(name)        do {da_redim(name); _qy_ ## name ## _p++;} while (0)

typedef enum {
    nd_Ident, nd_String, nd_Integer, nd_Sequence, nd_If, nd_Prtc, nd_Prts, nd_Prti, nd_While,
    nd_Assign, nd_Negate, nd_Not, nd_Mul, nd_Div, nd_Mod, nd_Add, nd_Sub, nd_Lss, nd_Leq,
    nd_Gtr, nd_Geq, nd_Eql, nd_Neq, nd_And, nd_Or
} NodeType;

typedef struct Tree Tree;
struct Tree {
    NodeType node_type;
    Tree *left;
    Tree *right;
    int value;
};

// dependency: Ordered by NodeType, must remain in same order as NodeType enum

struct {
    char       *enum_text;
    NodeType   node_type;
} atr[] = {
    {"Identifier"  , nd_Ident,  },  {"String"      , nd_String,  },
    {"Integer"     , nd_Integer,},  {"Sequence"    , nd_Sequence,},
    {"If"          , nd_If,     },  {"Prtc"        , nd_Prtc,    },
    {"Prts"        , nd_Prts,   },  {"Prti"        , nd_Prti,    },
    {"While"       , nd_While,  },  {"Assign"      , nd_Assign,  },
    {"Negate"      , nd_Negate, },  {"Not"         , nd_Not,     },
    {"Multiply"    , nd_Mul,    },  {"Divide"      , nd_Div,     },
    {"Mod"         , nd_Mod,    },  {"Add"         , nd_Add,     },
    {"Subtract"    , nd_Sub,    },  {"Less"        , nd_Lss,     },
    {"LessEqual"   , nd_Leq,    },  {"Greater"     , nd_Gtr,     },
    {"GreaterEqual", nd_Geq,    },  {"Equal"       , nd_Eql,     },
    {"NotEqual"    , nd_Neq,    },  {"And"         , nd_And,     },
    {"Or"          , nd_Or,     },
};

FILE *source_fp;
da_dim(string_pool, const char *);
da_dim(global_names, const char *);
da_dim(global_values, int);

void error(const char *fmt, ... ) {
    va_list ap;
    char buf[1000];

    va_start(ap, fmt);
    vsprintf(buf, fmt, ap);
    printf("error: %s\n", buf);
    exit(1);
}

Tree *make_node(NodeType node_type, Tree *left, Tree *right) {
    Tree *t = calloc(sizeof(Tree), 1);
    t->node_type = node_type;
    t->left = left;
    t->right = right;
    return t;
}

Tree *make_leaf(NodeType node_type, int value) {
    Tree *t = calloc(sizeof(Tree), 1);
    t->node_type = node_type;
    t->value = value;
    return t;
}

int interp(Tree *x) {           /* interpret the parse tree */
    if (!x) return 0;
    switch(x->node_type) {
        case nd_Integer:  return x->value;
        case nd_Ident:    return global_values[x->value];
        case nd_String:   return x->value;

        case nd_Assign:   return global_values[x->left->value] = interp(x->right);
        case nd_Add:      return interp(x->left) +  interp(x->right);
        case nd_Sub:      return interp(x->left) -  interp(x->right);
        case nd_Mul:      return interp(x->left) *  interp(x->right);
        case nd_Div:      return interp(x->left) /  interp(x->right);
        case nd_Mod:      return interp(x->left) %  interp(x->right);
        case nd_Lss:      return interp(x->left) <  interp(x->right);
        case nd_Gtr:      return interp(x->left) >  interp(x->right);
        case nd_Leq:      return interp(x->left) <= interp(x->right);
        case nd_Eql:      return interp(x->left) == interp(x->right);
        case nd_Neq:      return interp(x->left) != interp(x->right);
        case nd_And:      return interp(x->left) && interp(x->right);
        case nd_Or:       return interp(x->left) || interp(x->right);
        case nd_Negate:   return -interp(x->left);
        case nd_Not:      return !interp(x->left);

        case nd_If:       if (interp(x->left))
                            interp(x->right->left);
                          else
                            interp(x->right->right);
                          return 0;

        case nd_While:    while (interp(x->left))
                            interp(x->right);
                          return 0;

        case nd_Prtc:     printf("%c", interp(x->left));
                          return 0;
        case nd_Prti:     printf("%d", interp(x->left));
                          return 0;
        case nd_Prts:     printf("%s", string_pool[interp(x->left)]);
                          return 0;

        case nd_Sequence: interp(x->left);
                          interp(x->right);
                          return 0;

        default:          error("interp: unknown tree type %d\n", x->node_type);
    }
    return 0;
}

void init_in(const char fn[]) {
    if (fn[0] == '\0')
        source_fp = stdin;
    else {
        source_fp = fopen(fn, "r");
        if (source_fp == NULL)
            error("Can't open %s\n", fn);
    }
}

NodeType get_enum_value(const char name[]) {
    for (size_t i = 0; i < sizeof(atr) / sizeof(atr[0]); i++) {
        if (strcmp(atr[i].enum_text, name) == 0) {
            return atr[i].node_type;
        }
    }
    error("Unknown token %s\n", name);
    return -1;
}

char *read_line(int *len) {
    static char *text = NULL;
    static int textmax = 0;

    for (*len = 0; ; (*len)++) {
        int ch = fgetc(source_fp);
        if (ch == EOF || ch == '\n') {
            if (*len == 0)
                return NULL;
            break;
        }
        if (*len + 1 >= textmax) {
            textmax = (textmax == 0 ? 128 : textmax * 2);
            text = realloc(text, textmax);
        }
        text[*len] = ch;
    }
    text[*len] = '\0';
    return text;
}

char *rtrim(char *text, int *len) {         // remove trailing spaces
    for (; *len > 0 && isspace(text[*len - 1]); --(*len))
        ;

    text[*len] = '\0';
    return text;
}

int fetch_string_offset(char *st) {
    int len = strlen(st);
    st[len - 1] = '\0';
    ++st;
    char *p, *q;
    p = q = st;

    while ((*p++ = *q++) != '\0') {
        if (q[-1] == '\\') {
            if (q[0] == 'n') {
                p[-1] = '\n';
                ++q;
            } else if (q[0] == '\\') {
                ++q;
            }
        }
    }

    for (int i = 0; i < da_len(string_pool); ++i) {
        if (strcmp(st, string_pool[i]) == 0) {
            return i;
        }
    }
    da_add(string_pool);
    int n = da_len(string_pool) - 1;
    string_pool[n] = strdup(st);
    return da_len(string_pool) - 1;
}

int fetch_var_offset(const char *name) {
    for (int i = 0; i < da_len(global_names); ++i) {
        if (strcmp(name, global_names[i]) == 0)
            return i;
    }
    da_add(global_names);
    int n = da_len(global_names) - 1;
    global_names[n] = strdup(name);
    da_append(global_values, 0);
    return n;
}

Tree *load_ast() {
    int len;
    char *yytext = read_line(&len);
    yytext = rtrim(yytext, &len);

    // get first token
    char *tok = strtok(yytext, " ");

    if (tok[0] == ';') {
        return NULL;
    }
    NodeType node_type = get_enum_value(tok);

    // if there is extra data, get it
    char *p = tok + strlen(tok);
    if (p != &yytext[len]) {
        int n;
        for (++p; isspace(*p); ++p)
            ;
        switch (node_type) {
            case nd_Ident:      n = fetch_var_offset(p);    break;
            case nd_Integer:    n = strtol(p, NULL, 0);     break;
            case nd_String:     n = fetch_string_offset(p); break;
            default:            error("Unknown node type: %s\n", p);
        }
        return make_leaf(node_type, n);
    }

    Tree *left  = load_ast();
    Tree *right = load_ast();
    return make_node(node_type, left, right);
}

int main(int argc, char *argv[]) {
    init_in(argc > 1 ? argv[1] : "");

    Tree *x = load_ast();
    interp(x);

    return 0;
}


Compiler/code generator

The C and Python versions can be considered reference implementations.

;Related Tasks

* Lexical Analyzer task
* Syntax Analyzer task
* Virtual Machine Interpreter task
* AST Interpreter task

__TOC__

Solution:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <ctype.h>

typedef unsigned char uchar;

typedef enum {
    nd_Ident, nd_String, nd_Integer, nd_Sequence, nd_If, nd_Prtc, nd_Prts, nd_Prti, nd_While,
    nd_Assign, nd_Negate, nd_Not, nd_Mul, nd_Div, nd_Mod, nd_Add, nd_Sub, nd_Lss, nd_Leq,
    nd_Gtr, nd_Geq, nd_Eql, nd_Neq, nd_And, nd_Or
} NodeType;

typedef enum { FETCH, STORE, PUSH, ADD, SUB, MUL, DIV, MOD, LT, GT, LE, GE, EQ, NE, AND,
    OR, NEG, NOT, JMP, JZ, PRTC, PRTS, PRTI, HALT
} Code_t;

typedef uchar code;

typedef struct Tree {
    NodeType node_type;
    struct Tree *left;
    struct Tree *right;
    char *value;
} Tree;

#define da_dim(name, type)  type *name = NULL;          \
                            int _qy_ ## name ## _p = 0;  \
                            int _qy_ ## name ## _max = 0

#define da_redim(name)      do {if (_qy_ ## name ## _p >= _qy_ ## name ## _max) \
                                name = realloc(name, (_qy_ ## name ## _max += 32) * sizeof(name[0]));} while (0)

#define da_rewind(name)     _qy_ ## name ## _p = 0

#define da_append(name, x)  do {da_redim(name); name[_qy_ ## name ## _p++] = x;} while (0)
#define da_len(name)        _qy_ ## name ## _p
#define da_add(name)        do {da_redim(name); _qy_ ## name ## _p++;} while (0)

FILE *source_fp, *dest_fp;
static int here;
da_dim(object, code);
da_dim(globals, const char *);
da_dim(string_pool, const char *);

// dependency: Ordered by NodeType, must remain in same order as NodeType enum
struct {
    char       *enum_text;
    NodeType   node_type;
    Code_t     opcode;
} atr[] = {
    {"Identifier"  , nd_Ident,    -1 },
    {"String"      , nd_String,   -1 },
    {"Integer"     , nd_Integer,  -1 },
    {"Sequence"    , nd_Sequence, -1 },
    {"If"          , nd_If,       -1 },
    {"Prtc"        , nd_Prtc,     -1 },
    {"Prts"        , nd_Prts,     -1 },
    {"Prti"        , nd_Prti,     -1 },
    {"While"       , nd_While,    -1 },
    {"Assign"      , nd_Assign,   -1 },
    {"Negate"      , nd_Negate,   NEG},
    {"Not"         , nd_Not,      NOT},
    {"Multiply"    , nd_Mul,      MUL},
    {"Divide"      , nd_Div,      DIV},
    {"Mod"         , nd_Mod,      MOD},
    {"Add"         , nd_Add,      ADD},
    {"Subtract"    , nd_Sub,      SUB},
    {"Less"        , nd_Lss,      LT },
    {"LessEqual"   , nd_Leq,      LE },
    {"Greater"     , nd_Gtr,      GT },
    {"GreaterEqual", nd_Geq,      GE },
    {"Equal"       , nd_Eql,      EQ },
    {"NotEqual"    , nd_Neq,      NE },
    {"And"         , nd_And,      AND},
    {"Or"          , nd_Or,       OR },
};

void error(const char *fmt, ... ) {
    va_list ap;
    char buf[1000];

    va_start(ap, fmt);
    vsprintf(buf, fmt, ap);
    va_end(ap);
    printf("error: %s\n", buf);
    exit(1);
}

Code_t type_to_op(NodeType type) {
    return atr[type].opcode;
}

Tree *make_node(NodeType node_type, Tree *left, Tree *right) {
    Tree *t = calloc(sizeof(Tree), 1);
    t->node_type = node_type;
    t->left = left;
    t->right = right;
    return t;
}

Tree *make_leaf(NodeType node_type, char *value) {
    Tree *t = calloc(sizeof(Tree), 1);
    t->node_type = node_type;
    t->value = strdup(value);
    return t;
}

/*** Code generator ***/

void emit_byte(int c) {
    da_append(object, (uchar)c);
    ++here;
}

void emit_int(int32_t n) {
    union {
        int32_t n;
        unsigned char c[sizeof(int32_t)];
    } x;

    x.n = n;

    for (size_t i = 0; i < sizeof(x.n); ++i) {
        emit_byte(x.c[i]);
    }
}

int hole() {
    int t = here;
    emit_int(0);
    return t;
}

void fix(int src, int dst) {
    *(int32_t *)(object + src) = dst-src;
}

int fetch_var_offset(const char *id) {
    for (int i = 0; i < da_len(globals); ++i) {
        if (strcmp(id, globals[i]) == 0)
            return i;
    }
    da_add(globals);
    int n = da_len(globals) - 1;
    globals[n] = strdup(id);
    return n;
}

int fetch_string_offset(const char *st) {
    for (int i = 0; i < da_len(string_pool); ++i) {
        if (strcmp(st, string_pool[i]) == 0)
            return i;
    }
    da_add(string_pool);
    int n = da_len(string_pool) - 1;
    string_pool[n] = strdup(st);
    return n;
}

void code_gen(Tree *x) {
    int p1, p2, n;

    if (x == NULL) return;
    switch (x->node_type) {
        case nd_Ident:
            emit_byte(FETCH);
            n = fetch_var_offset(x->value);
            emit_int(n);
            break;
        case nd_Integer:
            emit_byte(PUSH);
            emit_int(atoi(x->value));
            break;
        case nd_String:
            emit_byte(PUSH);
            n = fetch_string_offset(x->value);
            emit_int(n);
            break;
        case nd_Assign:
            n = fetch_var_offset(x->left->value);
            code_gen(x->right);
            emit_byte(STORE);
            emit_int(n);
            break;
        case nd_If:
            code_gen(x->left);        // if expr
            emit_byte(JZ);                  // if false, jump
            p1 = hole();                    // make room for jump dest
            code_gen(x->right->left);   // if true statements
            if (x->right->right != NULL) {
                emit_byte(JMP);
                p2 = hole();
            }
            fix(p1, here);
            if (x->right->right != NULL) {
                code_gen(x->right->right);
                fix(p2, here);
            }
            break;
        case nd_While:
            p1 = here;
            code_gen(x->left);        // while expr
            emit_byte(JZ);                  // if false, jump
            p2 = hole();                    // make room for jump dest
            code_gen(x->right);       // statements
            emit_byte(JMP);                 // back to the top
            fix(hole(), p1);                // plug the top
            fix(p2, here);                  // plug the 'if false, jump'
            break;
        case nd_Sequence:
            code_gen(x->left);
            code_gen(x->right);
            break;
        case nd_Prtc:
            code_gen(x->left);
            emit_byte(PRTC);
            break;
        case nd_Prti:
            code_gen(x->left);
            emit_byte(PRTI);
            break;
        case nd_Prts:
            code_gen(x->left);
            emit_byte(PRTS);
            break;
        case nd_Lss: case nd_Gtr: case nd_Leq: case nd_Geq: case nd_Eql: case nd_Neq:
        case nd_And: case nd_Or: case nd_Sub: case nd_Add: case nd_Div: case nd_Mul:
        case nd_Mod:
            code_gen(x->left);
            code_gen(x->right);
            emit_byte(type_to_op(x->node_type));
            break;
        case nd_Negate: case nd_Not:
            code_gen(x->left);
            emit_byte(type_to_op(x->node_type));
            break;
        default:
            error("error in code generator - found %d, expecting operator\n", x->node_type);
    }
}

void code_finish() {
    emit_byte(HALT);
}

void list_code() {
    fprintf(dest_fp, "Datasize: %d Strings: %d\n", da_len(globals), da_len(string_pool));
    for (int i = 0; i < da_len(string_pool); ++i)
        fprintf(dest_fp, "%s\n", string_pool[i]);

    code *pc = object;

    again: fprintf(dest_fp, "%5d ", (int)(pc - object));
    switch (*pc++) {
        case FETCH: fprintf(dest_fp, "fetch [%d]\n", *(int32_t *)pc);
                    pc += sizeof(int32_t);  goto again;
        case STORE: fprintf(dest_fp, "store [%d]\n", *(int32_t *)pc);
                    pc += sizeof(int32_t);  goto again;
        case PUSH : fprintf(dest_fp, "push  %d\n", *(int32_t *)pc);
                    pc += sizeof(int32_t);    goto again;
        case ADD  : fprintf(dest_fp, "add\n");      goto again;
        case SUB  : fprintf(dest_fp, "sub\n");      goto again;
        case MUL  : fprintf(dest_fp, "mul\n");      goto again;
        case DIV  : fprintf(dest_fp, "div\n");      goto again;
        case MOD  : fprintf(dest_fp, "mod\n");      goto again;
        case LT   : fprintf(dest_fp, "lt\n");       goto again;
        case GT   : fprintf(dest_fp, "gt\n");       goto again;
        case LE   : fprintf(dest_fp, "le\n");       goto again;
        case GE   : fprintf(dest_fp, "ge\n");       goto again;
        case EQ   : fprintf(dest_fp, "eq\n");       goto again;
        case NE   : fprintf(dest_fp, "ne\n");       goto again;
        case AND  : fprintf(dest_fp, "and\n");      goto again;
        case OR   : fprintf(dest_fp, "or\n");       goto again;
        case NOT  : fprintf(dest_fp, "not\n");      goto again;
        case NEG  : fprintf(dest_fp, "neg\n");      goto again;
        case JMP  : fprintf(dest_fp, "jmp    (%d) %d\n",
                        *(int32_t *)pc, (int32_t)(pc + *(int32_t *)pc - object));
                    pc += sizeof(int32_t); goto again;
        case JZ   : fprintf(dest_fp, "jz     (%d) %d\n",
                        *(int32_t *)pc, (int32_t)(pc + *(int32_t *)pc - object));
                    pc += sizeof(int32_t); goto again;
        case PRTC : fprintf(dest_fp, "prtc\n");     goto again;
        case PRTI : fprintf(dest_fp, "prti\n");     goto again;
        case PRTS : fprintf(dest_fp, "prts\n");     goto again;
        case HALT : fprintf(dest_fp, "halt\n");     break;
        default:error("listcode:Unknown opcode %d\n", *(pc - 1));
    }
}

void init_io(FILE **fp, FILE *std, const char mode[], const char fn[]) {
    if (fn[0] == '\0')
        *fp = std;
    else if ((*fp = fopen(fn, mode)) == NULL)
        error(0, 0, "Can't open %s\n", fn);
}

NodeType get_enum_value(const char name[]) {
    for (size_t i = 0; i < sizeof(atr) / sizeof(atr[0]); i++) {
        if (strcmp(atr[i].enum_text, name) == 0) {
            return atr[i].node_type;
        }
    }
    error("Unknown token %s\n", name);
    return -1;
}

char *read_line(int *len) {
    static char *text = NULL;
    static int textmax = 0;

    for (*len = 0; ; (*len)++) {
        int ch = fgetc(source_fp);
        if (ch == EOF || ch == '\n') {
            if (*len == 0)
                return NULL;
            break;
        }
        if (*len + 1 >= textmax) {
            textmax = (textmax == 0 ? 128 : textmax * 2);
            text = realloc(text, textmax);
        }
        text[*len] = ch;
    }
    text[*len] = '\0';
    return text;
}

char *rtrim(char *text, int *len) {         // remove trailing spaces
    for (; *len > 0 && isspace(text[*len - 1]); --(*len))
        ;

    text[*len] = '\0';
    return text;
}

Tree *load_ast() {
    int len;
    char *yytext = read_line(&len);
    yytext = rtrim(yytext, &len);

    // get first token
    char *tok = strtok(yytext, " ");

    if (tok[0] == ';') {
        return NULL;
    }
    NodeType node_type = get_enum_value(tok);

    // if there is extra data, get it
    char *p = tok + strlen(tok);
    if (p != &yytext[len]) {
        for (++p; isspace(*p); ++p)
            ;
        return make_leaf(node_type, p);
    }

    Tree *left  = load_ast();
    Tree *right = load_ast();
    return make_node(node_type, left, right);
}

int main(int argc, char *argv[]) {
    init_io(&source_fp, stdin,  "r",  argc > 1 ? argv[1] : "");
    init_io(&dest_fp,   stdout, "wb", argc > 2 ? argv[2] : "");

    code_gen(load_ast());
    code_finish();
    list_code();

    return 0;
}