Compiler/lexical analyzer

The C and Python versions can be considered reference implementations.

;Related Tasks
* Syntax Analyzer task
* Code Generator task
* Virtual Machine Interpreter task
* AST Interpreter task

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

#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))

#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

typedef enum {
    tk_EOI, tk_Mul, tk_Div, tk_Mod, tk_Add, tk_Sub, tk_Negate, tk_Not, tk_Lss, tk_Leq,
    tk_Gtr, tk_Geq, tk_Eq, tk_Neq, tk_Assign, tk_And, tk_Or, tk_If, tk_Else, tk_While,
    tk_Print, tk_Putc, tk_Lparen, tk_Rparen, tk_Lbrace, tk_Rbrace, tk_Semi, tk_Comma,
    tk_Ident, tk_Integer, tk_String
} TokenType;

typedef struct {
    TokenType tok;
    int err_ln, err_col;
    union {
        int n;                  /* value for constants */
        char *text;             /* text for idents */
    };
} tok_s;

static FILE *source_fp, *dest_fp;
static int line = 1, col = 0, the_ch = ' ';
da_dim(text, char);

tok_s gettok(void);

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

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

static int next_ch(void) {     /* get next char from input */
    the_ch = getc(source_fp);
    ++col;
    if (the_ch == '\n') {
        ++line;
        col = 0;
    }
    return the_ch;
}

static tok_s char_lit(int n, int err_line, int err_col) {   /* 'x' */
    if (the_ch == '\'')
        error(err_line, err_col, "gettok: empty character constant");
    if (the_ch == '\\') {
        next_ch();
        if (the_ch == 'n')
            n = 10;
        else if (the_ch == '\\')
            n = '\\';
        else error(err_line, err_col, "gettok: unknown escape sequence \\%c", the_ch);
    }
    if (next_ch() != '\'')
        error(err_line, err_col, "multi-character constant");
    next_ch();
    return (tok_s){tk_Integer, err_line, err_col, {n}};
}

static tok_s div_or_cmt(int err_line, int err_col) { /* process divide or comments */
    if (the_ch != '*')
        return (tok_s){tk_Div, err_line, err_col, {0}};

    /* comment found */
    next_ch();
    for (;;) {
        if (the_ch == '*') {
            if (next_ch() == '/') {
                next_ch();
                return gettok();
            }
        } else if (the_ch == EOF)
            error(err_line, err_col, "EOF in comment");
        else
            next_ch();
    }
}

static tok_s string_lit(int start, int err_line, int err_col) { /* "st" */
    da_rewind(text);

    while (next_ch() != start) {
        if (the_ch == '\n') error(err_line, err_col, "EOL in string");
        if (the_ch == EOF)  error(err_line, err_col, "EOF in string");
        da_append(text, (char)the_ch);
    }
    da_append(text, '\0');

    next_ch();
    return (tok_s){tk_String, err_line, err_col, {.text=text}};
}

static int kwd_cmp(const void *p1, const void *p2) {
    return strcmp(*(char **)p1, *(char **)p2);
}

static TokenType get_ident_type(const char *ident) {
    static struct {
        const char *s;
        TokenType sym;
    } kwds[] = {
        {"else",  tk_Else},
        {"if",    tk_If},
        {"print", tk_Print},
        {"putc",  tk_Putc},
        {"while", tk_While},
    }, *kwp;

    return (kwp = bsearch(&ident, kwds, NELEMS(kwds), sizeof(kwds[0]), kwd_cmp)) == NULL ? tk_Ident : kwp->sym;
}

static tok_s ident_or_int(int err_line, int err_col) {
    int n, is_number = true;

    da_rewind(text);
    while (isalnum(the_ch) || the_ch == '_') {
        da_append(text, (char)the_ch);
        if (!isdigit(the_ch))
            is_number = false;
        next_ch();
    }
    if (da_len(text) == 0)
        error(err_line, err_col, "gettok: unrecognized character (%d) '%c'\n", the_ch, the_ch);
    da_append(text, '\0');
    if (isdigit(text[0])) {
        if (!is_number)
            error(err_line, err_col, "invalid number: %s\n", text);
        n = strtol(text, NULL, 0);
        if (n == LONG_MAX && errno == ERANGE)
            error(err_line, err_col, "Number exceeds maximum value");
        return (tok_s){tk_Integer, err_line, err_col, {n}};
    }
    return (tok_s){get_ident_type(text), err_line, err_col, {.text=text}};
}

static tok_s follow(int expect, TokenType ifyes, TokenType ifno, int err_line, int err_col) {   /* look ahead for '>=', etc. */
    if (the_ch == expect) {
        next_ch();
        return (tok_s){ifyes, err_line, err_col, {0}};
    }
    if (ifno == tk_EOI)
        error(err_line, err_col, "follow: unrecognized character '%c' (%d)\n", the_ch, the_ch);
    return (tok_s){ifno, err_line, err_col, {0}};
}

tok_s gettok(void) {            /* return the token type */
    /* skip white space */
    while (isspace(the_ch))
        next_ch();
    int err_line = line;
    int err_col  = col;
    switch (the_ch) {
        case '{':  next_ch(); return (tok_s){tk_Lbrace, err_line, err_col, {0}};
        case '}':  next_ch(); return (tok_s){tk_Rbrace, err_line, err_col, {0}};
        case '(':  next_ch(); return (tok_s){tk_Lparen, err_line, err_col, {0}};
        case ')':  next_ch(); return (tok_s){tk_Rparen, err_line, err_col, {0}};
        case '+':  next_ch(); return (tok_s){tk_Add, err_line, err_col, {0}};
        case '-':  next_ch(); return (tok_s){tk_Sub, err_line, err_col, {0}};
        case '*':  next_ch(); return (tok_s){tk_Mul, err_line, err_col, {0}};
        case '%':  next_ch(); return (tok_s){tk_Mod, err_line, err_col, {0}};
        case ';':  next_ch(); return (tok_s){tk_Semi, err_line, err_col, {0}};
        case ',':  next_ch(); return (tok_s){tk_Comma,err_line, err_col, {0}};
        case '/':  next_ch(); return div_or_cmt(err_line, err_col);
        case '\'': next_ch(); return char_lit(the_ch, err_line, err_col);
        case '<':  next_ch(); return follow('=', tk_Leq, tk_Lss,    err_line, err_col);
        case '>':  next_ch(); return follow('=', tk_Geq, tk_Gtr,    err_line, err_col);
        case '=':  next_ch(); return follow('=', tk_Eq,  tk_Assign, err_line, err_col);
        case '!':  next_ch(); return follow('=', tk_Neq, tk_Not,    err_line, err_col);
        case '&':  next_ch(); return follow('&', tk_And, tk_EOI,    err_line, err_col);
        case '|':  next_ch(); return follow('|', tk_Or,  tk_EOI,    err_line, err_col);
        case '"' : return string_lit(the_ch, err_line, err_col);
        default:   return ident_or_int(err_line, err_col);
        case EOF:  return (tok_s){tk_EOI, err_line, err_col, {0}};
    }
}

void run(void) {    /* tokenize the given input */
    tok_s tok;
    do {
        tok = gettok();
        fprintf(dest_fp, "%5d  %5d %.15s",
            tok.err_ln, tok.err_col,
            &"End_of_input    Op_multiply     Op_divide       Op_mod          Op_add          "
             "Op_subtract     Op_negate       Op_not          Op_less         Op_lessequal    "
             "Op_greater      Op_greaterequal Op_equal        Op_notequal     Op_assign       "
             "Op_and          Op_or           Keyword_if      Keyword_else    Keyword_while   "
             "Keyword_print   Keyword_putc    LeftParen       RightParen      LeftBrace       "
             "RightBrace      Semicolon       Comma           Identifier      Integer         "
             "String          "
            [tok.tok * 16]);
        if (tok.tok == tk_Integer)     fprintf(dest_fp, "  %4d",   tok.n);
        else if (tok.tok == tk_Ident)  fprintf(dest_fp, " %s",     tok.text);
        else if (tok.tok == tk_String) fprintf(dest_fp, " \"%s\"", tok.text);
        fprintf(dest_fp, "\n");
    } while (tok.tok != tk_EOI);
    if (dest_fp != stdout)
        fclose(dest_fp);
}

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);
}

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] : "");
    run();
    return 0;
}


Compiler/syntax analyzer

The C and Python versions can be considered reference implementations.

;Related Tasks

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

__TOC__

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

#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))

typedef enum {
    tk_EOI, tk_Mul, tk_Div, tk_Mod, tk_Add, tk_Sub, tk_Negate, tk_Not, tk_Lss, tk_Leq, tk_Gtr,
    tk_Geq, tk_Eql, tk_Neq, tk_Assign, tk_And, tk_Or, tk_If, tk_Else, tk_While, tk_Print,
    tk_Putc, tk_Lparen, tk_Rparen, tk_Lbrace, tk_Rbrace, tk_Semi, tk_Comma, tk_Ident,
    tk_Integer, tk_String
} TokenType;

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 {
    TokenType tok;
    int err_ln;
    int err_col;
    char *text;             /* ident or string literal or integer value */
} tok_s;

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

// dependency: Ordered by tok, must remain in same order as TokenType enum
struct {
    char       *text, *enum_text;
    TokenType   tok;
    bool        right_associative, is_binary, is_unary;
    int         precedence;
    NodeType    node_type;
} atr[] = {
    {"EOI",             "End_of_input"   , tk_EOI,     false, false, false, -1, -1        },
    {"*",               "Op_multiply"    , tk_Mul,     false, true,  false, 13, nd_Mul    },
    {"/",               "Op_divide"      , tk_Div,     false, true,  false, 13, nd_Div    },
    {"%",               "Op_mod"         , tk_Mod,     false, true,  false, 13, nd_Mod    },
    {"+",               "Op_add"         , tk_Add,     false, true,  false, 12, nd_Add    },
    {"-",               "Op_subtract"    , tk_Sub,     false, true,  false, 12, nd_Sub    },
    {"-",               "Op_negate"      , tk_Negate,  false, false, true,  14, nd_Negate },
    {"!",               "Op_not"         , tk_Not,     false, false, true,  14, nd_Not    },
    {"<",               "Op_less"        , tk_Lss,     false, true,  false, 10, nd_Lss    },
    {"<=",              "Op_lessequal"   , tk_Leq,     false, true,  false, 10, nd_Leq    },
    {">",               "Op_greater"     , tk_Gtr,     false, true,  false, 10, nd_Gtr    },
    {">=",              "Op_greaterequal", tk_Geq,     false, true,  false, 10, nd_Geq    },
    {"==",              "Op_equal"       , tk_Eql,     false, true,  false,  9, nd_Eql    },
    {"!=",              "Op_notequal"    , tk_Neq,     false, true,  false,  9, nd_Neq    },
    {"=",               "Op_assign"      , tk_Assign,  false, false, false, -1, nd_Assign },
    {"&&",              "Op_and"         , tk_And,     false, true,  false,  5, nd_And    },
    {"||",              "Op_or"          , tk_Or,      false, true,  false,  4, nd_Or     },
    {"if",              "Keyword_if"     , tk_If,      false, false, false, -1, nd_If     },
    {"else",            "Keyword_else"   , tk_Else,    false, false, false, -1, -1        },
    {"while",           "Keyword_while"  , tk_While,   false, false, false, -1, nd_While  },
    {"print",           "Keyword_print"  , tk_Print,   false, false, false, -1, -1        },
    {"putc",            "Keyword_putc"   , tk_Putc,    false, false, false, -1, -1        },
    {"(",               "LeftParen"      , tk_Lparen,  false, false, false, -1, -1        },
    {")",               "RightParen"     , tk_Rparen,  false, false, false, -1, -1        },
    {"{",               "LeftBrace"      , tk_Lbrace,  false, false, false, -1, -1        },
    {"}",               "RightBrace"     , tk_Rbrace,  false, false, false, -1, -1        },
    {";",               "Semicolon"      , tk_Semi,    false, false, false, -1, -1        },
    {",",               "Comma"          , tk_Comma,   false, false, false, -1, -1        },
    {"Ident",           "Identifier"     , tk_Ident,   false, false, false, -1, nd_Ident  },
    {"Integer literal", "Integer"        , tk_Integer, false, false, false, -1, nd_Integer},
    {"String literal",  "String"         , tk_String,  false, false, false, -1, nd_String },
};

char *Display_nodes[] = {"Identifier", "String", "Integer", "Sequence", "If", "Prtc",
    "Prts", "Prti", "While", "Assign", "Negate", "Not", "Multiply", "Divide", "Mod",
    "Add", "Subtract", "Less", "LessEqual", "Greater", "GreaterEqual", "Equal",
    "NotEqual", "And", "Or"};

static tok_s tok;
static FILE *source_fp, *dest_fp;

Tree *paren_expr();

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

    va_start(ap, fmt);
    vsprintf(buf, fmt, ap);
    va_end(ap);
    printf("(%d, %d) error: %s\n", err_line, err_col, buf);
    exit(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;
}

TokenType get_enum(const char *name) {      // return internal version of name
    for (size_t i = 0; i < NELEMS(atr); i++) {
        if (strcmp(atr[i].enum_text, name) == 0)
            return atr[i].tok;
    }
    error(0, 0, "Unknown token %s\n", name);
    return 0;
}

tok_s gettok() {
    int len;
    tok_s tok;
    char *yytext = read_line(&len);
    yytext = rtrim(yytext, &len);

    // [ ]*{lineno}[ ]+{colno}[ ]+token[ ]+optional

    // get line and column
    tok.err_ln  = atoi(strtok(yytext, " "));
    tok.err_col = atoi(strtok(NULL, " "));

    // get the token name
    char *name = strtok(NULL, " ");
    tok.tok = get_enum(name);

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

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;
}

void expect(const char msg[], TokenType s) {
    if (tok.tok == s) {
        tok = gettok();
        return;
    }
    error(tok.err_ln, tok.err_col, "%s: Expecting '%s', found '%s'\n", msg, atr[s].text, atr[tok.tok].text);
}

Tree *expr(int p) {
    Tree *x = NULL, *node;
    TokenType op;

    switch (tok.tok) {
        case tk_Lparen:
            x = paren_expr();
            break;
        case tk_Sub: case tk_Add:
            op = tok.tok;
            tok = gettok();
            node = expr(atr[tk_Negate].precedence);
            x = (op == tk_Sub) ? make_node(nd_Negate, node, NULL) : node;
            break;
        case tk_Not:
            tok = gettok();
            x = make_node(nd_Not, expr(atr[tk_Not].precedence), NULL);
            break;
        case tk_Ident:
            x = make_leaf(nd_Ident, tok.text);
            tok = gettok();
            break;
        case tk_Integer:
            x = make_leaf(nd_Integer, tok.text);
            tok = gettok();
            break;
        default:
            error(tok.err_ln, tok.err_col, "Expecting a primary, found: %s\n", atr[tok.tok].text);
    }

    while (atr[tok.tok].is_binary && atr[tok.tok].precedence >= p) {
        TokenType op = tok.tok;

        tok = gettok();

        int q = atr[op].precedence;
        if (!atr[op].right_associative)
            q++;

        node = expr(q);
        x = make_node(atr[op].node_type, x, node);
    }
    return x;
}

Tree *paren_expr() {
    expect("paren_expr", tk_Lparen);
    Tree *t = expr(0);
    expect("paren_expr", tk_Rparen);
    return t;
}

Tree *stmt() {
    Tree *t = NULL, *v, *e, *s, *s2;

    switch (tok.tok) {
        case tk_If:
            tok = gettok();
            e = paren_expr();
            s = stmt();
            s2 = NULL;
            if (tok.tok == tk_Else) {
                tok = gettok();
                s2 = stmt();
            }
            t = make_node(nd_If, e, make_node(nd_If, s, s2));
            break;
        case tk_Putc:
            tok = gettok();
            e = paren_expr();
            t = make_node(nd_Prtc, e, NULL);
            expect("Putc", tk_Semi);
            break;
        case tk_Print: /* print '(' expr {',' expr} ')' */
            tok = gettok();
            for (expect("Print", tk_Lparen); ; expect("Print", tk_Comma)) {
                if (tok.tok == tk_String) {
                    e = make_node(nd_Prts, make_leaf(nd_String, tok.text), NULL);
                    tok = gettok();
                } else
                    e = make_node(nd_Prti, expr(0), NULL);

                t = make_node(nd_Sequence, t, e);

                if (tok.tok != tk_Comma)
                    break;
            }
            expect("Print", tk_Rparen);
            expect("Print", tk_Semi);
            break;
        case tk_Semi:
            tok = gettok();
            break;
        case tk_Ident:
            v = make_leaf(nd_Ident, tok.text);
            tok = gettok();
            expect("assign", tk_Assign);
            e = expr(0);
            t = make_node(nd_Assign, v, e);
            expect("assign", tk_Semi);
            break;
        case tk_While:
            tok = gettok();
            e = paren_expr();
            s = stmt();
            t = make_node(nd_While, e, s);
            break;
        case tk_Lbrace:         /* {stmt} */
            for (expect("Lbrace", tk_Lbrace); tok.tok != tk_Rbrace && tok.tok != tk_EOI;)
                t = make_node(nd_Sequence, t, stmt());
            expect("Lbrace", tk_Rbrace);
            break;
        case tk_EOI:
            break;
        default: error(tok.err_ln, tok.err_col, "expecting start of statement, found '%s'\n", atr[tok.tok].text);
    }
    return t;
}

Tree *parse() {
    Tree *t = NULL;

    tok = gettok();
    do {
        t = make_node(nd_Sequence, t, stmt());
    } while (t != NULL && tok.tok != tk_EOI);
    return t;
}

void prt_ast(Tree *t) {
    if (t == NULL)
        printf(";\n");
    else {
        printf("%-14s ", Display_nodes[t->node_type]);
        if (t->node_type == nd_Ident || t->node_type == nd_Integer || t->node_type == nd_String) {
            printf("%s\n", t->value);
        } else {
            printf("\n");
            prt_ast(t->left);
            prt_ast(t->right);
        }
    }
}

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);
}

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] : "");
    prt_ast(parse());
}


Compiler/virtual machine interpreter

The C and Python versions can be considered reference implementations.

;Related Tasks

* Lexical Analyzer task
* Syntax Analyzer task
* Code Generator task
* AST Interpreter task

__TOC__

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

#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))

#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)

typedef unsigned char uchar;
typedef uchar code;

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 struct Code_map {
    char    *text;
    Code_t   op;
} Code_map;

Code_map code_map[] = {
    {"fetch",  FETCH},
    {"store",  STORE},
    {"push",   PUSH },
    {"add",    ADD  },
    {"sub",    SUB  },
    {"mul",    MUL  },
    {"div",    DIV  },
    {"mod",    MOD  },
    {"lt",     LT   },
    {"gt",     GT   },
    {"le",     LE   },
    {"ge",     GE   },
    {"eq",     EQ   },
    {"ne",     NE   },
    {"and",    AND  },
    {"or",     OR   },
    {"neg",    NEG  },
    {"not",    NOT  },
    {"jmp",    JMP  },
    {"jz",     JZ   },
    {"prtc",   PRTC },
    {"prts",   PRTS },
    {"prti",   PRTI },
    {"halt",   HALT },
};

FILE *source_fp;
da_dim(object, code);

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);
}

/*** Virtual Machine interpreter ***/
void run_vm(const code obj[], int32_t data[], int g_size, char **string_pool) {
    int32_t *sp = &data[g_size + 1];
    const code *pc = obj;

    again:
    switch (*pc++) {
        case FETCH: *sp++ = data[*(int32_t *)pc];  pc += sizeof(int32_t); goto again;
        case STORE: data[*(int32_t *)pc] = *--sp;  pc += sizeof(int32_t); goto again;
        case PUSH:  *sp++ = *(int32_t *)pc;        pc += sizeof(int32_t); goto again;
        case ADD:   sp[-2] += sp[-1]; --sp;                             goto again;
        case SUB:   sp[-2] -= sp[-1]; --sp;                             goto again;
        case MUL:   sp[-2] *= sp[-1]; --sp;                             goto again;
        case DIV:   sp[-2] /= sp[-1]; --sp;                             goto again;
        case MOD:   sp[-2] %= sp[-1]; --sp;                             goto again;
        case LT:    sp[-2] = sp[-2] <  sp[-1]; --sp;                    goto again;
        case GT:    sp[-2] = sp[-2] >  sp[-1]; --sp;                    goto again;
        case LE:    sp[-2] = sp[-2] <= sp[-1]; --sp;                    goto again;
        case GE:    sp[-2] = sp[-2] >= sp[-1]; --sp;                    goto again;
        case EQ:    sp[-2] = sp[-2] == sp[-1]; --sp;                    goto again;
        case NE:    sp[-2] = sp[-2] != sp[-1]; --sp;                    goto again;
        case AND:   sp[-2] = sp[-2] && sp[-1]; --sp;                    goto again;
        case OR:    sp[-2] = sp[-2] || sp[-1]; --sp;                    goto again;
        case NEG:   sp[-1] = -sp[-1];                                   goto again;
        case NOT:   sp[-1] = !sp[-1];                                   goto again;
        case JMP:   pc += *(int32_t *)pc;                               goto again;
        case JZ:    pc += (*--sp == 0) ? *(int32_t *)pc : (int32_t)sizeof(int32_t); goto again;
        case PRTC:  printf("%c", sp[-1]); --sp;                         goto again;
        case PRTS:  printf("%s", string_pool[sp[-1]]); --sp;            goto again;
        case PRTI:  printf("%d", sp[-1]); --sp;                         goto again;
        case HALT:                                                      break;
        default:    error("Unknown opcode %d\n", *(pc - 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;
}

char *translate(char *st) {
    char *p, *q;
    if (st[0] == '"')                       // skip leading " if there
        ++st;
    p = q = st;

    while ((*p++ = *q++) != '\0') {
        if (q[-1] == '\\') {
            if (q[0] == 'n') {
                p[-1] = '\n';
                ++q;
            } else if (q[0] == '\\') {
                ++q;
            }
        }
        if (q[0] == '"' && q[1] == '\0')    // skip trialing " if there
            ++q;
    }

    return st;
}

/* convert an opcode string into its byte value */
int findit(const char text[], int offset) {
    for (size_t i = 0; i < sizeof(code_map) / sizeof(code_map[0]); i++) {
        if (strcmp(code_map[i].text, text) == 0)
            return code_map[i].op;
    }
    error("Unknown instruction %s at %d\n", text, offset);
    return -1;
}

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

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]);
    }
}

/*
Datasize: 5 Strings: 3
" is prime\n"
"Total primes found: "
"\n"
 154 jmp    (-73) 82
 164 jz     (32) 197
 175 push  0
 159 fetch [4]
 149 store [3]
 */

/* Load code into global array object, return the string pool and data size */
char **load_code(int *ds) {
    int line_len, n_strings;
    char **string_pool;
    char *text = read_line(&line_len);
    text = rtrim(text, &line_len);

    strtok(text, " ");                      // skip "Datasize:"
    *ds = atoi(strtok(NULL, " "));          // get actual data_size
    strtok(NULL, " ");                      // skip "Strings:"
    n_strings = atoi(strtok(NULL, " "));    // get number of strings

    string_pool = malloc(n_strings * sizeof(char *));
    for (int i = 0; i < n_strings; ++i) {
        text = read_line(&line_len);
        text = rtrim(text, &line_len);
        text = translate(text);
        string_pool[i] = strdup(text);
    }

    for (;;) {
        int len;

        text = read_line(&line_len);
        if (text == NULL)
            break;
        text = rtrim(text, &line_len);

        int offset = atoi(strtok(text, " "));   // get the offset
        char *instr = strtok(NULL, " ");    // get the instruction
        int opcode = findit(instr, offset);
        emit_byte(opcode);
        char *operand = strtok(NULL, " ");

        switch (opcode) {
            case JMP: case JZ:
                operand++;                  // skip the '('
                len = strlen(operand);
                operand[len - 1] = '\0';    // remove the ')'
                emit_int(atoi(operand));
                break;
            case PUSH:
                emit_int(atoi(operand));
                break;
            case FETCH: case STORE:
                operand++;                  // skip the '['
                len = strlen(operand);
                operand[len - 1] = '\0';    // remove the ']'
                emit_int(atoi(operand));
                break;
        }
    }
    return string_pool;
}

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);
}

