もぐてっく

人は1つ歳をとるたび、1ビットづつ大きくなれると信じてた。

ネコミミ言語をデコードしてみた

1レス内に全命令のリファレンスが入る素敵な言語。
http://alfalfalfa.com/archives/01159.html

Hello World!が基地外じみててワラタ。


さっそく師匠を捕まえて「お前が作者だろう」とひとしきりいじった後、これってほんとにHello Worldなのか気になった。
"H"とかどっから引っ張ってきてるの?

真面目に読んでみる。
前の方のアドレスをカウンタにしてASCIIコードを上手いこと作ってるみたいだけど、これは手デコードがメンドイなぁ。
インタプリタを書くほどやる気もないので、Cで相当のコードを書いてみた。

#include <stdio.h>

#define ONIISAMA ((*p)++)
#define WATASHINOSHIMOBE ((*p)--)
#define NEKOMIMI (p++)
#define NEKOMIMIMODE (p--)
#define YAKUSOKUYO (printf("%c",*p))
#define KISSKISS while(*p != 0){
#define KISSSHITAKUNATTYATTA }

int main(int argc,char *argv[])
{
char data[128] = {0};
char *p = data;

ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
KISSKISS
NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
KISSKISS
NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
ONIISAMA; ONIISAMA; NEKOMIMI; ONIISAMA; ONIISAMA;
NEKOMIMIMODE; NEKOMIMIMODE; NEKOMIMIMODE; WATASHINOSHIMOBE;
KISSSHITAKUNATTYATTA
NEKOMIMI; ONIISAMA; ONIISAMA; NEKOMIMI; ONIISAMA;
NEKOMIMIMODE; NEKOMIMIMODE; NEKOMIMIMODE; WATASHINOSHIMOBE;
KISSSHITAKUNATTYATTA
NEKOMIMI; NEKOMIMI; YAKUSOKUYO; NEKOMIMI; ONIISAMA;
YAKUSOKUYO; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
ONIISAMA; ONIISAMA; ONIISAMA; YAKUSOKUYO; YAKUSOKUYO;
ONIISAMA; ONIISAMA; ONIISAMA; YAKUSOKUYO; NEKOMIMI;
YAKUSOKUYO; NEKOMIMIMODE; NEKOMIMIMODE; WATASHINOSHIMOBE;
NEKOMIMIMODE; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
KISSKISS
NEKOMIMI; ONIISAMA; ONIISAMA; ONIISAMA; ONIISAMA;
NEKOMIMIMODE; WATASHINOSHIMOBE;
KISSSHITAKUNATTYATTA
NEKOMIMI; YAKUSOKUYO; NEKOMIMI; YAKUSOKUYO;
ONIISAMA; ONIISAMA; ONIISAMA; YAKUSOKUYO;
WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE;
WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE;
YAKUSOKUYO; WATASHINOSHIMOBE; WATASHINOSHIMOBE;
WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE;
WATASHINOSHIMOBE; WATASHINOSHIMOBE; WATASHINOSHIMOBE;
YAKUSOKUYO; NEKOMIMI; ONIISAMA; YAKUSOKUYO;

return 0;
}

キス系の命令の説明が煩雑だが、結局はwhile(*p != 0)だと悟った。
実行してみる。

akari:/tmp# gcc a.c
akari:/tmp# ./a.out
Hello World!akari:/tmp#

おお・・・。

ロジック的には正しいことは分かったけど、どういうロジックかは分からん。
もうちょいC言語っぽくしてみた。

#include <stdio.h>

#define COUNTER_1 0
#define COUNTER_2 1
#define MOJI_UPPER 2
#define MOJI_LOWER 3
#define MOJI_SYMBOL 4

int main(int argc,char *argv[])
{
        char data[128] = {0};
        char *p = data;

        for(p[COUNTER_1] = 4;p[COUNTER_1] > 0;p[COUNTER_1]--)
        {
                for(p[COUNTER_2] = 4;p[COUNTER_2] > 0;p[COUNTER_2]--)
                {
                        p[MOJI_UPPER] += 4;
                        p[MOJI_LOWER] += 6;
                        p[MOJI_SYMBOL] += 2;
                }

                p[MOJI_UPPER] += 2;
                p[MOJI_LOWER]++;
        }

        printf("%c",p[MOJI_UPPER]); /* H */

        p[MOJI_LOWER]++;
        printf("%c",p[MOJI_LOWER]); /* e */

        p[MOJI_LOWER] += 7;
        printf("%c",p[MOJI_LOWER]); /* l */
        printf("%c",p[MOJI_LOWER]); /* l */

        p[MOJI_LOWER] += 3;
        printf("%c",p[MOJI_LOWER]); /* o */

        printf("%c",p[MOJI_SYMBOL]); /*   */

        p[MOJI_UPPER]--;

        for(p[COUNTER_2] = 4;p[COUNTER_2] > 0;p[COUNTER_2]--)
        {
                p[MOJI_UPPER] += 4;
        }

        printf("%c",p[MOJI_UPPER]); /* W */
        printf("%c",p[MOJI_LOWER]); /* o */

        p[MOJI_LOWER] += 3;
        printf("%c",p[MOJI_LOWER]); /* r */

        p[MOJI_LOWER] -= 6;
        printf("%c",p[MOJI_LOWER]); /* l */

        p[MOJI_LOWER] -= 8;
        printf("%c",p[MOJI_LOWER]); /* d */

        p[MOJI_SYMBOL]++;
        printf("%c",p[MOJI_SYMBOL]); /* ! */

        return 0;
}

うむ、ネコミミ言語の超少ないオペコードからすると最適解なのかも知れないけれど、高級言語的に見ると結構な辻褄合わせが入ってますな。

師匠とは「これでテキストファイルを暗号化したら面白くね?」とか言う話で終わった。