Language detail: C

Coverage: 83.72%
number of '+' ratings
contribution for coverage

Unsolved challenges

codes

Feed

Used modules

next >>

LL Golf Hole 3 - 13日の金曜日を数え上げる (Nested Flatten)
Cだとmktime(3C)を使うと便利です。
まぁ、ほんとにmktime()が本領発揮するのは日時へ変換したときなのですけど^^;;

// gcc -Wall -std=c99 doukaku197.c -o doukaku197
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <time.h>

static const char *weekdayname[] = {"Sun","Mon","Tue","Wed","Thi","Fri","Sat"};

int main(int argc, char *argv[])
{
    static const int YEAR_END = (2013 - 1900) + 1;
    struct tm t      = {0};
    time_t    now    = 0;
    int       count  = 0;

    now = time(NULL);
    localtime_r(&now, &t);
    t.tm_mday = 13; // 13日固定

    /* 2014年までの13日の金曜日を検索する */
    count = 0;
    while( t.tm_year < YEAR_END )
    {
        // 13日の金曜日を探す
        if( t.tm_wday == 5 )
        {
            // 13日の金曜日なら表示してカウントアップ
            printf("%d/%02d/%02d (%s)\n"
                    , t.tm_year+1900, t.tm_mon+1, t.tm_mday
                    , weekdayname[ t.tm_wday ]);
            count ++;
        }
        t.tm_mon ++;
        mktime( &t ); // 日時の再計算(正規化)
    }
    printf("COUNT:[%d]\n", count);

    return 0;
}
/* EOF */
ツェラーの公式を変形して。「今日の日付」はコマンドライン引数でもらいます。

$ ./fri13 2008 8 7
'09年2月13日
'09年3月13日
'09年11月13日
'10年8月13日
'11年5月13日
'12年1月13日
'12年4月13日
'12年7月13日
'13年9月13日
'13年12月13日
総数:10個
$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>

int main(int c, char *v[]) {
  int n = 0, y, m, y0 = atoi(v[1])-2000, m0 = atoi(v[2]);
  if (m0 < 3) { y0--; m0 += 12; }
  for (y = y0; y < 14; y++)
    for (m = 3; m < 15; m++) {
      if (y == y0 && (m < m0 || (m == m0 && atoi(v[3]) > 13))) continue;
      if (!((26*(m+1)/10+y+y/4)%7)) {
        printf("'%02d年%d月13日\n", (m>=13)?y+1:y, (m>=13)?m-12:m);
        n++;
      }
    }
  printf("総数:%d個\n", n);

  return 0;
}
出力の一時停止と再開 (Nested Flatten)
手抜きです。Unix likeなシステム限定です。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

void cleanup(void)
{
    system("stty sane");
    putc('\n', stderr);
}
int waitfor(int fd, int secs)
{
    fd_set fds;
    struct timeval tv = { secs, 0 };
    FD_ZERO(&fds);
    FD_SET(fd, &fds);
    return select(fd + 1, &fds, 0, 0, secs > 0 ? &tv : 0);
}
int main(void)
{
    int c = 0, timeout = 1;
    system("stty raw");
    atexit(cleanup);
    while (c != 'q')
        if (!waitfor(fileno(stdin), timeout))
            putc('a', stderr);
        else if ((c = getchar()) == 'p')
            timeout *= -1;
    return 0;
}
LL Golf Hole 2 - 文字列に含まれる単語の最初の文字を大文字にする (Nested Flatten)
外道版はUnix系なら後2byte短くなるんじゃないかと思ってみたり
1
2
/*●外道版(43byte)*/
main(){system("perl -pe's/\\b./\\U$&/g'");}
スタックオーバーフローで止まるのはダメ?
(うちのパソコンだと5万回くらいで終了。ただしゴミが出まくる)

putcharとgetcharのつづりをこれ以上短くできないのが痛いです。
やけくそで外道版も書いてみました。
1
2
3
4
5
●止まらない問題修正版(56byte)
b;main(a){b=getchar();~b&&main(putchar(b-a>64?b-32:b));}