int main(int argc, char *argv[]) {
    init_io(&source_fp, stdin,  "r",  argc > 1 ? argv[1] : "");
    int data_size;
    char **string_pool = load_code(&data_size);
    int data[1000 + data_size];
    run_vm(object, data, data_size, string_pool);
}


Conjugate transpose

Suppose that a conjugate transpose of M is a matrix M^H containing the [[complex conjugate]]s of the [[matrix transposition]] of M.

::: (M^H)_{ji} = \overline{M_{ij}}

This means that   row j, column i of the conjugate transpose equals the
complex conjugate of row i, column j of the original matrix.

In the next list, M must also be a square matrix.

* A Hermitian matrix equals its own conjugate transpose: M^H = M.
* A multiplication with its conjugate transpose: M^HM = MM^H.
* A iff M^HM = I_n and iff MM^H = I_n, where I_n is the identity matrix.

;Task:
Given some matrix of complex numbers, find its conjugate transpose.

Also determine if the matrix is a:
::* Hermitian matrix,
::* normal matrix,  or
::* unitary matrix.

;See also:
* MathWorld entry: conjugate transpose
* MathWorld entry: Hermitian matrix
* MathWorld entry: normal matrix
* MathWorld entry: unitary matrix

Solution:
/* Uses C99 specified complex.h, complex datatype has to be defined and operation provided if used on non-C99 compilers */

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

typedef struct
{
  int rows, cols;
  complex **z;
} matrix;

matrix
transpose (matrix a)
{
  int i, j;
  matrix b;

  b.rows = a.cols;
  b.cols = a.rows;

  b.z = malloc (b.rows * sizeof (complex *));

  for (i = 0; i < b.rows; i++)
    {
      b.z[i] = malloc (b.cols * sizeof (complex));
      for (j = 0; j < b.cols; j++)
        {
          b.z[i][j] = conj (a.z[j][i]);
        }
    }

  return b;
}

int
isHermitian (matrix a)
{
  int i, j;
  matrix b = transpose (a);

  if (b.rows == a.rows && b.cols == a.cols)
    {
      for (i = 0; i < b.rows; i++)
        {
          for (j = 0; j < b.cols; j++)
            {
              if (b.z[i][j] != a.z[i][j])
                return 0;
            }
        }
    }

  else
    return 0;

  return 1;
}

matrix
multiply (matrix a, matrix b)
{
  matrix c;
  int i, j;

  if (a.cols == b.rows)
    {
      c.rows = a.rows;
      c.cols = b.cols;

      c.z = malloc (c.rows * (sizeof (complex *)));

      for (i = 0; i < c.rows; i++)
        {
          c.z[i] = malloc (c.cols * sizeof (complex));
          c.z[i][j] = 0 + 0 * I;
          for (j = 0; j < b.cols; j++)
            {
              c.z[i][j] += a.z[i][j] * b.z[j][i];
            }
        }

    }

  return c;
}

int
isNormal (matrix a)
{
  int i, j;
  matrix a_ah, ah_a;

  if (a.rows != a.cols)
    return 0;

  a_ah = multiply (a, transpose (a));
  ah_a = multiply (transpose (a), a);

  for (i = 0; i < a.rows; i++)
    {
      for (j = 0; j < a.cols; j++)
        {
          if (a_ah.z[i][j] != ah_a.z[i][j])
            return 0;
        }
    }

  return 1;
}

int
isUnitary (matrix a)
{
  matrix b;
  int i, j;
  if (isNormal (a) == 1)
    {
      b = multiply (a, transpose(a));

      for (i = 0; i < b.rows; i++)
        {
          for (j = 0; j < b.cols; j++)
            {
              if ((i == j && b.z[i][j] != 1) || (i != j && b.z[i][j] != 0))
                return 0;
            }
        }
      return 1;
    }
  return 0;
}

int
main ()
{
  complex z = 3 + 4 * I;
  matrix a, aT;
  int i, j;
  printf ("Enter rows and columns :");
  scanf ("%d%d", &a.rows, &a.cols);

  a.z = malloc (a.rows * sizeof (complex *));
  printf ("Randomly Generated Complex Matrix A is : ");
  for (i = 0; i < a.rows; i++)
    {
      printf ("\n");
      a.z[i] = malloc (a.cols * sizeof (complex));
      for (j = 0; j < a.cols; j++)
        {
          a.z[i][j] = rand () % 10 + rand () % 10 * I;
          printf ("\t%f + %fi", creal (a.z[i][j]), cimag (a.z[i][j]));
        }
    }

  aT = transpose (a);

  printf ("\n\nTranspose of Complex Matrix A is : ");
  for (i = 0; i < aT.rows; i++)
    {
      printf ("\n");
      aT.z[i] = malloc (aT.cols * sizeof (complex));
      for (j = 0; j < aT.cols; j++)
        {
          aT.z[i][j] = rand () % 10 + rand () % 10 * I;
          printf ("\t%f + %fi", creal (aT.z[i][j]), cimag (aT.z[i][j]));
        }
    }

  printf ("\n\nComplex Matrix A %s hermitian",
          isHermitian (a) == 1 ? "is" : "is not");
  printf ("\n\nComplex Matrix A %s unitary",
          isUnitary (a) == 1 ? "is" : "is not");
  printf ("\n\nComplex Matrix A %s normal",
          isNormal (a) == 1 ? "is" : "is not");

  return 0;
}


Continued fraction/Arithmetic/Construct from rational number

To understand this task in context please see [[Continued fraction arithmetic]]
The purpose of this task is to write a function \mathit{r2cf}(\mathrm{int} N_1, \mathrm{int} N_2), or \mathit{r2cf}(\mathrm{Fraction} N), which will output a continued fraction assuming:
:N_1 is the numerator
:N_2 is the denominator

The function should output its results one digit at a time each time it is called, in a manner sometimes described as lazy evaluation.

To achieve this it must determine: the integer part; and remainder part, of N_1 divided by N_2. It then sets N_1 to N_2 and N_2 to the determined remainder part. It then outputs the determined integer part. It does this until \mathrm{abs}(N_2) is zero.

Demonstrate the function by outputing the continued fraction for:
: 1/2
: 3
: 23/8
: 13/11
: 22/7
: -151/77
\sqrt 2 should approach [1; 2, 2, 2, 2, \ldots] try ever closer rational approximations until boredom gets the better of you:
: 14142,10000
: 141421,100000
: 1414214,1000000
: 14142136,10000000

Try :
: 31,10
: 314,100
: 3142,1000
: 31428,10000
: 314285,100000
: 3142857,1000000
: 31428571,10000000
: 314285714,100000000

Observe how this rational number behaves differently to \sqrt 2 and convince yourself that, in the same way as 3.7 may be represented as 3.70 when an extra decimal place is required, [3;7] may be represented as [3;7,\infty] when an extra term is required.

Solution:
#include<stdio.h>

typedef struct{
	int num,den;
	}fraction;

fraction examples[] = {{1,2}, {3,1}, {23,8}, {13,11}, {22,7}, {-151,77}};
fraction sqrt2[] = {{14142,10000}, {141421,100000}, {1414214,1000000}, {14142136,10000000}};
fraction pi[] = {{31,10}, {314,100}, {3142,1000}, {31428,10000}, {314285,100000}, {3142857,1000000}, {31428571,10000000}, {314285714,100000000}};

int r2cf(int *numerator,int *denominator)
{
	int quotient=0,temp;

	if(denominator != 0)
	{
		quotient = *numerator / *denominator;

		temp = *numerator;

		*numerator = *denominator;

		*denominator = temp % *denominator;
	}

	return quotient;
}

int main()
{
	int i;

	printf("Running the examples :");

	for(i=0;i<sizeof(examples)/sizeof(fraction);i++)
	{
		printf("\nFor N = %d, D = %d :",examples[i].num,examples[i].den);

		while(examples[i].den != 0){
			printf(" %d ",r2cf(&examples[i].num,&examples[i].den));
			}
	}

	printf("\n\nRunning for %c2 :",251); /* 251 is the ASCII code for the square root symbol */

	for(i=0;i<sizeof(sqrt2)/sizeof(fraction);i++)
	{
		printf("\nFor N = %d, D = %d :",sqrt2[i].num,sqrt2[i].den);

		while(sqrt2[i].den != 0){
			printf(" %d ",r2cf(&sqrt2[i].num,&sqrt2[i].den));
			}
	}

	printf("\n\nRunning for %c :",227); /* 227 is the ASCII code for Pi's symbol */

	for(i=0;i<sizeof(pi)/sizeof(fraction);i++)
	{
		printf("\nFor N = %d, D = %d :",pi[i].num,pi[i].den);

		while(pi[i].den != 0){
			printf(" %d ",r2cf(&pi[i].num,&pi[i].den));
			}
	}

	return 0;
}


Convert decimal number to rational

The task is to write a program to transform a decimal number into a fraction in lowest terms.

It is not always possible to do this exactly. For instance, while rational numbers can be converted to decimal representation, some of them need an infinite number of digits to be represented exactly in decimal form. Namely, repeating decimals such as 1/3 = 0.333...

Because of this, the following fractions cannot be obtained (reliably) unless the language has some way of representing repeating decimals:
* 67 / 74 = 0.9(054) = 0.9054054...
* 14 / 27 = 0.(518)  = 0.518518...

Acceptable output:

* 0.9054054 - 4527027 / 5000000
* 0.518518  - 259259 / 500000

Finite decimals are of course no problem:

* 0.75      - 3 / 4

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

/* f : number to convert.
 * num, denom: returned parts of the rational.
 * md: max denominator value.  Note that machine floating point number
 *     has a finite resolution (10e-16 ish for 64 bit double), so specifying
 *     a "best match with minimal error" is often wrong, because one can
 *     always just retrieve the significand and return that divided by
 *     2**52, which is in a sense accurate, but generally not very useful:
 *     1.0/7.0 would be "2573485501354569/18014398509481984", for example.
 */
void rat_approx(double f, int64_t md, int64_t *num, int64_t *denom)
{
	/*  a: continued fraction coefficients. */
	int64_t a, h[3] = { 0, 1, 0 }, k[3] = { 1, 0, 0 };
	int64_t x, d, n = 1;
	int i, neg = 0;

	if (md <= 1) { *denom = 1; *num = (int64_t) f; return; }

	if (f < 0) { neg = 1; f = -f; }

	while (f != floor(f)) { n <<= 1; f *= 2; }
	d = f;

	/* continued fraction and check denominator each step */
	for (i = 0; i < 64; i++) {
		a = n ? d / n : 0;
		if (i && !a) break;

		x = d; d = n; n = x % n;

		x = a;
		if (k[1] * a + k[0] >= md) {
			x = (md - k[0]) / k[1];
			if (x * 2 >= a || k[1] >= md)
				i = 65;
			else
				break;
		}

		h[2] = x * h[1] + h[0]; h[0] = h[1]; h[1] = h[2];
		k[2] = x * k[1] + k[0]; k[0] = k[1]; k[1] = k[2];
	}
	*denom = k[1];
	*num = neg ? -h[1] : h[1];
}

int main()
{
	int i;
	int64_t d, n;
	double f;

	printf("f = %16.14f\n", f = 1.0/7);
	for (i = 1; i <= 20000000; i *= 16) {
		printf("denom <= %d: ", i);
		rat_approx(f, i, &n, &d);
		printf("%lld/%lld\n", n, d);
	}

	printf("\nf = %16.14f\n", f = atan2(1,1) * 4);
	for (i = 1; i <= 20000000; i *= 16) {
		printf("denom <= %d: ", i);
		rat_approx(f, i, &n, &d);
		printf("%lld/%lld\n", n, d);
	}

	return 0;
}


Convert seconds to compound duration

Write a function or program which:
*   takes a positive integer representing a duration in seconds as input (e.g., 100), and
*   returns a string which shows the same duration decomposed into:
:::*   weeks,
:::*   days,
:::*   hours,
:::*   minutes,   and
:::*   seconds.

This is detailed below (e.g., "2 hr, 59 sec").

Demonstrate that it passes the following three test-cases:

'''''Test Cases'''''

:::::{| class="wikitable"
|-
! input number
! output string
|-
| 7259
| 2 hr, 59 sec
|-
| 86400
| 1 d
|-
| 6000000
| 9 wk, 6 d, 10 hr, 40 min
|}

'''''Details'''''

