Notebook

Day05::300埋め+Janomeのインストール

Day5

  • AtCoder 300点問題を5問解いた
  • 形態素解析エンジンを入れた

令和時代

atcoder.jp

記念復習AC

ABC 070: C – Multiple Clocks

atcoder.jp

LCMを求めた.2数のLCMの計算量は$O(\log N)$らしいです.確かにそれはそうだった.

ABC 073: C – Write and Erase

atcoder.jp

おねえちゃんと数字を言い続けるゲームをしたかった.

mapで解いた.

ABC 075: C – Bridge

atcoder.jp

いい問題だった.UnionFindを使いました.多分これが一番早いと思います(ほんとうに?).

UnionFindのテンプレートは以下のような感じで

struct UF
{
public:
    ll tsize;
    ll mode;
    ll connect = 0;
    vll nodeSize;
    vll par;
    vll rank;
    UF(){};
    UF(const UF &uf) {}
    UF(ll _size, ll _mode = 0)
    {
        tsize = _size;
        mode = _mode;
        par.assign(tsize, -1);
        if (!mode)
            rank.resize(tsize, 0);
        nodeSize.resize(tsize, 1);
    }
    ll root(ll x)
    {
        return par[x] < 0 ? x : par[x] = root(par[x]);
    }
    bool isRoot(ll x)
    {
        return root(x) == x;
    }
    void unite(ll x, ll y)
    {
        x = root(x);
        y = root(y);
        if (x == y)
            return;
        if (mode)
        {
            par[x] += par[y];
            par[y] += x;
        }
        else
        {
            connect -= sumOfRange(nodeSize[x]) + sumOfRange(nodeSize[y]);
            connect += sumOfRange(nodeSize[x] + nodeSize[y]);
            if (rank[x] < rank[y])
            {
                nodeSize[y] += nodeSize[x];
                par[y] += par[x];
                par[x] = y;
            }
            else
            {
                nodeSize[x] += nodeSize[y];
                par[x] += par[y];
                par[y] = x;
                if (rank[x] == rank[y])
                    rank[x]++;
            }
        }
    }
    bool same(ll x, ll y)
    {
        return root(x) == root(y);
    }
    ll size(ll x)
    {
        return -par[root(x)];
    }
};

テンプレートとして持ってたりするのですが,前は連結要素数を保持していなくて痛い目見ました.猛省.

ABC 076: C – Dubious Document 2

atcoder.jp

やってることは単純なんだけどミスりそうな点が色々ありそうな問題.

ABC 079: C – Train Ticket

atcoder.jp

車のナンバーで合計10にするのをやってたので秒でACできました.嘘です(エイプリルフール).

形態素解析エンジン

MeCabあたりの辞書がとても有名ですが,怠惰なので同様にNeologd辞書が使えるJanomeをインストールしました.

Neologd対応するためにはこちらを参照.

github.com

ビルド済みのものを入れることでとても簡単にインストールできます.

試しに実行します

from janome.tokenizer import Tokenizer

tokenizer = Tokenizer(mmap=True)

tokenizer.tokenize("はい,ひょっこりはん", wakati=True)
# ['はい', ',', 'ひょっこりはん']

固有名詞をしっかり分類できています.やったね.これだけではつまらないのでワードクラウドを作ります.

$ pip install wordcloud twitter
import twitter
import re
consumer_key='hoge'
consumer_secret='huga'
access_token_key='piyo'
access_token_secret='hogehoge'

api = twitter.Twitter(auth=twitter.OAuth(
    access_token_key,
    access_token_secret,
    consumer_key,
    consumer_secret
))

app申請してもらったAPIトークンなどを入れます.

# TLのメッセージを形態素解析して名詞の頻度を表示
txts = " "
for tweet in tl:
    txt = tweet["text"]
    txt = re.sub(r"(@\w+:|RT|http.+)", "", txt)
    tokens = tokenizer.tokenize(txt)
    nouns = []
    for token in tokens:
        if token.part_of_speech.split(',')[0] == '名詞':
            nouns.append(token.surface)
    txts += " ".join(nouns)


from wordcloud import WordCloud
wc = WordCloud(
    background_color="white",
    font_path="/System/Library/Fonts/ヒラギノ角ゴシック W7.ttc",
    width=800,
    height=600
).generate(" ".join(txts))

wc.to_file("./wordcloud_sample.png")

これだけでワードクラウドが作れてしまいます.簡単すぎて驚きました.

時期が時期なので新元号一色です.