●外道版(45byte)
main(){system("perl -pe\"s/\\b./\\U$&/g\"");}
lessの実装 (Nested Flatten)
効率はともかく、巨大なファイルでも表示できるように作ってみました。 表示はcurses、ファイルの行インデックススキャンをバックグラウンドで行うためにpthreadを使用しています。 行インデックスもテンポラリファイルとして書き出しているので、fpos_tが32bitの環境でも2GB、64bitなら8EBまでいける(自信なし)はずです。 ただし、システム側に懲りすぎたので、タブやら一行の折り返しやらは手を抜いて全く手付かずです。 検索機能もUIが手抜きのためインクリメンタルサーチしかできません。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
    Large less
        programed by M.Suzuki
        ver 0.1     2008/8/4

    key binding
        n,j,^n      scroll up
        p,k,^p      scroll down
        /           i-search
        ESC         i-search cancel
        TAB         next search(i-search only)
        q           quit
 */

#include <stdio.h>
#include <string.h>
#include <curses.h>
#include <pthread.h>

#define LINE_MAX    256     /* file text width max  */

#define False   0
#define True    (!False)

static pthread_mutex_t file_mutex;
static FILE* fileFp;
static FILE* seekFp;
static fpos_t lineTop;
static fpos_t lineMax;
static bool readMaxFlag;
static bool abortFlag;

static void ScanWait()
{
    pthread_mutex_lock(&file_mutex);
    while( lineTop + LINES >= lineMax ){
        static struct timespec time10ms = {0,10*1000*1000};
        pthread_mutex_unlock(&file_mutex);
        nanosleep(&time10ms,NULL);
        pthread_mutex_lock(&file_mutex);
        if( readMaxFlag ){
            break;
        }
    }   /* end of while */
    pthread_mutex_unlock(&file_mutex);
}

static char* ReadLine(int y, char* buff)
{
    char* text = NULL;

    ScanWait();
    pthread_mutex_lock(&file_mutex);
    if( lineTop + y + 1 < lineMax ){
        fpos_t offset = sizeof(fpos_t)*(lineTop+y);

        fsetpos(seekFp,&offset);
        fread(&offset,sizeof(fpos_t),1,seekFp);
        fsetpos(fileFp,&offset);
        if( fgets(buff,LINE_MAX,fileFp) ){
            text = buff;
        }
    }
    pthread_mutex_unlock(&file_mutex);
    return text;
}

static void DrawLine(int y)
{
    char* text;
    char buff[LINE_MAX+1];

    text = ReadLine(y,buff);
    if( text == NULL ){
        text = "~";
    }
    mvinsstr(y,0,text);
}

static void ViewAll()
{
    int y;

    erase();
    for(y=0;y<LINES;y++){
        DrawLine(y);
    }
}

static void RollUp()
{
    ScanWait();
    pthread_mutex_lock(&file_mutex);
    if( lineTop >= lineMax ){
        if( readMaxFlag ){
            pthread_mutex_unlock(&file_mutex);
            return;
        }
    }
    lineTop++;
    pthread_mutex_unlock(&file_mutex);
    move(0,0);
    deleteln();
    move(LINES-1,0);
    DrawLine(LINES-1);
    refresh();
}

static void RollDown()
{
    pthread_mutex_lock(&file_mutex);
    if( lineTop <= 0 ){
        pthread_mutex_unlock(&file_mutex);
        return;
    }
    lineTop--;
    pthread_mutex_unlock(&file_mutex);
    move(0,0);
    insdelln(1);
    DrawLine(0);
    refresh();
}

static void Search()
{
    char search[LINE_MAX];
    int len = 0;

    while(1){
        int key = getch();
        int y = 0;
        if( key == 0x1b ){
            break;
        }
        if( key == '\t' ){
            y = 1;
        } else {
            if( len < LINE_MAX ){
                search[len++] = key;
                search[len] = '\0';
            }
        }
        while(1){
            char buff[LINE_MAX+1];
            if( ReadLine(y,buff) == NULL ){
                return;
            }
            if( strstr(buff,search) ){
                pthread_mutex_lock(&file_mutex);
                lineTop += y;
                pthread_mutex_unlock(&file_mutex);
                ViewAll();
                break;
            }
            y++;
        }   /* end of while */
    }   /* end of while */
}