The following five units should be used:
:::::{| class="wikitable"
|-
! unit
! suffix used in output
! conversion
|-
| week
| wk
| 1 week = 7 days
|-
| day
| d
| 1 day = 24 hours
|-
| hour
| hr
| 1 hour = 60 minutes
|-
| minute
| min
| 1 minute = 60 seconds
|-
| second
| sec
|
|}

However, '''only''' include quantities with non-zero values in the output (e.g., return "1 d" and not "0 wk, 1 d, 0 hr, 0 min, 0 sec").

Give larger units precedence over smaller ones as much as possible (e.g., return 2 min, 10 sec and not 1 min, 70 sec or 130 sec)

Mimic the formatting shown in the test-cases (quantities sorted from largest unit to smallest and separated by comma+space; value and unit of each quantity separated by space).

Solution:
#include <inttypes.h> /* requires c99 */
#include <stdbool.h>  /* requires c99 */
#include <stdio.h>
#include <stdlib.h>

#define N_EL 5

uintmax_t sec_to_week(uintmax_t);
uintmax_t sec_to_day(uintmax_t);
uintmax_t sec_to_hour(uintmax_t);
uintmax_t sec_to_min(uintmax_t);

uintmax_t week_to_sec(uintmax_t);
uintmax_t day_to_sec(uintmax_t);
uintmax_t hour_to_sec(uintmax_t);
uintmax_t min_to_sec(uintmax_t);

char *format_sec(uintmax_t);
    /* the primary function */

int main(int argc, char *argv[])
{
    uintmax_t input;
    char *a;

    if(argc<2) {
        printf("usage: %s #seconds\n", argv[0]);
        return 1;
    }
    input = strtoumax(argv[1],(void *)0, 10 /*base 10*/);
    if(input<1) {
        printf("Bad input: %s\n", argv[1]);
        printf("usage: %s #seconds\n", argv[0]);
        return 1;
    }
    printf("Number entered: %" PRIuMAX "\n", input);
    a = format_sec(input);
    printf(a);
    free(a);

    return 0;
}

/* note: must free memory
 * after using this function */
char *format_sec(uintmax_t input)
{
    int i;
    bool first;
    uintmax_t weeks, days, hours, mins;
    /*seconds kept in input*/

    char *retval;
    FILE *stream;
    size_t size;
    uintmax_t *traverse[N_EL]={&weeks,&days,
            &hours,&mins,&input};
    char *labels[N_EL]={"wk","d","hr","min","sec"};

    weeks = sec_to_week(input);
    input = input - week_to_sec(weeks);

    days = sec_to_day(input);
    input = input - day_to_sec(days);

    hours = sec_to_hour(input);
    input = input - hour_to_sec(hours);

    mins = sec_to_min(input);
    input = input - min_to_sec(mins);
    /* input now has the remaining seconds */

    /* open stream */
    stream = open_memstream(&retval,&size);
    if(stream == 0) {
        fprintf(stderr,"Unable to allocate memory");
        return 0;
    }

    /* populate stream */
    first = true;
    for(i=0;i<N_EL;i++) {
        if ( *(traverse[i]) != 0 ) {
            if(!first) {
                fprintf(stream,", %" PRIuMAX " %s",
                        *(traverse[i]), labels[i]);
            } else {
                fprintf(stream,"%" PRIuMAX " %s",
                        *(traverse[i]), labels[i]);
            }
            fflush(stream);
            first=false;
        }
    }
    fprintf(stream,"\n");
    fclose(stream);
    return retval;

}

uintmax_t sec_to_week(uintmax_t seconds)
{
    return sec_to_day(seconds)/7;
}

uintmax_t sec_to_day(uintmax_t seconds)
{
    return sec_to_hour(seconds)/24;
}

uintmax_t sec_to_hour(uintmax_t seconds)
{
    return sec_to_min(seconds)/60;
}

uintmax_t sec_to_min(uintmax_t seconds)
{
    return seconds/60;
}

uintmax_t week_to_sec(uintmax_t weeks)
{
    return day_to_sec(weeks*7);
}

uintmax_t day_to_sec(uintmax_t days)
{
    return hour_to_sec(days*24);
}

uintmax_t hour_to_sec(uintmax_t hours)
{
    return min_to_sec(hours*60);
}

uintmax_t min_to_sec(uintmax_t minutes)
{
    return minutes*60;
}


Copy stdin to stdout

Create an executable file that copies stdin to stdout, or else a script that does so through the invocation of an interpreter at the command line.

Solution:
#include <stdio.h>

int main(){
  char c;
  while ( (c=getchar()) != EOF ){
    putchar(c);
  }
  return 0;
}


Count the coins

There are four types of common coins in   US   currency:
:::#   quarters   (25 cents)
:::#   dimes   (10 cents)
:::#   nickels   (5 cents),   and
:::#   pennies   (1 cent)

There are six ways to make change for 15 cents:
:::#   A dime and a nickel
:::#   A dime and 5 pennies
:::#   3 nickels
:::#   2 nickels and 5 pennies
:::#   A nickel and 10 pennies
:::#   15 pennies

;Task:
How many ways are there to make change for a dollar using these common coins?     (1 dollar = 100 cents).

;Optional:
Less common are dollar coins (100 cents);   and very rare are half dollars (50 cents).   With the addition of these two coins, how many ways are there to make change for $1000?

(Note:   the answer is larger than   232).

;References:
* an algorithm from the book ''Structure and Interpretation of Computer Programs''.
* an article in the algorithmist.
* Change-making problem on Wikipedia.

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

// ad hoc 128 bit integer type; faster than using GMP because of low
// overhead
typedef struct { uint64_t x[2]; } i128;

// display in decimal
void show(i128 v) {
	uint32_t x[4] = {v.x[0], v.x[0] >> 32, v.x[1], v.x[1] >> 32};
	int i, j = 0, len = 4;
	char buf[100];
	do {
		uint64_t c = 0;
		for (i = len; i--; ) {
			c = (c << 32) + x[i];
			x[i] = c / 10, c %= 10;
		}

		buf[j++] = c + '0';
		for (len = 4; !x[len - 1]; len--);
	} while (len);

	while (j--) putchar(buf[j]);
	putchar('\n');
}

i128 count(int sum, int *coins)
{
	int n, i, k;
	for (n = 0; coins[n]; n++);

	i128 **v = malloc(sizeof(int*) * n);
	int *idx = malloc(sizeof(int) * n);

	for (i = 0; i < n; i++) {
		idx[i] = coins[i];
		// each v[i] is a cyclic buffer
		v[i] = calloc(sizeof(i128), coins[i]);
	}

	v[0][coins[0] - 1] = (i128) {{1, 0}};

	for (k = 0; k <= sum; k++) {
		for (i = 0; i < n; i++)
			if (!idx[i]--) idx[i] = coins[i] - 1;

		i128 c = v[0][ idx[0] ];

		for (i = 1; i < n; i++) {
			i128 *p = v[i] + idx[i];

			// 128 bit addition
			p->x[0] += c.x[0];
			p->x[1] += c.x[1];
			if (p->x[0] < c.x[0]) // carry
				p->x[1] ++;
			c = *p;
		}
	}

	i128 r = v[n - 1][idx[n-1]];

	for (i = 0; i < n; i++) free(v[i]);
	free(v);
	free(idx);

	return r;
}

// simple recursive method; slow
int count2(int sum, int *coins)
{
	if (!*coins || sum < 0) return 0;
	if (!sum) return 1;
	return count2(sum - *coins, coins) + count2(sum, coins + 1);
}

int main(void)
{
	int us_coins[] = { 100, 50, 25, 10, 5, 1, 0 };
	int eu_coins[] = { 200, 100, 50, 20, 10, 5, 2, 1, 0 };

	show(count(   100, us_coins + 2));
	show(count(  1000, us_coins));

	show(count(  1000 * 100, us_coins));
	show(count( 10000 * 100, us_coins));
	show(count(100000 * 100, us_coins));

	putchar('\n');

	show(count(     1 * 100, eu_coins));
	show(count(  1000 * 100, eu_coins));
	show(count( 10000 * 100, eu_coins));
	show(count(100000 * 100, eu_coins));

	return 0;
}


Create an HTML table

Create an HTML table.
* The table body should have at least three rows of three columns.
* Each of these three columns should be labelled "X", "Y", and "Z".
* An extra column should be added at either the extreme left or the extreme right of the table that has no heading, but is filled with sequential row numbers.
* The rows of the "X", "Y", and "Z" columns should be filled with random or sequential integers having 4 digits or less.
* The numbers should be aligned in the same fashion for all columns.

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

