目次: Might and Magic ファミコン版 - まとめリンク
Might and Magic Book One TAS US 版をさらに 6秒くらい短縮(7:32.39 → 7:25.80)しました。
TASVideos に再投稿するなら何かもう 1つくらいは改善してから送りたいですが、良いアイデアが思いつかないです……。
GNU tar の x オプションは圧縮された tar でも正しく展開してくれます。圧縮方法は gzip, bzip, xz, ... など複数存在しますが、どのように判定しているんでしょう?まさか拡張子でしょうか?
こういうときに OSS は便利です。ソースコードを見ればわかるはず。バージョンはどれでも仕組み自体は同じだと思いますが、とりあえず最新版リリース GNU tar 1.34 にしました。git リポジトリへのリンクも貼っておきます。
// src/buffer.c
/* Compression detection */
enum compress_type {
ct_none, /* Unknown compression type */
ct_tar, /* Plain tar file */
ct_compress,
ct_gzip,
ct_bzip2,
ct_lzip,
ct_lzma,
ct_lzop,
ct_xz,
ct_zstd
};
static enum compress_type archive_compression_type = ct_none;
struct zip_magic
{
enum compress_type type;
size_t length;
char const *magic;
};
struct zip_program
{
enum compress_type type;
char const *program;
char const *option;
};
static struct zip_magic const magic[] = {
{ ct_none, 0, 0 },
{ ct_tar, 0, 0 },
{ ct_compress, 2, "\037\235" },
{ ct_gzip, 2, "\037\213" },
{ ct_bzip2, 3, "BZh" },
{ ct_lzip, 4, "LZIP" },
{ ct_lzma, 6, "\xFFLZMA" },
{ ct_lzop, 4, "\211LZO" },
{ ct_xz, 6, "\xFD" "7zXZ" },
{ ct_zstd, 4, "\x28\xB5\x2F\xFD" },
};
各圧縮方式に固有のマジックヘッダを定義している部分がありました。さすがに拡張子などという雑な判定ではなさそうです。そりゃそうか。
// src/buffer.c
/* Check if the file ARCHIVE is a compressed archive. */
static enum compress_type
check_compressed_archive (bool *pshort)
{
struct zip_magic const *p;
bool sfr;
bool temp;
if (!pshort)
pshort = &temp;
/* Prepare global data needed for find_next_block: */
record_end = record_start; /* set up for 1st record = # 0 */
sfr = read_full_records;
read_full_records = true; /* Suppress fatal error on reading a partial
record */
*pshort = find_next_block () == 0;
/* Restore global values */
read_full_records = sfr;
if (record_start != record_end /* no files smaller than BLOCKSIZE */
&& (strcmp (record_start->header.magic, TMAGIC) == 0
|| strcmp (record_start->buffer + offsetof (struct posix_header,
magic),
OLDGNU_MAGIC) == 0)
&& tar_checksum (record_start, true) == HEADER_SUCCESS)
/* Probably a valid header */
return ct_tar;
for (p = magic + 2; p < magic + NMAGIC; p++) //★★magic はさきほど示したコードで定義していた配列★★
if (memcmp (record_start->buffer, p->magic, p->length) == 0) //★★ここで比較★★
return p->type;
return ct_none;
}
各圧縮方式に固有のバイナリ列が存在するか?を memcmp() で見ています。結構シンプルな仕組みですね。
C ライブラリがメモリを確保する際、内部でシステムコールを呼んで OS にメモリ確保を依頼します。現状の Linux ですとメモリ確保は 2種類用意されています。1つは懐かしの brk(), sbrk() で、もう 1つは mmap() で匿名ページ(MAP_ANONYMOUS)を割り当てる方法です。
匿名ページ(MAP_ANONYMOUS)によるメモリ確保の場合、0 初期化されていることが定められています。brk, sbrk が返す領域はどうでしょう?SUSv3 を見ましたが brk, sbrk の項目そのものがありません。
SUSv2 を見ると LEGACY 扱いではあるものの、brk の項目が(brk へのリンク)ありました。説明を見ると、
DESCRIPTION
The brk() and sbrk() functions are used to change the amount of space allocated for the calling process. The change is made by resetting the process' break value and allocating the appropriate amount of space. The amount of allocated space increases as the break value increases. The newly-allocated space is set to 0.
とのことです。0 初期化は必須ですね。
自作 OS もどきを作っていて、brk で確保した領域を未初期化で返していました。newlib だと動いてしまうんですが、glibc はたまに死んでしまうことがあって気づきました。実装する前に規格を見ましょう。行き当たりばったりは良くないです……はい。
一番たくさんの村があるのはどの都道府県でしょうか?地図を見てカウントしても良いのですが、こういう面倒なことは機械にやってもらいましょう。
総務省のサイト(総務省 - 地方行政のデジタル化 - 全国地方公共団体コード)に全国の市町村の一覧があります。サイトにある Excel ファイルから、余計な列を落として都道府県名と市町村名だけにしたテキストファイル( 都道府県名ファイル、
市町村名ファイル)を用意します。
for i in `cat 20220725_prefs.txt`; do echo -n "${i} "; grep ${i} 20220725_cities.txt | grep '村$' | wc -l; done 北海道 21 青森県 8 岩手県 4 宮城県 1 秋田県 3 山形県 3 福島県 15 茨城県 2 栃木県 0 群馬県 8 埼玉県 1 千葉県 1 東京都 8 神奈川県 1 新潟県 4 富山県 1 石川県 0 福井県 0 山梨県 6 長野県 35 岐阜県 2 静岡県 0 愛知県 2 三重県 0 滋賀県 0 京都府 1 大阪府 1 兵庫県 0 奈良県 12 和歌山県 1 鳥取県 1 島根県 1 岡山県 2 広島県 0 山口県 0 徳島県 1 香川県 0 愛媛県 0 高知県 6 福岡県 2 佐賀県 0 長崎県 0 熊本県 8 大分県 1 宮崎県 3 鹿児島県 4 沖縄県 19
正解は長野県でした。平成の市町村大合併で村は大分減りましたね。なぜか長野、北海道だけたくさんの村が残っていますけど……。
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2021.
Powered by PHP 5.2.17.
using GD bundled (2.0.34 compatible)(png support.)