static void KeyLoop()
{
    ViewAll();
    while(1){
        int key = getch();
        if( key == 'q' ){
            break;
        }
        switch(key){
          case 'N'-'@':
          case 'n':
          case 'j':
            RollUp();
            break;
          case 'P'-'@':
          case 'p':
          case 'k':
            RollDown();
            break;
          case '/':
            Search();
            break;
        }   /* end of switch */
    }   /* end of while */
}

void* ScanThread(void* arg)
{
    fpos_t filePos;

    fgetpos(fileFp, &filePos);
    while(1){
        char buff[LINE_MAX+1];
        fpos_t fpos = sizeof(fpos_t)*lineMax;

        pthread_mutex_lock(&file_mutex);
        fsetpos(seekFp,&fpos);
        fwrite(&filePos,sizeof(fpos_t),1,seekFp);
        lineMax++;
        fsetpos(fileFp,&filePos);
        if( fgets(buff,LINE_MAX,fileFp) == NULL ){
            break;
        }
        fgetpos(fileFp,&filePos);
        if( abortFlag ){
            break;
        }
        pthread_mutex_unlock(&file_mutex);
    }   /* end of while */
    readMaxFlag = True;
    pthread_mutex_unlock(&file_mutex);
    return NULL;
}

static void MainLoop()
{
    pthread_t scanThread_id;
    char tmpName[L_tmpnam];

    tmpnam(tmpName);
    if( (seekFp=fopen(tmpName,"w+b")) == NULL ){
        perror(tmpName);
        return;
    }

    pthread_mutex_init(&file_mutex,NULL);

    lineTop = 0;
    lineMax = 0;
    if( pthread_create(&scanThread_id,NULL,ScanThread,NULL)!=0){
        perror("ScanThread");
        return;
    }

    initscr();
    noecho();
    raw();
    cbreak();

    KeyLoop();

    nocbreak();
    noraw();
    echo();
    endwin();

    pthread_mutex_lock(&file_mutex);
    abortFlag = True;
    pthread_mutex_unlock(&file_mutex);
    pthread_join(scanThread_id,NULL);

    fclose(seekFp);
    remove(tmpName);
}

int main(int argc, char* argv[])
{
    char* fname = NULL;
    int i;

    for(i=1;i<argc;i++){
        char* p = argv[i];
        if( *p == '-' ){
            /* option   */
        } else {
            fname = argv[i];
        }
    }   /* end of for */
    if( fname != NULL ){
        if( (fileFp=fopen(fname,"r")) == NULL ){
            perror(fname);
            return 1;
        }
        MainLoop();
        fclose(fileFp);
    }
    return 0;
}
LL Golf Hole 2 - 文字列に含まれる単語の最初の文字を大文字にする (Nested Flatten)
だんだん凶悪に…55byte
1
b;main(a){b=getchar();main(putchar(b>96&a<33?b-32:b));}

Cygwin gcc3.4.4で確認

1
main(a,b){for(;(b=getchar())>0;)a=putchar(b>96&a<33?b-32:b);}

ちまちま^^; 81byte

1
a;main(){char*s=gets(&a);for(;*s;s++)putchar(&a==s||*(s-1)==' '?toupper(*s):*s);}

参考ページに影響を受けてみた。入出力込みで84byte

1
a;main(){char*s=gets(&a);for(;*s;s++)if(&a==s||*(s-1)==' ')*s=toupper(*s);puts(&a);}
VCEE2008でコンパイルできました。
LL Future
LL Day And Night
Hello, I Am A Cat
1
2
3
4
5
6
7
f(char *s){*s=toupper(*s);while(*++s)if(*(s-1)==' ')*s=toupper(*s);}