int main()
{
	int i;
	printf("
	"
		"X	Y	Z	");
	for (i = 0; i < 4; i++) {
		printf("
%d	%d	%d	%d
", i,
			rand() % 10000, rand() % 10000, rand() % 10000);
	}
	printf("
");

	return 0;
}


Currency

Show how to represent currency in a simple example, using a data type that represent exact values of dollars and cents.

;Note:
The '''IEEE 754''' binary floating point representations of numbers like   '''2.86'''   and   '''.0765'''   are not exact.

For this example, data will be two items with prices in dollars and cents, a quantity for each, and a tax rate.

Use the values:
::* 4000000000000000 hamburgers at $5.50 each       (four quadrillion burgers)
::* 2 milkshakes at $2.86 each, and
::* a tax rate of 7.65%.

(That number of hamburgers is a 4 with 15 zeros after it.    The number is contrived to exclude naive task solutions using 64 bit floating point types.)

Compute and output (show results on this page):
::* the total price before tax
::* the tax
::* the total with tax

The tax value must be computed by rounding to the nearest whole cent and this exact value must be added to the total price before tax.

The output must show dollars and cents with a decimal point.

The three results displayed should be:
::* 22000000000000005.72
::* 1683000000000000.44
::* 23683000000000006.16

Dollar signs and thousands separators are optional.

Solution:
mpf_set_d(burgerUnitPrice,5.50);
	mpf_set_d(milkshakePrice,2 * 2.86);
	mpf_set_d(burgerNum,4000000000000000);
	mpf_set_d(milkshakeNum,2);


Currying

{{Wikipedia|Currying}}

;Task:
Create a simple demonstrative example of Currying in a specific language.

Add any historic details as to how the feature made its way into the language.

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

long int factorial(int n){
	if(n>1)
		return n*factorial(n-1);
	return 1;
}

long int sumOfFactorials(int num,...){
	va_list vaList;
	long int sum = 0;

	va_start(vaList,num);

	while(num--)
		sum += factorial(va_arg(vaList,int));

	va_end(vaList);

	return sum;
}

int main()
{
	printf("\nSum of factorials of [1,5] : %ld",sumOfFactorials(5,1,2,3,4,5));
	printf("\nSum of factorials of [3,5] : %ld",sumOfFactorials(3,3,4,5));
	printf("\nSum of factorials of [1,3] : %ld",sumOfFactorials(3,1,2,3));

	return 0;
}


Cut a rectangle

A given rectangle is made from ''m'' x ''n'' squares. If ''m'' and ''n'' are not both odd, then it is possible to cut a path through the rectangle along the square edges such that the rectangle splits into two connected pieces with the same shape (after rotating one of the pieces by 180deg). All such paths for 2 x 2 and 4 x 3 rectangles are shown below.

[[file:rect-cut.svg]]

Write a program that calculates the number of different ways to cut an ''m'' x ''n'' rectangle.  Optionally, show each of the cuts.

Possibly related task: [[Maze generation]] for depth-first search.

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

typedef unsigned char byte;
int w = 0, h = 0, verbose = 0;
unsigned long count = 0;

byte **hor, **ver, **vis;
byte **c = 0;

enum { U = 1, D = 2, L = 4, R = 8 };

byte ** alloc2(int w, int h)
{
	int i;
	byte **x = calloc(1, sizeof(byte*) * h + h * w);
	x[0] = (byte *)&x[h];
	for (i = 1; i < h; i++)
		x[i] = x[i - 1] + w;
	return x;
}

void show()
{
	int i, j, v, last_v;
	printf("%ld\n", count);
#if 0
	for (i = 0; i <= h; i++) {
		for (j = 0; j <= w; j++)
			printf("%d ", hor[i][j]);
		puts("");
	}
	puts("");

	for (i = 0; i <= h; i++) {
		for (j = 0; j <= w; j++)
			printf("%d ", ver[i][j]);
		puts("");
	}
	puts("");
#endif
	for (i = 0; i < h; i++) {
		if (!i) v = last_v = 0;
		else last_v = v = hor[i][0] ? !last_v : last_v;

		for (j = 0; j < w; v = ver[i][++j] ? !v : v)
			printf(v ? "\033[31m[]" : "\033[33m{}");
		puts("\033[m");
	}
	putchar('\n');
}

void walk(int y, int x)
{
	if (x < 0 || y < 0 || x > w || y > h) return;

	if (!x || !y || x == w || y == h) {
		++count;
		if (verbose) show();
		return;
	}

	if (vis[y][x]) return;
	vis[y][x]++; vis[h - y][w - x]++;

	if (x && !hor[y][x - 1]) {
		hor[y][x - 1] = hor[h - y][w - x] = 1;
		walk(y, x - 1);
		hor[y][x - 1] = hor[h - y][w - x] = 0;
	}
	if (x < w && !hor[y][x]) {
		hor[y][x] = hor[h - y][w - x - 1] = 1;
		walk(y, x + 1);
		hor[y][x] = hor[h - y][w - x - 1] = 0;
	}

	if (y && !ver[y - 1][x]) {
		ver[y - 1][x] = ver[h - y][w - x] = 1;
		walk(y - 1, x);
		ver[y - 1][x] = ver[h - y][w - x] = 0;
	}

	if (y < h && !ver[y][x]) {
		ver[y][x] = ver[h - y - 1][w - x] = 1;
		walk(y + 1, x);
		ver[y][x] = ver[h - y - 1][w - x] = 0;
	}

	vis[y][x]--; vis[h - y][w - x]--;
}

void cut(void)
{
	if (1 & (h * w)) return;

	hor = alloc2(w + 1, h + 1);
	ver = alloc2(w + 1, h + 1);
	vis = alloc2(w + 1, h + 1);

	if (h & 1) {
		ver[h/2][w/2] = 1;
		walk(h / 2, w / 2);
	} else if (w & 1) {
		hor[h/2][w/2] = 1;
		walk(h / 2, w / 2);
	} else {
		vis[h/2][w/2] = 1;

		hor[h/2][w/2-1] = hor[h/2][w/2] = 1;
		walk(h / 2, w / 2 - 1);
		hor[h/2][w/2-1] = hor[h/2][w/2] = 0;

		ver[h/2 - 1][w/2] = ver[h/2][w/2] = 1;
		walk(h / 2 - 1, w/2);
	}
}

void cwalk(int y, int x, int d)
{
	if (!y || y == h || !x || x == w) {
		++count;
		return;
	}
	vis[y][x] = vis[h-y][w-x] = 1;

	if (x && !vis[y][x-1])
		cwalk(y, x - 1, d|1);
	if ((d&1) && x < w && !vis[y][x+1])
		cwalk(y, x + 1, d|1);
	if (y && !vis[y-1][x])
		cwalk(y - 1, x, d|2);
	if ((d&2) && y < h && !vis[y + 1][x])
		cwalk(y + 1, x, d|2);

	vis[y][x] = vis[h-y][w-x] = 0;
}

void count_only(void)
{
	int t;
	long res;
	if (h * w & 1) return;
	if (h & 1) t = h, h = w, w = t;

	vis = alloc2(w + 1, h + 1);
	vis[h/2][w/2] = 1;

	if (w & 1) vis[h/2][w/2 + 1] = 1;
	if (w > 1) {
		cwalk(h/2, w/2 - 1, 1);
		res = 2 * count - 1;
		count = 0;
		if (w != h)
			cwalk(h/2+1, w/2, (w & 1) ? 3 : 2);

		res += 2 * count - !(w & 1);
	} else {
		res = 1;
	}
	if (w == h) res = 2 * res + 2;
	count = res;
}

int main(int c, char **v)
{
	int i;

	for (i = 1; i < c; i++) {
		if (v[i][0] == '-' && v[i][1] == 'v' && !v[i][2]) {
			verbose = 1;
		} else if (!w) {
			w = atoi(v[i]);
			if (w <= 0) goto bail;
		} else if (!h) {
			h = atoi(v[i]);
			if (h <= 0) goto bail;
		} else
			goto bail;
	}
	if (!w) goto bail;
	if (!h) h = w;

	if (verbose) cut();
	else count_only();

	printf("Total: %ld\n", count);
	return 0;

bail:	fprintf(stderr, "bad args\n");
	return 1;
}


Damm algorithm

The '''Damm''' algorithm is a checksum algorithm which detects all single digit errors and adjacent transposition errors.

The algorithm is named after H. Michael Damm.

;Task:
Verify the checksum, stored as last digit of an input.

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

bool damm(unsigned char *input, size_t length) {
    static const unsigned char table[10][10] = {
        {0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
        {7, 0, 9, 2, 1, 5, 4, 8, 6, 3},
        {4, 2, 0, 6, 8, 7, 1, 3, 5, 9},
        {1, 7, 5, 0, 9, 8, 3, 4, 2, 6},
        {6, 1, 2, 3, 0, 4, 5, 9, 7, 8},
        {3, 6, 7, 4, 2, 0, 9, 5, 8, 1},
        {5, 8, 6, 9, 7, 2, 0, 1, 3, 4},
        {8, 9, 4, 5, 3, 6, 2, 0, 1, 7},
        {9, 4, 3, 8, 6, 1, 7, 2, 0, 5},
        {2, 5, 8, 1, 4, 3, 6, 7, 9, 0},
    };

    unsigned char interim = 0;
    for (size_t i = 0; i < length; i++) {
        interim = table[interim][input[i]];
    }
    return interim == 0;
}

int main() {
    unsigned char input[4] = {5, 7, 2, 4};
    puts(damm(input, 4) ? "Checksum correct" : "Checksum incorrect");
    return 0;
}


Deceptive numbers

Repunits are numbers that consist entirely of repetitions of the digit one (unity).  The notation '''Rn''' symbolizes the repunit made up of '''n''' ones.

Every prime '''p''' larger than 5, evenly divides the repunit '''Rp-1'''.

;E.G.

The repunit '''R6''' is evenly divisible by '''7'''.

111111 / 7 = 15873

The repunit '''R42''' is evenly divisible by '''43'''.

111111111111111111111111111111111111111111 / 43 = 2583979328165374677002583979328165374677

And so on.

There are composite numbers that also have this same property. They are often referred to as ''deceptive non-primes'' or ''deceptive numbers''.

The repunit '''R90''' is evenly divisible by the composite number '''91''' (=7*13).

111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 / 91 = 1221001221001221001221001221001221001221001221001221001221001221001221001221001221001221

;Task

* Find and show at least the first '''10 deceptive numbers'''; composite numbers '''n''' that evenly divide the repunit '''Rn-1'''

;See also

;* Numbers Aplenty - Deceptive numbers
;* OEIS:A000864 - Deceptive nonprimes: composite numbers k that divide the repunit R_{k-1}

Solution:
#include <stdio.h>

unsigned modpow(unsigned b, unsigned e, unsigned m)
{
    unsigned p;
    for (p = 1; e; e >>= 1) {
        if (e & 1)
            p = p * b % m;
        b = b * b % m;
    }
    return p;
}

int is_deceptive(unsigned n)
{
    unsigned x;
    if (n & 1 && n % 3 && n % 5) {
        for (x = 7; x * x <= n; x += 6) {
            if (!(n % x && n % (x + 4)))
                return modpow(10, n - 1, n) == 1;
        }
    }
    return 0;
}

int main(void)
{
    unsigned c, i = 49;
    for (c = 0; c != 50; ++i) {
        if (is_deceptive(i)) {
            printf(" %u", i);
            ++c;
        }
    }
    return 0;
}


Deepcopy

Demonstrate how to copy data structures containing complex heterogeneous and cyclic semantics.

This is often referred to as deep copying, and is normally required where structures are mutable and to ensure that independent copies can be manipulated without side-effects.

If this facility is not built into the language, it is permissible to use functions from a common library, or a coded procedure.

The task should show:

* Relevant semantics of structures, such as their homogeneous or heterogeneous properties, or containment of (self- or mutual-reference) cycles.

* Any limitations of the method.

* That the structure and its copy are different.

* Suitable links to external documentation for common libraries.

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

typedef struct elem{
	int data;
	struct elem* next;
}cell;

typedef cell* list;

void addToList(list *a,int num){
	list temp, holder;

	if(*a==NULL){
		*a = (list)malloc(sizeof(cell));
		(*a)->data = num;
		(*a)->next = NULL;
	}
	else{
		temp = *a;

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

		holder = (list)malloc(sizeof(cell));
		holder->data = num;
		holder->next = NULL;

		temp->next = holder;
	}
}

list copyList(list a){
	list b, tempA, tempB, temp;

	if(a!=NULL){
		b = (list)malloc(sizeof(cell));
		b->data = a->data;
		b->next = NULL;

		tempA = a->next;
		tempB = b;

		while(tempA!=NULL){
			temp = (list)malloc(sizeof(cell));
			temp->data = tempA->data;
			temp->next = NULL;

			tempB->next = temp;
			tempB = temp;

			tempA = tempA->next;
		}
	}

	return b;
}

void printList(list a){
	list temp = a;

	while(temp!=NULL){
		printf("%d,",temp->data);
		temp = temp->next;
	}
	printf("\b");
}

int main()
{
	list a,b;
	int i;

	for(i=1;i<=5;i++)
		addToList(&a,i);

	printf("List a is : ");

	printList(a);

	b = copyList(a);

	free(a);

	printf("\nList a destroyed, List b is : ");

	printList(b);

	return 0;
}


Department numbers

There is a highly organized city that has decided to assign a number to each of their departments:
::*   police department
::*   sanitation department
::*   fire department

Each department can have a number between   '''1'''   and   '''7'''   (inclusive).

The three department numbers are to be unique (different from each other) and must add up to   '''12'''.

The Chief of the Police doesn't like odd numbers and wants to have an even number for his department.

;Task:
Write a computer program which outputs all valid combinations.

Possible output   (for the 1st and 14th solutions):

  --police--  --sanitation--  --fire--
      2             3            7
      6             5            1

Solution:
#include<stdio.h>

int main()
{
	int police,sanitation,fire;

	printf("Police     Sanitation         Fire\n");
	printf("----------------------------------");

	for(police=2;police<=6;police+=2){
		for(sanitation=1;sanitation<=7;sanitation++){
			for(fire=1;fire<=7;fire++){
				if(police!=sanitation && sanitation!=fire && fire!=police && police+fire+sanitation==12){
					printf("\n%d\t\t%d\t\t%d",police,sanitation,fire);
				}
			}
		}
	}

	return 0;
}


Detect division by zero

Write a function to detect a   ''divide by zero error''   without checking if the denominator is zero.

Solution:
#include <limits.h>	/* INT_MIN */
#include <setjmp.h>	/* siglongjmp(), sigsetjmp() */
#include <stdio.h>	/* perror(), printf() */
#include <stdlib.h>	/* exit() */
#include <signal.h>	/* sigaction(), sigemptyset() */

static sigjmp_buf fpe_env;

/*
 * This SIGFPE handler jumps to fpe_env.
 *
 * A SIGFPE handler must not return, because the program might retry
 * the division, which might cause an infinite loop. The only safe
 * options are to _exit() the program or to siglongjmp() out.
 */
static void
fpe_handler(int signal, siginfo_t *w, void *a)
{
	siglongjmp(fpe_env, w->si_code);
	/* NOTREACHED */
}

/*
 * Try to do x / y, but catch attempts to divide by zero.
 */
void
try_division(int x, int y)
{
	struct sigaction act, old;
	int code;
	/*
	 * The result must be volatile, else C compiler might delay
	 * division until after sigaction() restores old handler.
	 */
	volatile int result;

	/*
	 * Save fpe_env so that fpe_handler() can jump back here.
	 * sigsetjmp() returns zero.
	 */
	code = sigsetjmp(fpe_env, 1);
	if (code == 0) {
		/* Install fpe_handler() to trap SIGFPE. */
		act.sa_sigaction = fpe_handler;
		sigemptyset(&act.sa_mask);
		act.sa_flags = SA_SIGINFO;
		if (sigaction(SIGFPE, &act, &old) < 0) {
			perror("sigaction");
			exit(1);
		}

		/* Do division. */
		result = x / y;

		/*
		 * Restore old hander, so that SIGFPE cannot jump out
		 * of a call to printf(), which might cause trouble.
		 */
		if (sigaction(SIGFPE, &old, NULL) < 0) {
			perror("sigaction");
			exit(1);
		}

		printf("%d / %d is %d\n", x, y, result);
	} else {
		/*
		 * We caught SIGFPE. Our fpe_handler() jumped to our
		 * sigsetjmp() and passes a nonzero code.
		 *
		 * But first, restore old handler.
		 */
		if (sigaction(SIGFPE, &old, NULL) < 0) {
			perror("sigaction");
			exit(1);
		}

		/* FPE_FLTDIV should never happen with integers. */
		switch (code) {
		case FPE_INTDIV: /* integer division by zero */
		case FPE_FLTDIV: /* float division by zero */
			printf("%d / %d: caught division by zero!\n", x, y);
			break;
		default:
			printf("%d / %d: caught mysterious error!\n", x, y);
			break;
		}
	}
}

/* Try some division. */
int
main()
{
	try_division(-44, 0);
	try_division(-44, 5);
	try_division(0, 5);
	try_division(0, 0);
	try_division(INT_MIN, -1);
	return 0;
}


Determinant and permanent

permanent of the matrix.

The determinant is given by
:: \det(A) = \sum_\sigma\sgn(\sigma)\prod_{i=1}^n M_{i,\sigma_i}
while the permanent is given by
::  \operatorname{perm}(A)=\sum_\sigma\prod_{i=1}^n M_{i,\sigma_i}
In both cases the sum is over the permutations \sigma of the permutations of 1, 2, ..., ''n''. (A permutation's sign is 1 if there are an even number of inversions and -1 otherwise; see parity of a permutation.)

More efficient algorithms for the determinant are known: [[LU decomposition]], see for example [[wp:LU decomposition#Computing the determinant]]. Efficient methods for calculating the permanent are not known.

;Related task:
* [[Permutations by swapping]]

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

void showmat(const char *s, double **m, int n)
{
	printf("%s:\n", s);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			printf("%12.4f", m[i][j]);
			putchar('\n');
	}
}

int trianglize(double **m, int n)
{
	int sign = 1;
	for (int i = 0; i < n; i++) {
		int max = 0;

		for (int row = i; row < n; row++)
			if (fabs(m[row][i]) > fabs(m[max][i]))
				max = row;

		if (max) {
			sign = -sign;
			double *tmp = m[i];
			m[i] = m[max], m[max] = tmp;
		}

		if (!m[i][i]) return 0;

		for (int row = i + 1; row < n; row++) {
			double r = m[row][i] / m[i][i];
			if (!r)	continue;

			for (int col = i; col < n; col ++)
				m[row][col] -= m[i][col] * r;
		}
	}
	return sign;
}

double det(double *in, int n)
{
	double *m[n];
	m[0] = in;

	for (int i = 1; i < n; i++)
		m[i] = m[i - 1] + n;

	showmat("Matrix", m, n);

	int sign = trianglize(m, n);
	if (!sign)
		return 0;

	showmat("Upper triangle", m, n);

	double p = 1;
	for (int i = 0; i < n; i++)
		p *= m[i][i];
	return p * sign;
}

#define N 18
int main(void)
{
	double x[N * N];
	srand(0);
	for (int i = 0; i < N * N; i++)
		x[i] = rand() % N;

	printf("det: %19f\n", det(x, N));
	return 0;
}


Determine if a string has all the same characters

Given a character string   (which may be empty, or have a length of zero characters):
::*   create a function/procedure/routine to:
::::*    determine if all the characters in the string are the same
::::*    indicate if or which character is different from the previous character
::*   display each string and its length   (as the strings are being examined)
::*   a zero-length (empty) string shall be considered as all the same character(s)
::*   process the strings from left-to-right
::*   if       all the same character,   display a message saying such
::*   if                  not all the same character,   then:
::::*    display a message saying such
::::*    display what character is different
::::*    only the 1st different character need be displayed
::::*    display where the different character is in the string
::::*    the above messages can be part of a single message
::::*    display the hexadecimal value of the different character

Use (at least) these seven test values   (strings):
:::*   a string of length   0   (an empty string)
:::*   a string of length   3   which contains three blanks
:::*   a string of length   1   which contains:   '''2'''
:::*   a string of length   3   which contains:   '''333'''
:::*   a string of length   3   which contains:   '''.55'''
:::*   a string of length   6   which contains:   '''tttTTT'''
:::*   a string of length   9   with a blank in the middle:   '''4444   444k'''

Show all output here on this page.

Solution:
/**
 * An example for RossetaCode - an example of string operation with wchar_t and
 * with old 8-bit characters. Anyway, it seem that C is not very UTF-8 friendly,
 * thus C# or C++ may be a better choice.
 */

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

/*
 * The wide character version of the program is compiled if WIDE_CHAR is defined
 */
#define WIDE_CHAR

#ifdef WIDE_CHAR
#define CHAR wchar_t
#else
#define CHAR char
#endif

/**
 * Find a character different from the preceding characters in the given string.
 *
 * @param s the given string, NULL terminated.
 *
 * @return the pointer to the occurence of the different character
 *         or a pointer to NULL if all characters in the string
 *         are exactly the same.
 *
 * @notice This function return a pointer to NULL also for empty strings.
 *         Returning NULL-or-CHAR would not enable to compute the position
 *         of the non-matching character.
 *
 * @warning This function compare characters (single-bytes, unicode etc.).
 *          Therefore this is not designed to compare bytes. The NULL character
 *          is always treated as the end-of-string marker, thus this function
 *          cannot be used to scan strings with NULL character inside string,
 *          for an example "aaa\0aaa\0\0".
 */
const CHAR* find_different_char(const CHAR* s)
{
    /* The code just below is almost the same regardles
       char or wchar_t is used. */

    const CHAR c = *s;
    while (*s && c == *s)
    {
        s++;
    }
    return s;
}

/**
 * Apply find_different_char function to a given string and output the raport.
 *
 * @param s the given NULL terminated string.
 */
void report_different_char(const CHAR* s)
{
#ifdef WIDE_CHAR
    wprintf(L"\n");
    wprintf(L"string: \"%s\"\n", s);
    wprintf(L"length: %d\n", wcslen(s));
    const CHAR* d = find_different_char(s);
    if (d)
    {
        /*
         * We have got the famous pointers arithmetics and we can compute
         * difference of pointers pointing to the same array.
         */
        wprintf(L"character '%wc' (%#x) at %d\n", *d, *d, (int)(d - s));
    }
    else
    {
        wprintf(L"all characters are the same\n");
    }
    wprintf(L"\n");
#else
    putchar('\n');
    printf("string: \"%s\"\n", s);
    printf("length: %d\n", strlen(s));
    const CHAR* d = find_different_char(s);
    if (d)
    {
        /*
         * We have got the famous pointers arithmetics and we can compute
         * difference of pointers pointing to the same array.
         */
        printf("character '%c' (%#x) at %d\n", *d, *d, (int)(d - s));
    }
    else
    {
        printf("all characters are the same\n");
    }
    putchar('\n');
#endif
}

/* There is a wmain function as an entry point when argv[] points to wchar_t */

#ifdef WIDE_CHAR
int wmain(int argc, wchar_t* argv[])
#else
int main(int argc, char* argv[])
#endif
{
    if (argc < 2)
    {
        report_different_char(L"");
        report_different_char(L"   ");
        report_different_char(L"2");
        report_different_char(L"333");
        report_different_char(L".55");
        report_different_char(L"tttTTT");
        report_different_char(L"4444 444k");
    }
    else
    {
        report_different_char(argv[1]);
    }

    return EXIT_SUCCESS;
}


Determine if a string has all unique characters

Given a character string   (which may be empty, or have a length of zero characters):
::*   create a function/procedure/routine to:
::::*    determine if all the characters in the string are unique
::::*    indicate if or which character is duplicated and where
::*   display each string and its length   (as the strings are being examined)
::*   a zero-length (empty) string shall be considered as unique
::*   process the strings from left-to-right
::*   if       unique,   display a message saying such
::*   if                  not unique,   then:
::::*    display a message saying such
::::*    display what character is duplicated
::::*    only the 1st non-unique character need be displayed
::::*    display where "both" duplicated characters are in the string
::::*    the above messages can be part of a single message
::::*    display the hexadecimal value of the duplicated character

Use (at least) these five test values   (strings):
:::*   a string of length     0   (an empty string)
:::*   a string of length     1   which is a single period   ('''.''')
:::*   a string of length     6   which contains:   '''abcABC'''
:::*   a string of length     7   which contains a blank in the middle:   '''XYZ  ZYX'''
:::*   a string of length         36   which   ''doesn't''   contain the letter "oh":
::::::::  '''1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ'''

Show all output here on this page.

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

typedef struct positionList{
    int position;
    struct positionList *next;
}positionList;

typedef struct letterList{
    char letter;
    int repititions;
    positionList* positions;
    struct letterList *next;
}letterList;

letterList* letterSet;
bool duplicatesFound = false;

void checkAndUpdateLetterList(char c,int pos){
    bool letterOccurs = false;
    letterList *letterIterator,*newLetter;
    positionList *positionIterator,*newPosition;

    if(letterSet==NULL){
        letterSet = (letterList*)malloc(sizeof(letterList));
        letterSet->letter = c;
        letterSet->repititions = 0;

        letterSet->positions = (positionList*)malloc(sizeof(positionList));
        letterSet->positions->position = pos;
        letterSet->positions->next = NULL;

        letterSet->next = NULL;
    }

    else{
        letterIterator = letterSet;

        while(letterIterator!=NULL){
            if(letterIterator->letter==c){
                letterOccurs = true;
                duplicatesFound = true;

                letterIterator->repititions++;
                positionIterator = letterIterator->positions;

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

                newPosition = (positionList*)malloc(sizeof(positionList));
                newPosition->position = pos;
                newPosition->next = NULL;

                positionIterator->next = newPosition;
            }
            if(letterOccurs==false && letterIterator->next==NULL)
                break;
            else
                letterIterator = letterIterator->next;
        }

        if(letterOccurs==false){
            newLetter = (letterList*)malloc(sizeof(letterList));
            newLetter->letter = c;

            newLetter->repititions = 0;

            newLetter->positions = (positionList*)malloc(sizeof(positionList));
            newLetter->positions->position = pos;
            newLetter->positions->next = NULL;

            newLetter->next = NULL;

            letterIterator->next = newLetter;
        }
    }
}

void printLetterList(){
    positionList* positionIterator;
    letterList* letterIterator = letterSet;

    while(letterIterator!=NULL){
        if(letterIterator->repititions>0){
            printf("\n'%c' (0x%x) at positions :",letterIterator->letter,letterIterator->letter);

            positionIterator = letterIterator->positions;

            while(positionIterator!=NULL){
                printf("%3d",positionIterator->position + 1);
                positionIterator = positionIterator->next;
            }
        }

        letterIterator = letterIterator->next;
    }
    printf("\n");
}

int main(int argc,char** argv)
{
    int i,len;

    if(argc>2){
        printf("Usage : %s <Test string>\n",argv[0]);
        return 0;
    }

    if(argc==1||strlen(argv[1])==1){
        printf("\"%s\" - Length %d - Contains only unique characters.\n",argc==1?"":argv[1],argc==1?0:1);
        return 0;
    }

    len = strlen(argv[1]);

    for(i=0;i<len;i++){
        checkAndUpdateLetterList(argv[1][i],i);
    }

    printf("\"%s\" - Length %d - %s",argv[1],len,duplicatesFound==false?"Contains only unique characters.\n":"Contains the following duplicate characters :");

    if(duplicatesFound==true)
        printLetterList();

    return 0;
}


Determine if a string is collapsible

Determine if a character string is   ''collapsible''.

And if so,   collapse the string   (by removing   ''immediately repeated''   characters).

If a character string has   ''immediately repeated''   character(s),   the repeated characters are to be
deleted (removed),   but not the primary (1st) character(s).

An   ''immediately repeated''   character is any character that is   immediately   followed by an
identical character (or characters).   Another word choice could've been   ''duplicated character'',   but that
might have ruled out   (to some readers)   triplicated characters   ***   or more.

{This Rosetta Code task was inspired by a newly introduced   (as of around November 2019)   '''PL/I'''   BIF:   '''collapse'''.}

;Examples:
In the following character string:

  The better the 4-wheel drive, the further you'll be from help when ya get stuck!

Only the 2nd   '''t''',   '''e''', and   '''l'''   are repeated characters,   indicated
by underscores (above),   even though they (those characters) appear elsewhere in the character string.

So, after ''collapsing'' the string, the result would be:

  The beter the 4-whel drive, the further you'l be from help when ya get stuck!

Another example:
In the following character string:

  headmistressship

The "collapsed" string would be:

  headmistreship

;Task:
Write a subroutine/function/procedure/routine***   to
locate   ''repeated''   characters and   ''collapse''   (delete)   them from the character
string.   The character string can be processed from either direction.

Show all output here, on this page:
:*   the   original string and its length
:*   the       resultant string and its length
:*   the above strings should be "bracketed" with   '''<<<'''   and   '''>>>'''   (to delineate blanks)
;*   <<<<<<Guillemets may be used instead for "bracketing" for the more artistic programmers,   shown used here>>>>>>

Use (at least) the following five strings,   all strings are length seventy-two (characters, including blanks),   except
the 1st string:

  string
  number
         ++
    1    |+-----------------------------------------------------------------------+   <######  a null string  (length zero)
    2    |"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln |
    3    |..1111111111111111111111111111111111111111111111111111111111111117777888|
    4    |I never give 'em hell, I just tell the truth, and they think it's hell. |
    5    |                                                    --- Harry S Truman  |   <######  has many repeated blanks
         +------------------------------------------------------------------------+

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

#define COLLAPSE 0
#define SQUEEZE 1

typedef struct charList{
    char c;
    struct charList *next;
} charList;

/*
Implementing strcmpi, the case insensitive string comparator, as it is not part of the C Standard Library.

Comment this out if testing on a compiler where it is already defined.
*/

int strcmpi(char* str1,char* str2){
    int len1 = strlen(str1), len2 = strlen(str2), i;

    if(len1!=len2){
        return 1;
    }

    else{
        for(i=0;i<len1;i++){
            if((str1[i]>='A'&&str1[i]<='Z')&&(str2[i]>='a'&&str2[i]<='z')&&(str2[i]-65!=str1[i]))
                return 1;
            else if((str2[i]>='A'&&str2[i]<='Z')&&(str1[i]>='a'&&str1[i]<='z')&&(str1[i]-65!=str2[i]))
                return 1;
            else if(str1[i]!=str2[i])
                return 1;
        }
    }

    return 0;
}

charList *strToCharList(char* str){
    int len = strlen(str),i;

    charList *list, *iterator, *nextChar;

    list = (charList*)malloc(sizeof(charList));
    list->c = str[0];
    list->next = NULL;

    iterator = list;

    for(i=1;i<len;i++){
        nextChar = (charList*)malloc(sizeof(charList));
        nextChar->c = str[i];
        nextChar->next = NULL;

        iterator->next = nextChar;
        iterator = nextChar;
    }

    return list;
}

char* charListToString(charList* list){
    charList* iterator = list;
    int count = 0,i;
    char* str;

    while(iterator!=NULL){
        count++;
        iterator = iterator->next;
    }

    str = (char*)malloc((count+1)*sizeof(char));
    iterator = list;

    for(i=0;i<count;i++){
        str[i] = iterator->c;
        iterator = iterator->next;
    }

    free(list);
    str[i] = '\0';

    return str;
}

char* processString(char str[100],int operation, char squeezeChar){
    charList *strList = strToCharList(str),*iterator = strList, *scout;

    if(operation==SQUEEZE){
        while(iterator!=NULL){
            if(iterator->c==squeezeChar){
                scout = iterator->next;

                while(scout!=NULL && scout->c==squeezeChar){
                        iterator->next = scout->next;
                        scout->next = NULL;
                        free(scout);
                        scout = iterator->next;
                }
            }
            iterator = iterator->next;
        }
    }

    else{
        while(iterator!=NULL && iterator->next!=NULL){
            if(iterator->c == (iterator->next)->c){
                scout = iterator->next;
                squeezeChar = iterator->c;

                while(scout!=NULL && scout->c==squeezeChar){
                        iterator->next = scout->next;
                        scout->next = NULL;
                        free(scout);
                        scout = iterator->next;
                }
            }
            iterator = iterator->next;
        }
    }

    return charListToString(strList);
}

void printResults(char originalString[100], char finalString[100], int operation, char squeezeChar){
    if(operation==SQUEEZE){
        printf("Specified Operation : SQUEEZE\nTarget Character : %c",squeezeChar);
    }

    else
        printf("Specified Operation : COLLAPSE");

    printf("\nOriginal %c%c%c%s%c%c%c\nLength : %d",174,174,174,originalString,175,175,175,(int)strlen(originalString));
    printf("\nFinal    %c%c%c%s%c%c%c\nLength : %d\n",174,174,174,finalString,175,175,175,(int)strlen(finalString));
}

int main(int argc, char** argv){
    int operation;
    char squeezeChar;

    if(argc<3||argc>4){
        printf("Usage : %s <SQUEEZE|COLLAPSE> <String to be processed> <Character to be squeezed, if operation is SQUEEZE>\n",argv[0]);
        return 0;
    }

    if(strcmpi(argv[1],"SQUEEZE")==0 && argc!=4){
        scanf("Please enter characted to be squeezed : %c",&squeezeChar);
        operation = SQUEEZE;
    }

    else if(argc==4){
        operation = SQUEEZE;
        squeezeChar = argv[3][0];
    }

    else if(strcmpi(argv[1],"COLLAPSE")==0){
        operation = COLLAPSE;
    }

    if(strlen(argv[2])<2){
        printResults(argv[2],argv[2],operation,squeezeChar);
    }

    else{
        printResults(argv[2],processString(argv[2],operation,squeezeChar),operation,squeezeChar);
    }

    return 0;
}


Determine if a string is squeezable

Determine if a character string is   ''squeezable''.

And if so,   squeeze the string   (by removing any number of
a   ''specified''   ''immediately repeated''   character).

This task is very similar to the task     '''Determine if a character string is collapsible'''     except
that only a specified character is   ''squeezed''   instead of any character that is ''immediately repeated''.

If a character string has a specified   ''immediately repeated''   character(s),   the repeated characters are to be
deleted (removed),   but not the primary (1st) character(s).

A specified   ''immediately repeated''   character is any specified character that is   immediately
followed by an identical character (or characters).   Another word choice could've been   ''duplicated
character'',   but that might have ruled out   (to some readers)   triplicated characters   ***   or more.

{This Rosetta Code task was inspired by a newly introduced   (as of around
November 2019)   '''PL/I'''   BIF:   '''squeeze'''.}

;Examples:
In the following character string with a specified   ''immediately repeated''   character of   '''e''':

  The better the 4-wheel drive, the further you'll be from help when ya get stuck!

Only the 2nd   '''e'''   is an specified repeated character,   indicated by an underscore
(above),   even though they (the characters) appear elsewhere in the character string.

So, after ''squeezing'' the string, the result would be:

  The better the 4-whel drive, the further you'll be from help when ya get stuck!

Another example:
In the following character string,   using a specified immediately repeated character   '''s''':

  headmistressship

The "squeezed" string would be:

  headmistreship

;Task:
Write a subroutine/function/procedure/routine***   to locate a   ''specified immediately repeated''   character
and   ''squeeze''   (delete)   them from the character string.   The
character string can be processed from either direction.

Show all output here, on this page:
:*   the   specified repeated character   (to be searched for and possibly ''squeezed''):
:*   the   original string and its length
:*   the       resultant string and its length
:*   the above strings should be "bracketed" with   '''<<<'''   and   '''>>>'''   (to delineate blanks)
;*   <<<<<<Guillemets may be used instead for "bracketing" for the more artistic programmers,   shown used here>>>>>>

Use (at least) the following five strings,   all strings are length seventy-two (characters, including blanks),   except
the 1st string:

                                                                                immediately
  string                                                                            repeated
  number                                                                            character
                                                                                ( |   a blank,  a minus,  a seven,  a period)
         ++
    1    |+-----------------------------------------------------------------------+    ' '    <######  a null string  (length zero)
    2    |"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln |    '-'
    3    |..1111111111111111111111111111111111111111111111111111111111111117777888|    '7'
    4    |I never give 'em hell, I just tell the truth, and they think it's hell. |    '.'
    5    |                                                    --- Harry S Truman  |  (below)  <######  has many repeated blanks
         +------------------------------------------------------------------------+     |
                                                                                |
                                                                                |
         For the 5th string  (Truman's signature line),  use each of these  specified immediately  repeated characters:
                                   *  a blank
                                   *  a minus
                                   *  a lowercase  '''r'''

Note:   there should be seven results shown,   one each for the 1st four strings,   and three results for
the 5th string.

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

#define COLLAPSE 0
#define SQUEEZE 1

typedef struct charList{
    char c;
    struct charList *next;
} charList;

/*
Implementing strcmpi, the case insensitive string comparator, as it is not part of the C Standard Library.

Comment this out if testing on a compiler where it is already defined.
*/

int strcmpi(char str1[100],char str2[100]){
    int len1 = strlen(str1), len2 = strlen(str2), i;

    if(len1!=len2){
        return 1;
    }

    else{
        for(i=0;i<len1;i++){
            if((str1[i]>='A'&&str1[i]<='Z')&&(str2[i]>='a'&&str2[i]<='z')&&(str2[i]-65!=str1[i]))
                return 1;
            else if((str2[i]>='A'&&str2[i]<='Z')&&(str1[i]>='a'&&str1[i]<='z')&&(str1[i]-65!=str2[i]))
                return 1;
            else if(str1[i]!=str2[i])
                return 1;
        }
    }

    return 0;
}

charList *strToCharList(char* str){
    int len = strlen(str),i;

    charList *list, *iterator, *nextChar;

    list = (charList*)malloc(sizeof(charList));
    list->c = str[0];
    list->next = NULL;

    iterator = list;

    for(i=1;i<len;i++){
        nextChar = (charList*)malloc(sizeof(charList));
        nextChar->c = str[i];
        nextChar->next = NULL;

        iterator->next = nextChar;
        iterator = nextChar;
    }

    return list;
}

char* charListToString(charList* list){
    charList* iterator = list;
    int count = 0,i;
    char* str;

    while(iterator!=NULL){
        count++;
        iterator = iterator->next;
    }

    str = (char*)malloc((count+1)*sizeof(char));
    iterator = list;

    for(i=0;i<count;i++){
        str[i] = iterator->c;
        iterator = iterator->next;
    }

    free(list);
    str[i] = '\0';

    return str;
}

char* processString(char str[100],int operation, char squeezeChar){
    charList *strList = strToCharList(str),*iterator = strList, *scout;

    if(operation==SQUEEZE){
        while(iterator!=NULL){
            if(iterator->c==squeezeChar){
                scout = iterator->next;

                while(scout!=NULL && scout->c==squeezeChar){
                        iterator->next = scout->next;
                        scout->next = NULL;
                        free(scout);
                        scout = iterator->next;
                }
            }
            iterator = iterator->next;
        }
    }

    else{
        while(iterator!=NULL && iterator->next!=NULL){
            if(iterator->c == (iterator->next)->c){
                scout = iterator->next;
                squeezeChar = iterator->c;

                while(scout!=NULL && scout->c==squeezeChar){
                        iterator->next = scout->next;
                        scout->next = NULL;
                        free(scout);
                        scout = iterator->next;
                }
            }
            iterator = iterator->next;
        }
    }

    return charListToString(strList);
}

void printResults(char originalString[100], char finalString[100], int operation, char squeezeChar){
    if(operation==SQUEEZE){
        printf("Specified Operation : SQUEEZE\nTarget Character : %c",squeezeChar);
    }

    else
        printf("Specified Operation : COLLAPSE");

    printf("\nOriginal %c%c%c%s%c%c%c\nLength : %d",174,174,174,originalString,175,175,175,(int)strlen(originalString));
    printf("\nFinal    %c%c%c%s%c%c%c\nLength : %d\n",174,174,174,finalString,175,175,175,(int)strlen(finalString));
}

int main(int argc, char** argv){
    int operation;
    char squeezeChar;

    if(argc<3||argc>4){
        printf("Usage : %s <SQUEEZE|COLLAPSE> <String to be processed> <Character to be squeezed, if operation is SQUEEZE>\n",argv[0]);
        return 0;
    }

    if(strcmpi(argv[1],"SQUEEZE")==0 && argc!=4){
        scanf("Please enter characted to be squeezed : %c",&squeezeChar);
        operation = SQUEEZE;
    }

    else if(argc==4){
        operation = SQUEEZE;
        squeezeChar = argv[3][0];
    }

    else if(strcmpi(argv[1],"COLLAPSE")==0){
        operation = COLLAPSE;
    }

    if(strlen(argv[2])<2){
        printResults(argv[2],argv[2],operation,squeezeChar);
    }

    else{
        printResults(argv[2],processString(argv[2],operation,squeezeChar),operation,squeezeChar);
    }

    return 0;
}


Dice game probabilities

Two players have a set of dice each. The first player has nine dice with four faces each, with numbers one to four. The second player has six normal dice with six faces each, each face has the usual numbers from one to six.

They roll their dice and sum the totals of the faces. The player with the highest total wins (it's a draw if the totals are the same). What's the probability of the first player beating the second player?

Later the two players use a different set of dice each. Now the first player has five dice with ten faces each, and the second player has six dice with seven faces each. Now what's the probability of the first player beating the second player?

This task was adapted from the Project Euler Problem n.205:
https://projecteuler.net/problem=205

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

typedef uint32_t uint;
typedef uint64_t ulong;

ulong ipow(const uint x, const uint y) {
    ulong result = 1;
    for (uint i = 1; i <= y; i++)
        result *= x;
    return result;
}

uint min(const uint x, const uint y) {
    return (x < y) ? x : y;
}

void throw_die(const uint n_sides, const uint n_dice, const uint s, uint counts[]) {
    if (n_dice == 0) {
        counts[s]++;
        return;
    }

    for (uint i = 1; i < n_sides + 1; i++)
        throw_die(n_sides, n_dice - 1, s + i, counts);
}

double beating_probability(const uint n_sides1, const uint n_dice1,
                           const uint n_sides2, const uint n_dice2) {
    const uint len1 = (n_sides1 + 1) * n_dice1;
    uint C1[len1];
    for (uint i = 0; i < len1; i++)
        C1[i] = 0;
    throw_die(n_sides1, n_dice1, 0, C1);

    const uint len2 = (n_sides2 + 1) * n_dice2;
    uint C2[len2];
    for (uint j = 0; j < len2; j++)
        C2[j] = 0;
    throw_die(n_sides2, n_dice2, 0, C2);

    const double p12 = (double)(ipow(n_sides1, n_dice1) * ipow(n_sides2, n_dice2));

    double tot = 0;
    for (uint i = 0; i < len1; i++)
        for (uint j = 0; j < min(i, len2); j++)
            tot += (double)C1[i] * C2[j] / p12;
    return tot;
}

int main() {
    printf("%1.16f\n", beating_probability(4, 9, 6, 6));
    printf("%1.16f\n", beating_probability(10, 5, 7, 6));
    return 0;
}


Digital root

The digital root, X, of a number, n, is calculated:
: find X as the sum of the digits of n
: find a new X by summing the digits of X, repeating until X has only one digit.

The additive persistence is the number of summations required to obtain the single digit.

The task is to calculate the additive persistence and the digital root of a number, e.g.:
:627615 has additive persistence 2 and digital root of 9;
:39390 has additive persistence 2 and digital root of 6;
:588225 has additive persistence 2 and digital root of 3;
:393900588225 has additive persistence 2 and digital root of 9;

The digital root may be calculated in bases other than 10.

;See:
* [[Casting out nines]] for this wiki's use of this procedure.
* [[Digital root/Multiplicative digital root]]
* [[Sum digits of an integer]]
* Digital root sequence on OEIS
* Additive persistence sequence on OEIS
* [[Iterated digits squaring]]

Solution:
#include <stdio.h>

int droot(long long int x, int base, int *pers)
{
	int d = 0;
	if (pers)
		for (*pers = 0; x >= base; x = d, (*pers)++)
			for (d = 0; x; d += x % base, x /= base);
	else if (x && !(d = x % (base - 1)))
			d = base - 1;

	return d;
}

int main(void)
{
	int i, d, pers;
	long long x[] = {627615, 39390, 588225, 393900588225LL};

	for (i = 0; i < 4; i++) {
		d = droot(x[i], 10, &pers);
		printf("%lld: pers %d, root %d\n", x[i], pers, d);
	}

	return 0;
}


Disarium numbers

A '''Disarium number''' is an integer where the sum of each digit raised to the power of its position in the number, is equal to the number.

;E.G.

'''135''' is a '''Disarium number''':

 11 + 32 + 53 == 1 + 9 + 125 == 135

There are a finite number of '''Disarium numbers'''.

;Task

* Find and display the first 18 '''Disarium numbers'''.

;Stretch

* Find and display all 20 '''Disarium numbers'''.

;See also

;* Geeks for Geeks - Disarium numbers
;* OEIS:A032799 - Numbers n such that n equals the sum of its digits raised to the consecutive powers (1,2,3,...)
;* Related task: Narcissistic decimal number
;* Related task: Own digits power sum  ''Which seems to be the same task as Narcissistic decimal number...''

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

int power (int base, int exponent) {
    int result = 1;
    for (int i = 1; i <= exponent; i++) {
        result *= base;
    }
    return result;
}

int is_disarium (int num) {
    int n = num;
    int sum = 0;
    int len = n <= 9 ? 1 : floor(log10(n)) + 1;
    while (n > 0) {
        sum += power(n % 10, len);
        n /= 10;
        len--;
    }

    return num == sum;
}

int main() {
    int count = 0;
    int i = 0;
    while (count < 19) {
        if (is_disarium(i)) {
            printf("%d ", i);
            count++;
        }
        i++;
    }
    printf("%s\n", "\n");
}


Display a linear combination

Display a finite linear combination in an infinite vector basis (e_1, e_2,\ldots).

Write a function that, when given a finite list of scalars (\alpha^1,\alpha^2,\ldots), creates a string representing the linear combination \sum_i\alpha^i e_i in an explicit format often used in mathematics, that is:

:\alpha^{i_1}e_{i_1}\pm|\alpha^{i_2}|e_{i_2}\pm|\alpha^{i_3}|e_{i_3}\pm\ldots

where \alpha^{i_k}\neq 0

The output must comply to the following rules:
*   don't show null terms, unless the whole combination is null.
:::::::  '''e(1)'''     is fine,     '''e(1) + 0*e(3)'''     or     '''e(1) + 0'''     is wrong.
*   don't show scalars when they are equal to one or minus one.
:::::::  '''e(3)'''     is fine,     '''1*e(3)'''     is wrong.
*   don't prefix by a minus sign if it follows a preceding term.   Instead you use subtraction.
:::::::  '''e(4) - e(5)'''     is fine,     '''e(4) + -e(5)'''     is wrong.

Show here output for the following lists of scalars:

 1)    1,  2,  3
 2)    0,  1,  2,  3
 3)    1,  0,  3,  4
 4)    1,  2,  0
 5)    0,  0,  0
 6)    0
 7)    1,  1,  1
 8)   -1, -1, -1
 9)   -1, -2,  0, -3
