昨日のhdkさんの日記(リンク)を見て、自分も挑戦してみました。
元ネタは2011年のブログ(リンク)ですね。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int atod(char *str)
{
int len = strlen(str);
int r = 0;
int i;
for (i = 0; i < len; i++) {
r *= 26;
r += str[i] - 'A' + 1;
}
return r;
}
void dtoa(int r, char *buf)
{
char tmp[256];
int p = 0;
int i, len;
memset(tmp, 0, sizeof(tmp));
r -= 1;
while (r >= 0) {
tmp[p] = 'A' + (r % 26);
r = r / 26 - 1;
p++;
}
len = strlen(tmp);
for (i = 0; i < len; i++) {
buf[len - i - 1] = tmp[i];
}
}
int main(int argc, char *argv[])
{
int dir = atoi(argv[1]);
char *str = argv[2];
int r;
char buf[256];
switch (dir) {
case 0:
r = atod(str);
printf("%d\n", r);
break;
case 1:
memset(buf, 0, strlen(buf));
dtoa(atoi(str), buf);
printf("'%s'\n", buf);
break;
}
return 0;
}
掛かった時間は正確に計ってないですが、atodの方が10分くらいで、dtoaの方が1時間くらいだったと思います。
2文字目以降を求める式(r = r / 26 - 1)を思いつくのに、予想以上に時間が掛かりました。
$ for i in `seq 1 100` `seq 650 750` `seq 17550 17650`; do echo $i `./a.out 1 $i`; done | egrep "[ABYZ]'" 1 'A' 2 'B' 25 'Y' 26 'Z' 27 'AA' 28 'AB' 51 'AY' 52 'AZ' 53 'BA' 54 'BB' 77 'BY' 78 'BZ' 79 'CA' 80 'CB' 650 'XZ' 651 'YA' 652 'YB' 675 'YY' 676 'YZ' 677 'ZA' 678 'ZB' 701 'ZY' 702 'ZZ' 703 'AAA' 704 'AAB' 727 'AAY' 728 'AAZ' 729 'ABA' 730 'ABB' 17550 'YXZ' 17551 'YYA' 17552 'YYB' 17575 'YYY' 17576 'YYZ' 17577 'YZA' 17578 'YZB' 17601 'YZY' 17602 'YZZ' 17603 'ZAA' 17604 'ZAB' 17627 'ZAY' 17628 'ZAZ' 17629 'ZBA' 17630 'ZBB'
二桁目がAになるとき、二桁目がZになるとき、三桁目がAになるとき、三桁目がZになるとき、いずれも特におかしくならないので、他の桁数でもたぶん大丈夫でしょう。
< | 2016 | > | ||||
<< | < | 03 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | 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 | - | - |
合計:
本日: