ポッキーの日を気合で増やしてみた
毎年11月11日はポッキーの日だ。正式名称は、「ポッキー&プリッツの日」。1が4つ並んだ状態がポッキーやプリッツを並べているように見えるかららしい。実は日本記念日協会の認定も受けている、れっきとした記念日なのである。
なんとなく世間的にもポッキーをたくさん買ったり食べたりしても許される雰囲気があるので、ポッキーが大好きな僕にとっては非常にうれしい記念日だ。きたるポッキーアンドプリッツの日にはたくさん食べようと思う。
でも、たまに思うことがある。
あんなにおいしいポッキーを奉る日が一年に一回だけでいいのか。もっとプリッツは崇められるべきではないのか。畢竟、ポッキーは甘い系お菓子の頂点に君臨し、プリッツもまたしょっぱい系お菓子の中で最も美味しいとされている。最上のお菓子と言えるポッキーやプリッツのために、僕は何をしてあげられるのだろうか。
そうだ、ポッキーの日を増やそう。
ポッキーの日が一年に何度もあれば、一年に何度もポッキーを大量買いできるし、一年に何度も大学の生協にポッキーが大量に入荷する。そういう世界こそが求められている。 2020年の366日をなるべくたくさんのポッキーの日で彩ろうじゃないか。
ちなみに、先述の通り正式には「ポッキー&プリッツの日」なのだが、長いので「ポッキーの日」と呼ばせてほしい。プリッツのことも好きだが、「&」の入力がめんどくさすぎる。なんだよshift+5同時押しって。&ボタン作らんかい。タカアンドトシとかテツandトモとかも入力が大変だから&の表記変えちゃってるんだぞ。たぶん違うけど。
2020年のポッキーの日・・・ 現在 1 日
1が並んでたらポッキーの日でいいはず
11月11日がポッキーの日だというのならば、当然1月1日や1月11日、11月1日だってポッキーの日になっていいはずだ。1月11日なんかはポッキーがとプリッツが3本しかなくて物足りないのでは?という疑問を抱いた方もいるかとは思うが、ポッキーとプリッツが3本あれば三角形を作ることができるので、窓に取り付ければビルの窓によくあるアレを再現することができてとても嬉しい。
消防隊はアレがある窓から建物に入るらしいので、ポッキーでアレを作る場合は消防隊が突入してきた場合に渡す手土産を準備しておこう。
というわけで、1月1日、1月11日、11月1日の3日が新たにポッキーの日と認定された。
2020年のポッキーの日・・・ 現在 4 日
でも、まだ足りないような気がする。現状、年に4回しかポッキーの日が訪れない。年4回と言ったらドラえもんの1時間スペシャルが放送される頻度と全く同じだ。特別な内容ではなく単純に二倍長いドラえもんよりポッキーのほうがたくさん見たいのは明白(ドラえもんファンの皆様ごめんなさい)。あまりにも頻度が少なすぎると言わざるを得ないだろう。
日付を限界突破する
今年の2月19日はポッキーの日だ。何故かというと…この日は2019年11月1日から数えて110日後、すなわち2019年11月111日にあたるから。
ポッキーとプリッツがあわせて5本になった。5本もあればホームベースの形を作れるので、野球をすることができる。非常に嬉しい。
ほかにも、
2020年4月20日は2020年1月111日になる。
このように、1月または11月の日付に無理やり変換したときに日付の部分に1が連続して出てくる日もポッキーの日に認定してあげよう。1月1111日や11月11111日みたいな感じだ。ちなみに111月や1111月についても考えようか迷ったが、13月以降のひと月の日数が30日か31日か決められないのでこっちを調べるのはやめておいた。
2020年のポッキーの日・・・ 現在 6 日
全部調べる
計算サイトがあるのでひとつひとつ調べていけば一応調べることは可能だが、1日、11日、111日、1111日、11111日……とすべての日付について調べるのはあまりにも無理がある。というわけで、自動化した。
import datetime def main(): Result = [] #XXXX年1月repunit日と、XXXX年11月Repunit日について一致を調べる RepunitDelta = [datetime.timedelta(days = repunit) for repunit in (0,10,110,1110,11110,111110)] for y in range(1,2021): JanOrig = datetime.date(year=y,month=1,day=1) NovOrig = datetime.date(year=y,month=11,day=1) for RD in RepunitDelta:#日付の差分 JanRes = JanOrig + RD NovRes = NovOrig + RD if JanRes.year==2020: result = (f"{JanRes}は{JanOrig.year}年{JanOrig.month}月{RD.days+1}日") Result.append((JanRes,result)) if NovRes.year==2020: result = (f"{NovRes}は{NovOrig.year}年{NovOrig.month}月{RD.days+1}日") Result.append((NovRes,result)) Result.sort(key = lambda x:x[0]) for r in Result: print(r[1]) if __name__ == "__main__": main()
このコード、要するに西暦1年~2020年の11月1,11,111,1111,1万1111,11万1111日をすべて調べ、その中で西暦2020年のものだけをピックアップして出力するようになっている。*1単純に日付の数字を足し算するだけではうるう年があったり、一月が30日か31日かの処理が面倒だったりするが、pythonには日付を直接足したり引いたりの計算ができるdatetimeというモジュールがあるので便利だ。
ただ、毎月厳密に30日だったりうるう年がなかったりしたらもっと便利なのになと思った。暦を考えた人はポッキーの日を求めることを想定していなかったのだろうか?
またコード内にレピュニット(Repunit)という言葉が出てきているが、1や11、1111など1がたくさん並んだ数字のことをこう呼ぶらしい。ポッキーのおかげで知らない知識が増えていく。
まあとにかく実行してみると、以下の結果が得られた。
2020-01-01は2020年1月1日 2020-01-11は2020年1月11日 2020-01-16は1715年11月111111日 2020-01-16は2017年1月1111日 2020-02-19は2019年11月111日 2020-03-17は1716年1月111111日 2020-04-02は1989年11月11111日 2020-04-20は2020年1月111日 2020-06-02は1990年1月11111日 2020-11-01は2020年11月1日 2020-11-11は2020年11月11日 2020-11-15は2017年11月1111日
全部で12日まで増えた!ちなみに今まで数えてきた11月111日なんかも全て入っている。これによると、2020年1月16日は1715年11月111111日らしい。
1715年といえば、1600年に江戸幕府ができてから大体100年くらいだ。調べてみると、和暦では正徳5年。翌年の1716年には8代将軍・徳川吉宗が将軍に着任しているらしい。徳川吉宗といえば”米将軍”の異名を取り、米の増産や安定供給に力を尽くしたらしい。しかし11万日の時を経て、時代は米からパンへ、そしてポッキーへと移った。時間の流れとは無情なものである。
さらに、11月111111日とかならポッキーとプリッツが合計8本あるので、漢字の「四」を作りだし、
厚切りジェイソンをキレさせることができる。 あと6本あれば「一」「二」「三」まで揃えて前フリまで完成させられるので、各自手持ちのポッキーで補ってほしい。
2020年のポッキーの日・・・ 現在 12 日
無限年に、挑む
じつは、先程書いたコードには重大な欠陥がある。書いたとおり日数の都合で11万1111日までしか計算していなかったが、当然レピュニットは111万1111、1111万1111…と続いていく。これは調べる範囲を西暦1~2020年までに限定していたせいで、要は西暦1年より前、すなわち紀元前の1月・11月すべてのポッキーの日を探索できたわけではないのだ。 とはいえ紀元前は無限に続く。どのようにすれば「本当に全ての」ポッキーの日を探索することができるのだろうか? 数日に渡る試行錯誤の末、以下のコードが完成した。
import datetime def RepDaysList400yrs(): """ 400年(146097日)周期の中で、レピュニット日だけ経過した日をすべて列挙する """ Shuki = 146097 #一周は146097日 RepDays = [False]*Shuki curpos = 1#1/1+curpos日 RepDays[1] = True while 1: nextpos = (curpos*10 + 1)%Shuki if RepDays[nextpos]:break else: RepDays[nextpos] = True curpos = nextpos return([n for n,d in enumerate(RepDays) if d])#「レピュニット日後」の日付をすべて列挙する if __name__ == "__main__": print(len(RepDaysList400yrs()))
少しややこしい話になるのでざっくりした解説に留めるが、実は、いわゆる西暦に使われる「グレゴリオ暦」は、うるう年などを加味しても400年=146097日周期で完全にループしている。さらに、上のコードを実行することで存在するすべてのレピュニット(1,11,111,……)を「146097で割った余り」が10422桁周期でループしていることが判明する。なので、考えなきゃいけない日付は1日、11日、111日……(1が10421桁並ぶ数)日、(1が10422桁並ぶ数)日までで全てだ。10422個となると多そうに見えるが、無限個調べるところが1万個まで減ったわけで、結構な進歩である。
さらに上のコードは1,11,111,1111…(1が10422桁並ぶ数) を146097で割った余りを全て計算し、出力してくれるようになっている。
というわけで1620年から2020年までの400年間について、1月と11月の1,11,111,1111…(1が10422桁並ぶ数)"を146097で割ったあまり"日を全て調べれば、少なくともこの400年間に理論上存在しうるすべてのポッキーの日を列挙することができる。
このへんは論理の飛躍がすごいですが、細かい解説は後日別の記事にまとめる予定です。
まあとにかく、2020年11月11日から紀元前数万、いや数億年の11111...111日まで、ポッキーの日を一つの漏れもなく調べることが可能になったのだ。
import datetime import ModularRepunit def main(): Repunits = ModularRepunit.RepDaysList400yrs() Result = set() #XXXX年1月repunit日と、XXXX年11月Repunit日について一致を調べる RepunitDelta = [datetime.timedelta(days = repunit) for repunit in [i-1 for i in Repunits]] for y in range(1600,2021): JanOrig = datetime.date(year=y,month=1,day=1) NovOrig = datetime.date(year=y,month=11,day=1) for RD in RepunitDelta: JanRes = JanOrig + RD NovRes = NovOrig + RD if JanRes.year==2020: Result.add(JanRes) if NovRes.year==2020: Result.add(NovRes) print(len(Result)) if __name__ == "__main__": main()
このコードを走らせれば、2020年の”本当の”ポッキーの日の日数が出力される。その実行結果は…
366
2020年のポッキーの日・・・ 366 日
なんと、366日すべてがポッキーの日だということがここに立証された。ここに、ポッキーによる天下統一がなされた。毎日が日曜日ならぬ、毎日がポッキーの日である。これでもう、11月11日の元祖・ポッキーの日を心待ちにする必要はない。ただ、毎日がポッキーの日であるという事実に目を向け、歓びをたたえてポッキーを食べればよいのである。街中のスーパーやコンビニは毎日ポッキーを大量に入荷すべきだし、大学の生協は毎日でっかいポッキーのバルーンをポッキー購入者に抽選でプレゼントすべきなのだ。
ちなみに記事公開日の3月16日は紀元前30421188966538973725979619324451867214552279954033583471559610700044795200753228638811504989453237年11月の111...1(1が101個続く)日なのでポッキーの日だ。
そして年の方はおおよそ紀元前10の98乗年なので、グーゴル(10の100乗)に近い。紀元前グーゴル年までさかのぼって初めて、3月16日はポッキーの日たりえるのだ。なお宇宙の誕生が約138億年前で11桁くらいなので、ビッグバンよりも圧倒的に昔ということになるがそういうのは気にしないでいただきたい。
毎日がポッキーの日であるエビデンス
2020年のすべての日について、ポッキーの日の具体的な日付も調べておいた。全部掲載するととんでもない分量になるので、とりあえず1月の最初の10日ぶんだけここに載せておく。
2020年1月1日は2020年1月の1日です 2020年1月2日は紀元前3042118896653897372597961932445186721455227995403358347155959051年1月の111...1(1が67個続く)日です 2020年1月3日は紀元前304211889665389737259796193244518672145522799540335834715596107000445933年1月の111...1(1が75個続く)日です 2020年1月4日は紀元前304211889665389737259796193244518672145522799540335834715596107000447952007532286388115049894552553744734282322323144516618715267558159609331091291706499410969728635389121230719620830300721058231479390024740031927037820382652925415608462年1月の111...1(1が240個続く)日です 2020年1月5日は紀元前3042118896653897372597961932445186721455227995403358347155961070004479520075322863881150498945525537447342823223231445166187152675581596093310912917064994109697286353891212307196208303007210582314793900247400319270378203826529254156104810122346414708年11月の111...1(1が253個続く)日です 2020年1月6日は紀元前304211889665389737259796193244518672145522799540335834715596107000447952007532286388115049894552553744734282322323144516618715267558159609331091291706499410969728635389121230719620830300721058231479390024740031927037820382652925415610481012234641672617811758245853401811429697012563190513456432674486433290515509862929725795年1月の111...1(1が327個続く)日です 2020年1月7日は紀元前3042118896653897372597961930427年11月の1111111111111111111111111111111111日です 2020年1月8日は紀元前28403年11月の11111111日です 2020年1月9日は紀元前304211889665389737257778年11月の111111111111111111111111111日です 2020年1月10日は紀元前30421188966538973725979619324451867214552279954033583471559610700044795200753228638811504989455255374473428232232314451661871526755815960933109129170649941096972863538912123071962083030072105823147939002471985年11月の111...1(1が212個続く)日です
桁数が最も小さいポッキーの日を選んだが、それでも無茶苦茶に長い。
一番下の1月10日は年だけで212桁ある。無量大数ですら68桁なので、ざっくり無量大数の3乗、要するに無量大数の無量大数倍の無量大数倍。デカすぎ。当然宇宙に存在するすべての粒子の数(10の80乗)より圧倒的に多い。
ちなみに一番長いのは9月25日で、日付の方は1が1471個続くし、年も当然のように1468桁ある。(9月25日のデータは、記事の最後に全日付のデータへのリンクと一緒に貼っておきます)
さっきの書き方をすると無量大数の無量大数倍の無量大数倍の…(「無量大数倍の」が20個)無量大数倍。
ここまで大きな数だともはや想像も及ばない。わかるのは唯一、「ポッキーの日だ」ということだけである。
でも、それで十分なのかもしれない。
だって、ポッキーが1471本もあったらめちゃめちゃ嬉しいから。
おまけ
※一番長いポッキーの日の詳細
2020年9月15日は紀元前3042118896653897372597961932445186721455227995403358347155961070004479520075322863881150498945525537447342823223231445166187152675581596093310912917064994109697286353891212307196208303007210582314793900247400319270378203826529254156104810122346416726178117582458534018114296970125631905134564326744864332905155098629297278140170191341673302288509992980310645971131812730202840882731640242061400606750613937619830964663507426192491594245223683199822340256435412393440279023145201095467014685068443872526091873511738396027601144749340810861581308613075179123763283602294670283746034788150642685643404343993678476932753201259741435104378901992816036225551821354609912896530691557283479088854969263191197933184421613342125056944663096740141443318099922958338942240049038956614060825646279146351016409949858275285902136556154092448472209863614204565764146043001871663651166310358490896078936901130375329024171916223087705048320256024726342392002877844476234586914477671988093146638496645683651576996409539172224237625991255429231568372002467158425186310769176947127213046431100189904272123619543484427773632890781086842607613054644821210869795029634040702029777780819896674431675150375739710222964499233005773181136124933738847782257297853100641658928276723303315225120601001009222943964930453359373871088690694842771887475064131668990084973986080784988360092571678025178097048155981604307031933882587900124194503955895360236311795892074747903409682912342104522642110680914年11月の111...1(1が1471個続く)日です
腕時計
自分に声をかけてくる人間をすべからく捕食者(Predator)だと思っているのでインタビューには応じないスタンスでいる。
万一インタビューを頼まれても「急いでるんで」と答えて、街並みをキョロキョロ見回して「今日渋谷に初めて来た人」感を醸しながらやや早歩きで立ち去ったりする。あと心の中で「急がなきゃ……」と一心に唱えて罪悪感を軽減する試みもやっている。
二限が終わり、暇なので駒場から渋谷まで歩いて帰ろうと思っていたら、駅の前でインタビューを依頼された。いつもなら毅然とした態度で「あ、すいません、いそ、急いでるんで、あ、すいません」ときっぱり断れるのだが、その日は「まさに今、暇を潰そうとしている」という現行犯であったためなんとなくインタビュアーにも罪悪感にも嘘がつけず、無駄な抵抗をせずにおとなしく捕食されることにした。アーメン。
捕食者は「大学のサークルで調査をしていまして、名前と学年、科類を教えて頂けますか」と聞いてきた。手にはiPhoneのメモアプリ(白紙)。長くなる予感がした。
学年を間違えて2年生と言ってしまうミスはあったもののいちおう質問に答えつつ、”武器”を探す。プレデターと戦うには武器が必要なのだ。ポケットに手を突っ込み、腕時計を取り出した。
笑顔で受け答えしながら、ゆっくり腕時計をつける。"腕時計を見る"というコミュニケーション・破壊行為をちらつかせる。「きょうもちゃんと人と話せた」という自尊心を巻き込んで破壊する自爆スイッチ、それを持ち出すという無言の宣戦布告。この戦い<Communication>、負けるつもりは、ない。
インタビュー、普通に面白い内容だったので腕時計は1度も見ずに最後まで受け答えしました。インタビュアーのメモも結構埋まってた。腕時計は、インタビューが終わってちょっと歩いたあとポッケにしまった。ずっとつけてると手首痛くなるから。そういうギリギリのところを生きています。
米津玄師を知らない
米津玄師を知っている。昔ハチだった人だ。
Lemonも、ゴーゴー幽霊船も、Flamingoも、パプリカも知っている。テレビやら店のBGMやらでそこかしこに流れてるやつ。
でも米津玄師を知らない。一曲たりとも、フルで聞いたことがない。サブスクのAmazon Music(Unlimited)に加入している僕にとっての「音楽」とはアマプラで聞ける曲を意味する。サブスクで聞けない米津玄師の曲は、僕にとって幻想上の存在なのだ。馬でも鹿でもなくて麒麟だ。
そりゃSoundCloudなんかを漁ればたぶんフルバージョンがアップロードされてるんだろうけど、絶対に聞きたくない。ネットに上がったフル音源を聞かないためにサブスクに入っているんだから。
サブスクの檻の中にいる限りは完全に安全。一歩でも外に出るとそこは地雷原だ。米津だ。米津が地雷原から笑っている。
Pythonで偶然短歌をやりたくてMecab使って頑張ったけど…
偶然短歌botというのがある。Wikipediaの記事の中から57577になっている部分を取り出し投稿するbotだ。 たとえばこういうの。
フクロウが鳴くと明日は晴れるので洗濯物を干せという意味 #tanka
— 偶然短歌bot (@g57577) December 31, 2014
ウィキペディア日本語版「フクロウ」より http://t.co/Dm1uHcQdzR
良い。 あるいはこういうの。
もしくはこういうの。彼らには襲われている人々を守れるだけの戦力はなく #tanka
— 偶然短歌bot (@g57577) July 8, 2019
ウィキペディア日本語版「ルワンダ虐殺における初期の出来事」より https://t.co/UKUKpcjZNe
研究で、ネコが砂糖に関心を持たないことは示されていた #tanka
— 偶然短歌bot (@g57577) June 21, 2019
ウィキペディア日本語版「ネコ」より https://t.co/L8b5HhUezs
良すぎる……。 こういうのもあった。
同様に、「普通免許」は普通でも免許でもなく、運転免許 #tanka
— 偶然短歌bot (@g57577) June 30, 2019
ウィキペディア日本語版「地学」より https://t.co/JkZWw4wOFn
最高……!Wikipediaのもつ無機質な文体が、短歌という形で取り出されることによって、荒涼とした侘び寂びのようなものを生み出していて心惹かれるかんじ、たまらん。
……同じことを、やりたい。任意のテキストから短歌を探すやつを、作りたい。
詳しくはわからないが、おそらく形態素解析を用いて単語の音数を抽出し、57577になる部分を抜き取っているのだろう。
形態素解析といえば、こないだの記事のはてブコメントで存在を知ったやつだ。日本語を品詞単位で分解するやつ。Pythonでも動くライブラリがあるらしい。
Pythonでできるなら、たぶん、いける。やってみよう。
必要なのはおそらく
のらへんだろう。
MeCabのセットアップ
文の分析には形態素解析エンジンの中で一番メジャーっぽいMeCabを使う。
MeCabの導入までにはこの記事をほぼまんま参考にした。
また、MeCab標準の辞書だと新語に対応できていないとの話だったので、追加辞書「mecab-ipadic-NEologd」を導入した。参考にしたのはこのサイト。これがかなりしんどかった。このためだけにgitとUbuntuを導入した。泣きそうになった。gitの使い方はこれから勉強します。 とりあえずテストでコードを動かしてみる。
import MeCab t = MeCab.Tagger("Ochasen -d neologd") print(t.parse(input(">>")))
こうなった。
なるほど確かに文章が分解できている。この分解の単位を「形態素」と呼ぶらしい。
あとは、各形態素ごとの文字数が取得できればいいわけだ。書くぞ!!!!!!!!
import MeCab import sys def ParseNode(text): p = MeCab.Tagger("-Ochasen -d neologd") p.parse("")#なんか消すとおかしくなるらしい node = p.parseToNode(text) Result = [] Sentence = [] while node: print(node.feature.split(",")) word = dict() word["text"] = node.surface detail = node.feature.split(",") word["hinshi"] = detail[0] if len(detail)>=9: word["Yomi"] = detail[8] word["Length"] = len(detail[8]) else: word["Yomi"] = "*" word["Length"] = 0 node = node.next if detail[0] == "BOS/EOS": if Sentence: Result.append(Sentence) elif word["Yomi"] == "。": Result.append(Sentence) Sentence = [] elif word["hinshi"] == "記号": pass else: Sentence.append(word) if word["Length"] == "*":word["Length"] = 0 print(type(node)) return Result if __name__ == "__main__": t = "".join(sys.stdin.readlines()) result = ParseNode(t) for sentence in result: print("\n".join([str(d) for d in sentence])) print("------------------------------")
書いた。parseToNodeメソッドの仕様がよくわからなかったので手探りで書いたが、どうも以下のようになっているらしい。
- 返り値はnodeというものが連結された状態
- node.surfaceには、単語(形態素)の文字列が入っている
- node.featureには、単語(形態素)の品詞/品詞の細分類(固有名詞など)/さらなる細分類(人名など)/謎の分類(おそらく細分類の備考)/活用形式/活用形/原型/読み仮名/読みの順にカンマ区切りでデータが入っている
- node.nextを代入することで、次の形態素に進める
このnodeデータからとりあえず、文字列/品詞/読み/読みの文字数 の4つを取得してリストにまとめた。上記のコードはそのリストを返す関数。
57577探し
形態素に分解したら、それらが5・7・5・7・7音でつながっている部分を探す。松尾芭蕉もこうやって俳句を作っていたのだと思うと、妙な親近感が湧く。 こういう系のアルゴリズムは色々思いつきそうだが、今回は単純な方法で解決しようと思う。すなわち、あらゆる名詞・動詞・連体詞・副詞から形態素の文字数を数えていき、ちょうどよく57577にマッチしたら短歌とみなす。
コードが汚くて恥ずかしい///
from split_node import ParseNode import MeCab import itertools import sys def FindTanka(text,neologd=False): """ テキストをぶちこむと短歌のリストを返してくれる風流な関数。 """ Nodes = ParseNode(text,neologd=neologd) TankaPoint = (5,12,17,24,31,32) Tankas = [] for sentence in Nodes: l = len(sentence) for n,StartWord in enumerate(sentence): if StartWord["Yomi"] =="*" or\ StartWord["Hinshi"] not in ("名詞","動詞","連体詞","副詞"):continue sound = 0 curpos = n tanka = "" tankalen = 0 while sound<=31 and curpos<l: w = sentence[curpos] #句の始まりが助詞や助動詞でないかどうか if sound in TankaPoint: if w["Hinshi"] not in ("名詞","動詞","連体詞","副詞"): break if w["Yomi"]!="*": tanka += w["Text"] sound += w["Length"] if sound ==TankaPoint[tankalen]: tankalen+=1 if tankalen == 5: Tankas.append(tanka) break curpos+=1 return(Tankas) if __name__ == "__main__": print(FindTanka(wikipedia(input("url:")),neologd = True))
コードは長いが、要するに単語をひとつずつ数えて短歌になっているかどうか調べている。Wikipediaからテキストを抽出する機能もつけた。 これで偶然短歌をぼくも作れるはずだ! とりあえずこのプログラムに青空文庫から「人間失格」をぶちこんだ結果がこれ。 「政党の有名人がこの町に演説に来て自分は下男」 「画家たちは人間という化け物に傷めつけられおびやかされた」あたりは短歌として成り立っていそうだが、その他はどうもしっくりこない。 俳句の終わり際が不自然なので、「体言止め」または「文節の切れ目」で終わっていれば良いはず。
というわけで魔改造した。
明らかに処理に無駄が多い気はするが…
from split_node import ParseNode from getAozora import aozora from getWikipedia import wikipedia import MeCab import itertools import sys import numpy as np import re def readlines(): return " ".join(sys.stdin.readlines()) JIRITSUGO = ( "動詞","形容詞","接続詞", "名詞","副詞","連体詞","感動詞","記号")#自立後のリスト FUZOKUGO = ("助詞","助動詞") def FindTanka(text,neologd=False): """ テキストをぶちこむと短歌のリストを返してくれる風流な関数。 """ text = re.sub(" "," ",re.sub(r"\r"," ",text)) Nodes = ParseNode(text,neologd=neologd) Tankalist = (5,7,5,7,7)#ここのタプルをいじると自由に検出が変更可能 TankaPoint = np.cumsum(Tankalist+(1,)) Tankas = [] for sentence in Nodes: l = len(sentence) for n,StartWord in enumerate(sentence): if StartWord["Yomi"] in("*","、") or StartWord["Hinshi"] in FUZOKUGO: continue sound = 0 curpos = n tanka = "" tankalen = 0 while sound<=TankaPoint[-1] and curpos<l: w = sentence[curpos] if w["Hinshi"]=="記号": tanka += w["Text"] curpos += 1 continue #句(57577)の始まりが助詞や助動詞でないかどうか if sound in TankaPoint and tankalen<=4: if w["Hinshi"] in FUZOKUGO: break if w["Yomi"]!="*": tanka += w["Text"] sound += w["Length"] if sound ==TankaPoint[tankalen]: tankalen+=1 if tankalen == len(TankaPoint)-1:#短歌が完成した場合 if (w["Hinshi"] in JIRITSUGO and "連用" not in w["Katsuyo"]) or (curpos<l-1 and sentence[curpos+1]["Hinshi"] in JIRITSUGO): Tankas.append(tanka) break if tankalen == len(TankaPoint):#31文字でうまく終わらなかった場合の安全策 Tankas.append(tanka) break curpos+=1 return(Tankas) if __name__ == "__main__": print(FindTanka(wikipedia(input()),neologd=True))
用言の場合は連用形で終わっているものと、直後にまだ助詞/助動詞が続くものを結果から外した。と同時に、字余りの「57578」を許可した。本当はすべての字余りのパターンを許容したかったのだが、コーディングが地獄すぎるので、違和感が少なそうな最後の字余りだけ対応した。 その結果がこちら。
だいぶ改善した気がする。とりあえず、短歌を抽出する部分はこのアルゴリズムで良さそうだ。
ちなみに、必死こいてインストールしたipadic-neologd(最新辞書)だが、使うと逆に精度が落ちる場合があるらしい。 たとえば本家の
これ。撮影を手掛けたことをきっかけに、氷室京介、布袋寅泰 #tanka
— 偶然短歌bot (@g57577) February 28, 2015
ウィキペディア日本語版「加藤正憲」より http://t.co/MjrgUrgJQr
80年代にBOØWYのプロモーションの写真撮影を手掛けたことをきっかけに、氷室京介、布袋寅泰、吉川晃司、Gackt、スピッツなど多くのアーティスト写真を撮影する
という文章からの抽出なのだが、neologd辞書を採用すると短歌として認識してくれない。原因を調べたところ、neologd辞書は「写真撮影」を1語とみなしているため短歌にしてくれなかった事が判明。検出精度がよすぎても短歌的にはマイナスになることがあるんだなあ。 ただ、追加辞書を使わずプリセットの辞書でやると本家のクローンになっちゃうので、neologdは採用することとした。neologdにしか検出できない単語もあるしね。
Wikipediaのデータ注入
本家よろしく、Wikipediaのデータをコイツに流し込む。Wikipediaはサーバーへの負荷を減らすためにクローリングを禁止しているが、そのかわり全テキストデータをまとめたファイルを公開している。そのサイズじつに10GB。もっと重いかと思ったが、画像がないとこんなもんらしい。
これを展開するプログラムがあったのでこれを入手、ちょっと手を加えてさっきのプログラムに放り込む。
オラ!!!!!!!!!!!!!!!
……
……
……
おわびとおわり
プログラムの効率が悪すぎた上にPythonなどという激遅言語で10GBのデータを処理しようとした結果、何時間立っても終わりませんでした…。とりあえず数時間で打ち切ったやつをここにおいておきます。
数時間動かしたけど、10メガのファイルサイズは余裕でオーバー。
ざっと目を通した限りだけれども、よさげな短歌はこんな感じか。
もう同じ趣旨のボットがあるからね、Twtiterには流しませんよ。
ここまでの4文全部短歌です、あえて言うなら必然短歌?
でも辞世の句が 偶然短歌だったら やだな (自由律俳句)
騎空士もそれ以外もいい加減Yuzu Browserを使ってくれ
みなさん、グラブル、してますか?
僕は3年くらいやってるのにもかかわらず先日やっと十天衆のソーンを取得したばっかり。これは「グラブルをしている」のうちには入らない気がする。1000倍に薄めたカルピスが、もはや水であるのと同じように。
そんなエセ騎空士だが、ソーンの獲得に向けてヘイローやキャンペーンクエストをガン回ししていた時に「Yuzu Browser」という最高のブラウザを見つけた。
これが設定項目が非常に多くて自分の好きなようにカスタマイズできて超絶便利で1、グラブル用・普段遣いともに非常に便利なのだが、あまりにもカスタマイズ性が高すぎて設定が相当難しい。そのためかネット上にユーザーがほっっっとんど見当たらないので、もう自分で記事を書くことにした。
今ではグラブル用ブラウザとしてはSmoozが有名だが、それより使い勝手は良いんじゃないかと思う。
※私はグラブルの運営ではないので、Yuzu BrowserやSmooz等のブラウザの利用がBANの原因になるかどうかはわかりません。指定URLへの遷移や再読込みなど、ブラウザとしてごく一般的な機能しか使っていないのでBANされる理由はないと勝手に思っていますが、もし何らかの被害を負っても当方責任を負えません!!というか僕だってBANが怖い!!!!
Yuzu Browser
Smoozでも同じだが、グラブルを遊ぶにあたって欲しい機能は
- 戻る/進む
- 再読み込み
- (マルチ参戦画面やサポ石選択画面など)指定ページへの移動
の3つだろうか。グラブルだけならこれ以外要らない気もする。 この辺の機能の追加も含めて、使いやすいように改造していこう。
ここからYuzu Browserをインストールして起動したら、以下の画面が出ているはず。
この状態から、快適に使うための初期設定が始まる。設定にあるまじき長さなので、心してついてきてほしい。
URLバーの非表示
グラブルやるなら画面はでっかいほうが良いので、上部にあるURLとかがあるバーを非表示にする。
右下のメニューから
[設定]→
[表示設定]→
[ツールバー設定]→
[URLバー]→
[表示設定]
の、一番上の「表示」のチェックを外す。
おさらい。
[*設定]→[表示設定]→[ツールバー設定]→[URLバー]→[表示設定]→[表示**]のチェックボックスをオフ、だ。
これで画面上部のURLバーが非表示になる。画面はこんな感じ。
広々していて使いやすい。
次は画面下の、戻るとか進むとかのボタンの部分を改造する。ここは完全に自由なので、個人的なオススメの設定を紹介するかたちで。
ちなみに、[ツールバー設定]画面から[カスタムバー]→[位置(縦画面)]をタップして「下部バー(常時表示)」にしておけば、スクロール時に画面下のバーが隠れず、操作が楽になるので是非お試しを。
ツールバーのカスタマイズ
ツールバーと言っておいてアレだが、下部のバーは「カスタムバー」と呼ばれている。ボタンやバーの名前を勘違いすると目的の設定項目へ永遠にたどり着けないスリルがある。バカでかい家電量販店を探索している時みたいな感情を設定画面で得られるブラウザは多分これだけだろう。
さきほど同様右下のメニューから\
[設定]→
[アクション設定]→
[ツールバーボタン設定]→
[カスタムバーボタン]
]
を開くと、こんな設定画面が出る。
おさらい。
[設定]→[アクション設定]→[ツールバーボタン設定]→[カスタムバーボタン]だ。
さっきも書いたけど、これはあくまで僕が使っている設定。可能性は本当に無限大なので、僕の設定をベースにして自分が一番ストレスなく操作できるボタン配置を模索していければそれに越したことはない。
なお今回はやらないが、右下の+ボタンを押せば新しいボタンを追加でき、ボタンの名前の部分を長押しすればボタンを削除できる。右上のそれっぽいマークを押すと並び替えも可能だ。
Smoozっぽい検索ボタン
Smoozの検索ボタンは、タップするだけで新しいタブが開き、入力画面に遷移できる。もちろんYuzuでも同じことができる。
「メインメニューを開く」ボタンの[上スワイプ]に、「検索バーの表示」を割り当てる(とんでもない数の選択項目があるが慌ててはいけない)。さらに歯車のマークを押して「新しいタブで開く」にチェックを入れて[OK]。
この状態で右下のメニューバーを上にフリックすると…
こんなふうに検索画面に推移する。検索結果は新しいタブで開かれるので、衝動的に検索しても「あれ!?今まで開いてたページどこいった!?」とならずに済む。便利。
指定URLを開くボタン
グラブルやるならこのボタンがないとね。
ブックマーク機能をあまり使わないので、ブックマークボタンをマルチの参戦ページへ遷移できるボタンに変える。
マルチバトル募集など、好きなURLをコピーしておいてから設定を始めよう。
[ブックマーク]ボタンから[タップ]を選び、現在設定されている「ブックマーク」からチェックを外したあと「URLを開く」にチェック。入力画面が出るので、好きなURLを入力して[OK]。
これで、ツールバーのボタンをタップするだけで好きなページを開けるようになった。この機能、実際に使ってみるとめっっちゃくちゃ便利なので一度体験してみてほしい。
Smoozにも似た機能はあるが、Yuzu Browserの強みは、動作が軽快なことは勿論、タップ・ロングタップに加えて4方向へのフリックの計6動作にそれぞれ別の操作を割り当てられること。
グラブルやるなら、ヘイロー・キャンペーン・共闘あたりのページが全部一発で開けるのでめちゃくちゃ便利になる。
初期設定でボタンが5つあるので、5×6=30通りもの動作を割り当てられるので、日常でよく使う操作やページはほぼ全部割り当てられるはずだ。
ちなみに僕は「進む」を上フリックで再読み込み、「タブ一覧」を上フリックで新規タブの追加ができるようにしてある。ご参考までに。
ユーザーが増えてほしい
最低限グラブルやブラウジングができるだけの操作方法は紹介したが、Yuzu Browserの深奥はこんなものじゃない。主流ブラウザの条件である広告ブロックやジェスチャーでの操作にももちろん対応しているし、ツールバーを上部に表示したり2段にしたりできる。あとなんか、画面左の方から半円状にバーってメニューを出したりできるらしい。バーって。 この辺はまだ僕も理解しきれていない。
とにかくできることが多いブラウザで、Wikiなんかもあるので自分なりの使い方を編み出してみてほしい。
そしてグラブルに限らず、色々なユーザーに最適な設定方法を見つけ出して共有してほしい。
このブラウザは「ちょっとマイナーなブラウザ」とかで済ませてはいけない代物だと思う。みんなで使い倒して、いい感じの設定を集合知で見つけ出そう。
-
本質:Yuzu Browserは設定項目が多い↩
栄光落札オークションで最高を落札で優勝しよう
謎解き公演「栄光落札オークション」が開催一週間前ということで、テストプレイに行ってきました。端的に感想を書こうと思います。
謎解きの非日常体験を「日常の延長の非日常」と、「現実から切り離された非日常」の2つに
分類するならば、これは120%後者でした。すべてが狂っていました。というか体験通り越して「
Nova1とUnlimited2の2つのレーベルを背負っている以上は難しいんだろうなと思っていましたが、それにしてもぶっ飛んだ難易度でした。それなのに1mmも理不尽じゃないからすごいですよね。
詳しい内容は当日体験してほしいので言いません(し、そのせいでタイトルが抽象的になりました)が、その場にいる全員の「目」が凄かったです。謎を解きまくるプレイヤーはもちろん、過剰な仕事量をひたすらさばくスタッフの方々、そしてそれを部屋のすみっこから見ていたディレクター3のどやさん…。部屋の中にいる全員が、殺気とも絶望とも異なる、ある種の興奮を含んだ狂気に包まれていました。
チケットを入手できた方は期待をマックスまで高めても絶対に裏切らないと思うし、取れなかった方はいつか来るかもしれない再演まで待つ価値があります。そういう公演でした。僕の中では今まで参加した謎解き公演の中で圧倒的満足度ナンバーワンでした。
ちなみにチームメンバーがガチすぎた結果、テストプレイ唯一のクリアチームになりました。いぇいぴーす。
ヒルナンデスが好きだ
最近嫌なニュースが多い。Twitterやネットニュースで嫌という程見ている情報なのに、テレビを付けるとそれをおさらいする羽目になる。誰が好きこのんで殺人犯のプロフィールを知りたがるというんだ。見たところで心に擦り傷がひとつ増えるだけだ。
その点ヒルナンデスはいい。12時から2時までずっと、決して中身のない話が流れ続けている。しかも決して飽きさせないように、小刻みにコーナーを変えながら。
かの番組は視聴者に「視聴」という概念だけを植え付けて跡を一切残さない。
どうかその虚無感を共有させてほしい。
たとえば料理コーナー。「料理の超キホン検定」という題のコーナーで、以下のようなクイズが出される。
お料理をしていても「そう言われるとどうだっけ?」と思う 基本中の基本知識を楽しくクイズで学ぶコーナー! Q1【片栗粉と小麦粉】 ①鶏の唐揚げを、カリッとした食感に揚げたいとき使うのは、 片栗粉である。○か×か? 答え:○ ②あんかけのあんを作るとき、片栗粉がないとき代わりに 水溶き片栗粉でも代用できる。○か×か? 答え:× ③春巻きの皮を巻くとき、ノリ代わりとして使う小麦粉がないとき代わりに 水溶き片栗粉でも代用できる。○か×か? 答え:○ Q2【天ぷら】 アク抜きに関する問題 ①サクサクの衣を作るには・・・Aぬるま湯 B氷水 C常温の水 答え:B.氷水 ②エビに切り込みを入れる場所は・・・A背中 B脇 Cお腹 答え:C.お腹 ③衣をつける前にやると剥がれにくくなるのは・・・ A塩をふる B軽くもむ C小麦粉をまぶす 答え:C.小麦粉をまぶす Q3【家庭の定番料理、何を作っているか答えなさい】 答え:茶碗蒸し Q4【ある食材の調理の様子、何をしているのか答えなさい】 答え:アボカド Q5【ロールキャベツ】 ①肉を包むキャベツは・・・A生のもの B加熱したもの 答え:B.加熱したもの ②タネを包むとき、キャベツの向きは・・・A芯のほうから B葉のほうから 答え:A.芯のほうから ③ロールキャベツの鍋の入れ方は・・・A隙間がないように B間隔を空けて並べる 答え:A.隙間がないように Q6 【煮干しのダシ】 ①3つの間違っている工程は? 行程① 煮干しは頭だけ取り除く 行程②水を沸騰させたところで煮干しを入れる 行程③煮立つとアクが浮いてくるが取り除かずにそのまま煮立ててよい 行程④2分ほど煮立てて、厚めのペーパータオルを敷いたザルなどでダシをこす 答え:①・②・③
以上の6問だ。難易度や、正解/不正解はこの際どうでもいい。クイズとしての価値など、月曜ゲストの藤田ニコルの前には些事だ。僕の心を掴んだのは、このコーナーに30分かけているという事実だ。これ以外の情報は、なにもない。ただ淡々と、キッチンでの収録の様子が放映されている。
たいていのワイドショーの中心企画であるグルメレポも、ヒルナンデスの手にかかればあっという間に虚無に早変わりだ。普通の番組ならVTRでタレントが食レポをして、その中の1つか2つをスタジオにお持ちしました……といった流れだが、ヒルナンデス1は一味違う。
食レポされたスイーツがスタジオに持ち込まれるところまでは同じだが、南原の一行は唐突にあみだくじを始める。なんと「一人だけスイーツの断面を見られない」というルールが存在し、しかもその見られない人物をその場で決めているのだ。
平日の真昼間。裏番組ではニュースに対する行き場のない議論がなされているそのときに、日本テレビは、貴重な貴重な地デジの電波を使ってスイーツを見られない人物を決めている。そこに報道はない。そこに怒りはない。そこに苦しみはない。
ただ、目隠しされる南原清隆とほんの少しのお得情報だけがある。
そういう、味がなくて食感だけがあるような、瞑想にも似た奇妙な浮遊感を伴う情報を目から取り入れているときに、僕の思考は止まり、雑念が消え、自分の心がゆっくり癒やされていくのを感じてしまう。
ヒールナンデスってか。