10)   -1

Solution:
#include<stdlib.h>
#include<stdio.h>
#include<math.h> /*Optional, but better if included as fabs, labs and abs functions are being used. */

int main(int argC, char* argV[])
{

	int i,zeroCount= 0,firstNonZero = -1;
	double* vector;

	if(argC == 1){
		printf("Usage : %s <Vector component coefficients seperated by single space>",argV[0]);
	}

	else{

		printf("Vector for [");
		for(i=1;i<argC;i++){
			printf("%s,",argV[i]);
		}
		printf("\b] -> ");

		vector = (double*)malloc((argC-1)*sizeof(double));

		for(i=1;i<=argC;i++){
			vector[i-1] = atof(argV[i]);
			if(vector[i-1]==0.0)
				zeroCount++;
			if(vector[i-1]!=0.0 && firstNonZero==-1)
				firstNonZero = i-1;
		}

		if(zeroCount == argC){
			printf("0");
		}

		else{
			for(i=0;i<argC;i++){
				if(i==firstNonZero && vector[i]==1)
					printf("e%d ",i+1);
				else if(i==firstNonZero && vector[i]==-1)
					printf("- e%d ",i+1);
				else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])>0.0)
					printf("- %lf e%d ",fabs(vector[i]),i+1);
				else if(i==firstNonZero && vector[i]<0 && fabs(vector[i])-abs(vector[i])==0.0)
					printf("- %ld e%d ",labs(vector[i]),i+1);
				else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])>0.0)
					printf("%lf e%d ",vector[i],i+1);
				else if(i==firstNonZero && vector[i]>0 && fabs(vector[i])-abs(vector[i])==0.0)
					printf("%ld e%d ",vector[i],i+1);
				else if(fabs(vector[i])==1.0 && i!=0)
					printf("%c e%d ",(vector[i]==-1)?'-':'+',i+1);
				else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])>0.0)
					printf("%c %lf e%d ",(vector[i]<0)?'-':'+',fabs(vector[i]),i+1);
				else if(i!=0 && vector[i]!=0 && fabs(vector[i])-abs(vector[i])==0.0)
					printf("%c %ld e%d ",(vector[i]<0)?'-':'+',labs(vector[i]),i+1);
			}
		}
	}

	free(vector);

	return 0;
}