main(){
    char *s1="LL future",*s2="LL day and night",*s3="hello, i am a cat";
    f(s1);f(s2);f(s3);
    printf("%s\n%s\n%s\n",s1,s2,s3);
}
環境変数の取得 (Nested Flatten)

環境を選ぶかもしれません。

環境変数名=値

という文字列の配列なので、strtokで分割。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[], char *envp[])
{
    char **p;
    char *name;
    char *value;

    for(p = envp; p != NULL; p++) {
        name  = strtok(*p, "=");
        value = strtok(NULL, "=");
        printf("%s = %s\n", name, value);
    }

    return 0;
}
比較しないソートの作成 (Nested Flatten)

初投稿です。 勢いで作ったので例外処理とか入ってません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<stdio.h>

void sort(int min, int max, int len, int data[], int *result);

int main()
{
        int min = -1;
        int max = 10;
        int data[] = {-1, 9, 4, 8, 9, 6, 3, 9, 5, 2};
        int len = 10;
        int i;
        int *result;

        sort(min, max, len, data, result);
        for(i = 0; i < len; i++)
        {
                printf("%d\n", result[i]);
        }

        return 0;
}

void sort(int min, int max, int len, int data[], int * result)
{
        int bucket[len];
        int i, j;
        int idx = 0;

        for(i = min; i < max; i++)
        {
                bucket[i] = 0;
        }

        for(i = 0; i < len; i++)
        {
                bucket[data[i]]++;
        }


        for(i = min; i < max; i++)
        {
                for(j = 0; j < bucket[i]; j++)
                {
                        result[idx++] = i;
                }
        }
}
設定ファイルから値を取得 (Nested Flatten)

PerlのConfig::Simple かっこいいっす

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-------------------------------------------

ITEM_NAME=りんご
ITEM_COST=200

-------------------------------------------

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

#define SIZE 256
#define ITEM_NAME "ITEM_NAME"
#define ITEM_COST "ITEM_COST"

char* get_value(const char *path, const char *key, char *value) {
    char buf[SIZE];
    FILE *f;
    char *key_ptr, *val_ptr;

    f = fopen(path, "r");
    while(fgets(buf, sizeof buf, f) != NULL) {
        if((key_ptr = strstr(buf, key)) != NULL) {
            if((val_ptr = strchr(key_ptr, '=')) != NULL) {
                strcpy(value, ++val_ptr);
            }
        }
    }
    *(value + strlen(value) -1) = '\0';
    return value;
}

int main(int argc, char *argv[])
{
    char value1[SIZE], value2[SIZE];
    char path[] = "ShowPrice.ini";

    get_value(path, ITEM_NAME, value1);
    get_value(path, ITEM_COST, value2);
    printf("「%s」は%.f円(税込み)", value1, (atoi(value2)*1.05));

    return 0;
}
出力の一時停止と再開 (Nested Flatten)
ども、raynstardです。
入力がブロッキングされてしまうのは
入力モードを変更してあげないからですね。

UNIXでgetche()の作り方というのを調べるといろいろと出てくると思います。
ポイントはtermiosでカノニカルモードを解除してあげていることと
標準出力のバッファリングをなしにしているところでしょうか?
標準入力の方はおまけです。
// gcc -Wall -std=c99 doukaku179.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdio.h>
#include <stdbool.h>
#include <termios.h>
#include <time.h>

static struct termios termios_save;
static bool isContinued = true;
static bool enableOutputScreen = true;

int initKeyInput(void)
{
    struct termios t;
    tcgetattr(0, &termios_save);
    tcgetattr(0, &t);
    t.c_lflag &= ~(ICANON|ECHO);
    t.c_cc[VMIN]  = 0;
    t.c_cc[VTIME] = 0;
    tcsetattr(0, TCSANOW, &t);
    setvbuf(stdin, NULL, _IONBF, 0);
    return 0;
}

int main(int argc, char *argv[])
{
    char key;
    ssize_t read_size;
    time_t old, now;

    initKeyInput();
    setvbuf(stdout, NULL, _IONBF, 0);

    old = 0;
    while( isContinued )
    {
        now = time(NULL);
        if( now != old )
        {
            old = now;
            if( enableOutputScreen == true )
            {
                printf("a");
            }
        }
        read_size = fread(&key, 1, sizeof(key), stdin);
        if( read_size > 0 )
        {
            switch( key )
            {
                case 'q':   /* quit */
                    isContinued = false;
                    break;
                case 'p':   /* pause */
                    enableOutputScreen = (enableOutputScreen != true);
                    break;
                default:
                    break;
            }
        }
    }
    tcsetattr(0, TCSANOW, &termios_save);
    printf("\n");
    return 0;
}
/* EOF */
コメントの削除 (Nested Flatten)

相互再帰風に書いてみました

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <stdio.h>

typedef void* (*filter)(int c, FILE* out);

void drive(filter f, FILE* in, FILE* out)
{
    int c;

    do {
        c = fgetc(in);

        if (c == EOF)
            break;
    } while ((f = f(c, out)));
}

#define CALL(func)                              \
    do { return func; } while(0)

#define FINISH()                                \
    do { return NULL; } while(0)


void* normal_code(int, FILE*);
void* next_of_slash_in_normal_code(int, FILE*);
void* string(int, FILE*);
void* next_of_backslash_in_string(int, FILE*);
void* single_quote(int, FILE*);
void* next_of_backslash_in_single_quote(int, FILE*);
void* comment(int, FILE*);
void* next_of_star_in_comment(int, FILE*);
void* oneline_comment(int, FILE*);

void* normal_code(int c, FILE* out)
{
    switch (c) {
    case '/':
        CALL(next_of_slash_in_normal_code);

    case '"':
        fputc(c, out);
        CALL(string);

    case '\'':
        fputc(c, out);
        CALL(single_quote);

    default:
        fputc(c, out);
        CALL(normal_code);
    }
}

void* next_of_slash_in_normal_code(int c, FILE* out)
{
    switch (c) {
    case '*':
        CALL(comment);
        
    case '/':
        CALL(oneline_comment);

    default:
        fputc('/', out);
        fputc(c, out);
        CALL(normal_code);
    }
}

void* string(int c, FILE* out)
{
    fputc(c, out);

    switch (c) {
    case '\\':
        CALL(next_of_backslash_in_string);

    case '"':
        CALL(normal_code);

    default:
        CALL(string);
    }
}

void* next_of_backslash_in_string(int c, FILE* out)
{
    fputc(c, out);
    CALL(string);
}

void* single_quote(int c, FILE* out)
{
    fputc(c, out);

    switch (c) {
    case '\\':
        CALL(next_of_backslash_in_single_quote);

    case '\'':
        CALL(normal_code);

    default:
        CALL(single_quote);
    }
}

void* next_of_backslash_in_single_quote(int c, FILE* out)
{
    fputc(c, out);
    CALL(single_quote);
}

void* comment(int c, FILE* out)
{
    if (c == '*')
        CALL(next_of_star_in_comment);
    else
        CALL(comment);
}

void* next_of_star_in_comment(int c, FILE* out)
{
    if (c == '/')
        CALL(normal_code);
    else
        CALL(comment);
}

void* oneline_comment(int c, FILE* out)
{
    if (c == '\n')
        CALL(normal_code);
    else
        CALL(oneline_comment);
}

void decomment(FILE* in, FILE* out)
{
    drive(normal_code, in, out);
}

int main(int argc, char** argv)
{
    decomment(stdin, stdout);
    return 0;
}

やっつけです

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
  FILE *f;
  char c;
  int flg = 0;

  if(argc != 2)
    exit(EXIT_FAILURE);

  f = fopen(argv[1],  "r");

  while((c = fgetc(f)) != EOF) {
    if((flg == 0) && (c == '/')) {
      flg = 1;
      continue;
    } else if((flg == 1) && (c ==