オヤジギャグ生成エンジンです。洒落にしたい言葉をローマ字で引数に渡すと、辞書から母音が同じ言葉を抽出して出力します。
辞書ファイルは、je-edict-kanji.txtですが、探せない人のために、ここに置いておきます。
n(ん)の後の母音や「やゆよ」の前には、nの後に'を付けて値渡しをしてください。
for ex. seenya shin'ya
コードをccでコンパイルして、辞書ファイルと同じディレクトリに置いて、実行してください。
$ cc seenya.c -o seenya
seenya.c
/*
* 'seenya' oyaji joking engine ver 0.84
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#define WL 256
#define RS 4
char *romaji[]={"a","i","u","e","o",
"ka","ki","ku","ke","ko",
"sa","si","su","se","so",
"ta","ti","tu","te","to",
"na","ni","nu","ne","no",
"ha","hi","hu","he","ho",
"ma","mi","mu","me","mo",
"ya","yi","yu","ye","yo",
"ra","ri","ru","re","ro",
"wa","wi","wu","we","wo",
"ga","gi","gu","ge","go",
"za","zi","zu","ze","zo",
"ja","ji","ju","je","jo",
"da","di","du","de","do",
"ba","bi","bu","be","bo",
"pa","pi","pu","pe","po",
"fa","fi","fu","fe","fo",
"ta","ti","tsu","te","to",
"n",
"dza","dzi","dzu","dze","dzo",
"kya","kyi","kyu","kye","kyo",
"sha","shi","shu","she","sho",
"cha","chi","chu","che","cho",
"nya","nyi","nyu","nye","nyo",
"hya","hyi","hyu","hye","hyo",
"mya","myi","myu","mye","myo",
"rya","ryi","ryu","rye","ryo",
"gya","gyi","gyu","gye","gyo",
"dya","dyi","dyu","dye","dyo",
"bya","byi","byu","bye","byo",
"pya","pyi","pyu","pye","pyo", };
char origword[WL][RS];
char vowels[WL][RS];
int beats;
char infile[]="/home/gar/dic/je-edict-kanji.txt";
#define SOT (30*5)
bool isvowel(char c) {
switch(c) {
case 'a': case 'i': case 'u':
case 'e': case 'o': return(true);
default:
return(false);
}
}
int decomposite_word(char *o,char word[WL][RS]) {
int i,j,l;
j=0;
while(1) {
if (*o=='\0') { // 行末か?
word[j][0]='\0';
return(j);
}
if (!isvowel(*o)&&(*o==*(o+1))) { // 小さい 'っ'の処理
word[j][0]='x';
word[j][1]='\0';
o++;
j++;
continue;
}
/*
if (*o=='n') { // "ん"の処理
if (*(o+1)=='\0') { // 次に行末
word[j][0]='u';
word[j][1]='\0';
o++;
j++;
return(j);
}
if (*(o+1)=='\'') { // 次に '
word[j][0]='u';
word[j][1]='\0';
o+=2;
o++;
j++;
continue;
}
if (!isvowel(*(o+1))&&(*(o+1)!='y')) { // 次に子音か
word[j][0]='u';
word[j][1]='\0';
o++;
j++;
continue;
}
}
*/
for(i=0;i<SOT;i++) { // ローマ字テーブルにマッチするか?
l=strlen(romaji[i]);
if (strncmp(romaji[i],o,l)==0) {
strcpy(&(word[j][0]),romaji[i]);
o+=l;
j++;
if (*o=='-') { // 長音 − の処理 (母音を重ねる)
l=strlen((char *)(&(word[j-1][0])));
word[j][0]=word[j-1][l-1];
word[j][1]='\0';
o++;
j++;
}
break;
}
}
if (i==SOT) { // 標準以外の記法の文字の場合
while(*o!='\0') {
if (!isvowel(*o++))
continue;
word[j][0]=*(o-1);
word[j][1]='\0';
j++;
break;
}
}
}
}
void get_vowels(char word[WL][RS]) {
int l;
for(int i=0;word[i][0]!='\0';i++) {
l=strlen((char *)(&(word[i][0])));
vowels[i][0]=word[i][l-1];
vowels[i][1]='\0';
}
}
int eval_word(char w[WL][RS]) {
int l;
for(int i=0;w[i][0]!='\0';i++) {
l=strlen((char *)(&(w[i][0])));
if (vowels[i][0]!=w[i][l-1])
return(0);
}
return(1);
}
void printword(char word[WL][RS]) {
int i;
for(i=0;word[i][0]!='\0';i++) {
printf("%s ",(char *)&(word[i][0]));
}
printf("\n");
}
void printjoke1(char *line) {
char d1[1024];
sscanf(line,"%s",d1); //最初の単語を飛ばす
line+=strlen(d1)+1;
if (!isdigit(*line)) { // ナンバリングされてない(ひとつ)か?
sscanf(line,"%s",d1);
printf("%s\n",d1);
return;
}
// ナンバリングされている
while(1) {
if (*line=='\0')
return;
if (isdigit(*line)&&(*(line+1)=='.')&&(*(line+2)==' ')) {
line+=3;
sscanf(line,"%s",d1);
printf("%s\n",d1);
line+=strlen(d1)+1;
while(1) {
if (isdigit(*line)&&(*(line+1)=='.')&&(*(line+2)==' '))
break;
if (*line=='\0')
break;
line++;
}
} else return;
}
}
void joke(char *o,FILE *fp) {
char lw[WL];
char lword[WL][RS];
char line[1024];
int f;
int b;
beats=decomposite_word(o,origword);
get_vowels(origword);
while(1) {
if(fgets(line,1024,fp)==NULL)
return;
sscanf(line,"%s",lw);
b=decomposite_word(lw,lword);
if (strcmp(lw,o)==0) // 同じ発音
continue;
if (b!=beats) // 違う拍数
continue;
f=eval_word(lword);
if (f==1)
printjoke1(line);
}
}
int main(int argc,char *argv[]) {
char orig[WL];
FILE *fp;
if (argc==1)
fscanf((FILE *)stdin,"%s",orig);
else if (argc==2)
strcpy(orig,argv[1]);
else {
fprintf(stderr,"Usage: %s word\n",argv[0]);
exit(1);
}
fp=fopen(infile,"r");
if (fp==NULL) {
fprintf(stderr,"File open error.\n");
exit(1);
}
joke(orig,fp);
fclose(fp);
exit(0);
}
実行例
①
$ ./seenya oyaji
母体
母胎
土塊
五戒
誤解
五彩
後妻
五体
魚介
魚雷
火先
穂先
除外
古代
誇大
個体
古体
固体
恐い
怖い
肥やし
巨大
去来
お菓子
同じ
書斎
所帯
書体
疎外
阻害
鼠害
疎開
租界
空似
トカイ
都会
都内
隣
トライ
渡来
弱い
齢
弱気