Diversity prediction theorem

The   ''wisdom of the crowd''   is the collective opinion of a group of individuals rather than that of a single expert.

Wisdom-of-the-crowds research routinely attributes the superiority of crowd averages over individual judgments to the elimination of individual noise,   an explanation that assumes independence of the individual judgments from each other.

Thus the crowd tends to make its best decisions if it is made up of diverse opinions and ideologies.

Scott E. Page introduced the diversity prediction theorem:
: ''The squared error of the collective prediction equals the average squared error minus the predictive diversity''.

Therefore,   when the diversity in a group is large,   the error of the crowd is small.

;Definitions:
::*   Average Individual Error:   Average of the individual squared errors
::*   Collective Error:           Squared error of the collective prediction
::*   Prediction Diversity:       Average squared distance from the individual predictions to the collective prediction
::*   Diversity Prediction Theorem:   ''Given a crowd of predictive models'',     then
::::::   Collective Error   =   Average Individual Error   -   Prediction Diversity

;Task:
For a given   true   value and a number of number of estimates (from a crowd),   show   (here on this page):
:::*   the true value   and   the crowd estimates
:::*   the average error
:::*   the crowd error
:::*   the prediction diversity

Use   (at least)   these two examples:
:::*   a true value of   '''49'''   with crowd estimates of:   ''' 48   47   51'''
:::*   a true value of   '''49'''   with crowd estimates of:   ''' 48   47   51   42'''

