C言語で書いてみました

過去の情報処理技術者試験の出題をもとにして、Cのソースを起こしてみました。

■ カプレカ操作2(平成18年春午後2問1設問3)

/*
 *  ソフトウェア開発 平成18年春午後2問1設問3
 *  カプレカ操作
 */

#include <stdio.h>

#define HIST_MAX    30

/* 設問3 */
int DR, DL, BR, BL, borrow, r;

void kaprekar(int d[], int result[], int n)
{
    int i;
    for (i = 0; i <= 9; i++)
        result[i] = 0;
    DR = 0;
    DL = 9;
    BR = d[DR];
    BL = d[DL];
    borrow = 0;
    for (i = 0; i <= n - 1; i++) {
        while (i >= BR) {
            DR = DR + 1;
            BR = BR + d[DR];
        }
        while (i >= BL) {
            DL = DL - 1;
            BL = BL + d[DL];
        }
        r = DR - DL - borrow;
        borrow = 0;
        if (r < 0) {
            r = 10 + r;
            borrow = 1;
        }
        result[r] = result[r] + 1;
    }
}

/* サイクルの検出(手抜き) */
int history[HIST_MAX][10], sp;

int check(int d[])
{
    int i, j, k, flag;
    for (i = 0; i < sp; i++) {
        for (j = 0; j < 10; j++) {
            flag = 0;
            if (history[i][j] != d[j]) {
                flag = 1;
                break;
            }
        }
        if (flag == 0) return 1;
    }
    for (k = 0; k < 10; k++)
        history[sp][k] = d[k];
    sp++;
    return 0;   
}

/* 実行例 */
int main()
{
    int d[10] = { 0 }, result[10], i, keta;
    char s[127];

    printf("数を入力:");
    fgets(s, 127, stdin);
    i = keta = 0;
    while (s[i] != '\n' && s[i] != '\0') {
        if (s[i] >= '0' && s[i] <= '9') {
            d[s[i]-'0']++;
            keta++;
        }
        i++;
    }

    sp = 0;
    while (check(d) == 0) {
        kaprekar(d, result, keta);
        for (i = 0; i < 10; i++)
            printf("%d", d[i] = result[i]);
        putchar('\n');
    }

    return 0;
}