;Also see:
:*   Wikipedia entry:   Wisdom of the crowd
:*   University of Michigan: PDF paper         (exists on a web archive,   the ''Wayback Machine'').

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

float mean(float* arr,int size){
	int i = 0;
	float sum = 0;

	while(i != size)
		sum += arr[i++];

	return sum/size;
}

float variance(float reference,float* arr, int size){
	int i=0;
	float* newArr = (float*)malloc(size*sizeof(float));

	for(;i<size;i++)
		newArr[i] = (reference - arr[i])*(reference - arr[i]);

	return mean(newArr,size);
}

float* extractData(char* str, int *len){
	float* arr;
	int i=0,count = 1;
	char* token;

	while(str[i]!=00){
		if(str[i++]==',')
			count++;
	}

	arr = (float*)malloc(count*sizeof(float));
	*len = count;

	token = strtok(str,",");

	i = 0;

	while(token!=NULL){
		arr[i++] = atof(token);
		token = strtok(NULL,",");
	}

	return arr;
}

int main(int argC,char* argV[])
{
	float* arr,reference,meanVal;
	int len;
	if(argC!=3)
		printf("Usage : %s <reference value> <observations separated by commas>");
	else{
		arr = extractData(argV[2],&len);

		reference = atof(argV[1]);

		meanVal = mean(arr,len);

		printf("Average Error : %.9f\n",variance(reference,arr,len));
		printf("Crowd Error : %.9f\n",(reference - meanVal)*(reference - meanVal));
		printf("Diversity : %.9f",variance(meanVal,arr,len));
	}

	return 0;
}