ニートが学ぶプログラミング

ニートの日記。プログラムのことやら、くだらないこと、思ったことをまとめていきます。頑張って毎日更新するぞぉ_(:3」∠)_ 更新が連続して途切れたら察してください。

AtCoderの過去問に挑戦 ABC076 AtCoder Beginner Contest 076

こんにちは鬱太郎です。先週の土曜日に開催されたAtCoderのコンテストを復習したため、記事にしたいと思います。

atcoderの画像を使わせていただきました。問題があれば削除します。

はじめに

私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。

公式URL

abc076.contest.atcoder.jp

結果

ABC076ランキングの結果を表示します

使用したもの等

名称 使用したもの
言語 JavaSE8
エディタ pleiades All in one var.4.7.0
プラグイン addons.mozilla.org

A - Rating Goal

B - Addition and Multiplication

問題

配点:200

問題文

square1001 は、電光掲示板に整数 1 が表示されているのを見ました。
彼は、電光掲示板に対して、以下の操作 A, 操作 B をすることができます。

  • 操作 A: 電光掲示板に表示する整数を「今の電光掲示板の整数を 2 倍にしたもの」に変える。
  • 操作 B: 電光掲示板に表示する整数を「今の電光掲示板の整数に K を足したもの」に変える。

square1001 は、操作 A, 操作 B 合計で N 回 行わなければなりません。そのとき、N 回の操作後の、電光掲示板に書かれている整数として考えられる最小の値を求めなさい。

制約

  • 1N,K10
  • 入力はすべて整数である

入力

入力は以下の形式で標準入力から与えられる。

N
K

出力

square1001 が N 回操作を行った後の、電光掲示板に書かれている整数として考えられる最小値を出力しなさい。


入力例 1

4
3

出力例 1

10

高橋君は、操作 A, A, B, B の順でやると、整数を最小化できます。この時、電光掲示板に書かれている整数は 124710 と変わり、最終的に 10 となります。


入力例 2

10
10

出力例 2

76

高橋君は、操作 A, A, A, A, B, B, B, B, B, B の順にやると、整数を最小化できます。この時、電光掲示板に書かれている整数は 124816263646566676 と変わり、最終的に 76 となります。

なお、今日のコンテストは、AtCoder Beginner Contest 076 です。

見出しをクリックすると開きます。↓↓

回答

問題文を読んでると難しい感じがしてきますね。ですが問題Bです。という事は難しい問題ではないという事ですね!

問題から

  • 操作Aは2^xの指数関数
  • 操作Bはkxの線形関数

という事が分かりますね。つまり、操作後の最小値を求める場合は操作Aを先にする必要があるという事です。1->2->4..kまで操作Aを、そこから操作Bをすればいいでしょう。

この考えにたどり着ければ、そう難しくないでしょう。

ポイント for文の条件式にはカウンタ以外の比較もできる

分かってる方には冗談もほどほどにしろと言われてしまいますね。

for文は

for(初期操作;boolean(trueならばループ);更新)

こうですね。(間違ってたらすいません)

通常のfor文では

for(int i=0;i<n;i++)

のようにカウンタの比較をよくします。しかし、2番目のループ条件には他のbooleanの条件も追加しても構いません。

今回の問題で言えばvalue<=kを条件に加えることもできます。13行目ですね。

for(; i<n && value <=k; i++)

break文を減らせて見やすくなります(ただそれだけです…)

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
69 ms 21204 KB

C - Dubious Document 2

問題

配点:300

問題文

E869120 は、宝物が入ってそうな箱を見つけました。
しかし、これには鍵がかかっており、鍵を開けるためには英小文字からなる文字列 S が必要です。
彼は文字列 S' を見つけ、これは文字列 S0 個以上 |S| 個以内の文字が ? に置き換わった文字列であることも分かりました。
ただし、文字列 A に対して、|A| を「文字列 A の長さ」とします。

そこで、E869120 はヒントとなる紙を見つけました。

  • 条件1:文字列 S の中に連続する部分文字列として英小文字から成る文字列 T が含まれている。
  • 条件2:S は、条件1を満たす文字列の中で辞書順最小の文字列である。

そのとき、鍵となる文字列 S を出力しなさい。
ただし、そのような文字列 S が存在しない場合は代わりに UNRESTORABLE と出力しなさい。

制約

  • 1|S'|,|T|50
  • S' は英小文字と ? から成る
  • T は英小文字から成る

入力

入力は以下の形式で標準入力から与えられる。

S'
T

出力

鍵となる文字列 S を出力しなさい。
ただし、そのような文字列 S が存在しない場合は、代わりに UNRESTORABLE と出力しなさい。


入力例 1

?tc????
coder

出力例 1

atcoder

条件1 を満たす文字列は atcoder, btcoder, ctcoder,..., ztcoder26 個がありますが、その中で最も辞書順で小さいものは atcoder なので、S=atcoder と特定できます。


入力例 2

??p??d??
abc

出力例 2

UNRESTORABLE

条件1を満たすような文字列 S が存在しないので、鍵となる文字列 S は存在しません。

見出しをクリックすると開きます。↓↓

回答

これも問題文を見ていると難しい感じがします。実際に私が今まで挑戦してきた過去問001,002,003よりもやっぱり難しくなっている気がしますね。

ですが、やはり問題Cです。さほど難しくないでしょう。

ポイント1 辞書順最小の文字列という記述から問題を読み解く

この辞書順最小の文字列という記述にどんな意味があるでしょうか?私はこの問題を解いているときになるほど!と思い、問題を作る人はすごいなぁと思いました。

この記述から

  • 残った?はすべてaに変えてね
  • 後方一致で調べてね

という事が分かりますね!たった一言でこの問題のアルゴリズムがほぼ決まってしまいます。素晴らしい!

あとはプログラムを実装するだけですね。

ポイント2 ?は正規表現の予約文字

予約文字という表現が正しいのかわかりませんが、正規表現では?は特別な意味を持つ記号です。String::replaceAllで置換してあげるときにエスケープしてあげる必要があります。しかも、エスケープ文字である\もまた、Javaではエスケープしなくてはいけません。

return new String(tmp).replaceAll("\\?", "a");

24行目のように\を2回入力してあげましょう。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
76 ms 25044 KB

D - AtCoder Express

問題

配点:400

問題文

2168年、AtCoder 社は成長し、ついに "AtCoder特急" という鉄道を建設することを決めた。

さて、社長の高橋君は、"AtCoder特急" の列車を以下のように運行することを計画した。

  • 列車の走行時間は、(t1+t2+t3++tN) 秒である。
  • 最初の t1 秒間は、列車は速度 v1 m/s 以内で走っていなければならない。また、次の t2 秒間は、列車は速度 v2 m/s 以内で走っていなければならない。 次の t3 秒間、またそれ以降についても同様である。
  • 最後の tN 秒間は、列車は速度 vN m/s 以内で走っていなければならない。

ただし、列車の性能上、加速度は ±1ms2 以内でなければならない。また、走行開始時と走行終了時には列車は止まっていなければならない。

列車が発車してから停車するまでに走れる最大の距離を求めなさい。

制約

  • 1N100
  • 1ti200
  • 1vi100
  • 入力はすべて整数である

入力

入力は以下の形式で標準入力から与えられる。

N
t1 t2 t3tN
v1 v2 v3vN

出力

列車が発車してから停車するまでに走ることのできる最大の距離を出力しなさい。ただし、絶対誤差が 10−3 以内であれば、正解となります。


入力例 1

1
100
30

出力例 1

2100.000000000000000

  • 最初の 30 秒は、加速度を 1ms2 にし、加速します。その間に列車は 450m 走ります。
  • 次の 40 秒は、速度 30ms を保ちます。その間に列車は 1200m 走ります。
  • 最後の 30 秒は、加速度を −1ms2 にし、減速します。その間に列車は 450m 走ります。

合計で、450 + 1200 + 450=2100m 走ることができます。


入力例 2

2
60 50
34 38

出力例 2

2632.000000000000000

  • 最初の 34 秒は、加速度を 1ms2 にし、加速します。その間に列車は 578m 走ります。
  • 次の 26 秒は、速度 34ms を保ちます。その間に列車は 884m 走ります。
  • 次の 4 秒は、加速度を 1ms2 にし、加速します。その間に列車は 144m 走ります。
  • 次の 8 秒は、速度 38ms を保ちます。その間は列車は 304m 走ります。
  • 最後の 38 秒は、加速度を −1ms2 にし、減速します。その間に列車は 722m 走ります。

合計で、578 + 884 + 144 + 304 + 722=2632m 走ることができます。


入力例 3

3
12 14 2
6 2 7

出力例 3

76.000000000000000

  • 最初の 6 秒は、加速度を 1ms2 にし、加速します。その間に列車は 18m 走ります。
  • 次の 2 秒は、速度 6ms を保ちます。その間に列車は 12m 走ります。
  • 次の 4 秒は、加速度を −1ms2 にし、減速します。その間に列車は 16m 走ります。
  • 次の 14 秒は、速度 2ms を保ちます。その間は列車は 28m 走ります。
  • 最後の 2 秒は、加速度を −1ms2 にし、減速します。その間に列車は 2m 走ります。

合計で、18 + 12 + 16 + 28 + 2=76m 走ることができます。


入力例 4

1
9
10

出力例 4

20.250000000000000000

  • 最初の 4.5 秒は、加速度を 1ms2 にし、加速します。その間に列車は 10.125m 走ります。
  • 最後の 4.5 秒は、加速度を −1ms2 にし、減速します。その間に列車は 10.125m 走ります。

合計で、10.125 + 10.125=20.25m 走ることができます。


入力例 5

10
64 55 27 35 76 119 7 18 49 100
29 19 31 39 27 48 41 87 55 70

出力例 5

20291.000000000000

見出しをクリックすると開きます。↓↓

回答

D問題ですね。私は本番中では解けませんでした。また、自力でやっても解けそうになかったので解説を見ました。

でもよくわかんなかったです(´;ω;`)

正順に調査して加速・逆順に調査して減速を挟み撃ちするように求めることと、0.5ずつでマッピングすることまではなんとなく理解できたのですが、それ以上はさっぱりでした。

どうしたもんかな?と考えているとふと思いつきました。そうだ、関数で表現すればいいじゃん!せっかくJava8で追加されたんだしいけるいける!

となりました。

大体のアルゴリズム

1.最大速度を関数として追加する

i区間ごとの最大速度viをグラフ関数として追加します。

{ \displaystyle{ f(x) = v_i   (0 \leq dx \leq t_i)}}

{ \displaystyle{ dx = x - \sum_{j=0}^{i-1}t_j}}

ですね。ソースコードでは25行目からの部分です。

グラフにすると単なる横棒の関数です。

2.正順に調査し、加速を関数として追加する

i区間で最大速度-現在速度が正ならば、加速させる必要があります。

{ \displaystyle{ f(x) = dx + speed (0 \leq dx \leq t_i)}}

{ \displaystyle{ dx = x - \sum_{j=0}^{i-1}t_j}}

こんな感じですね。

{ \displaystyle{ y = x + b}}

の様な傾き1の簡単な関数ですね。

3.逆順に調査し、加速(減速)を関数として追加する

i区間で最大速度-現在速度が正ならば、加速(減速)させる必要があります。

{ \displaystyle{ f(x) = dx + speed (0 \leq dx \leq t_i)}}

{ \displaystyle{ dx = \sum_{j=0}^{i}t_j - x}}

逆順調査の時だけ、dxの計算が違いますのでご注意を。傾き-1の簡単な関数です。

4.全ての関数をまとめる

全ての関数をまとめます。関数をグラフにするとこんな感じです。

関数をまとめるとこのようになります 関数をまとめるとこのようになります 関数をまとめるとこのようになります 関数をまとめるとこのようになります 関数をまとめるとこのようになります

橙色が最大速度の関数(1)、黄色が正順調査の加速関数(2)、灰色が逆順調査の加速(減速)関数(3)です。

5.全ての関数の中で最小の値をマッピングする

集めた関数の中で最小の値を配列に入れましょう。公式解説によると、0.5ごとにマッピングすればよいとのことです。

マッピングをグラフにするとこんな感じです。

まとめた関数の最小値を示すとこのようになります

まとめた関数の最小値を示すとこのようになります

まとめた関数の最小値を示すとこのようになります

まとめた関数の最小値を示すとこのようになります

まとめた関数の最小値を示すとこのようになります

青色の部分が最小の値ですね。

6.面積を台形の公式を使って求める

マッピングした配列から台形の公式を使って面積を求めましょう。回答に必要なのは移動した距離です。

距離(m) = 速度(m/s)×時間(s)

ですね。つまり、面積が距離になるわけです。

台形の公式は

面積 = (上底+下底)×高さ÷2

ですね!懐かしい!

{ \displaystyle{ T = \sum_{i=0}t_i}}

{ \displaystyle{ S = \sum_{x=1}^{2T}(f_{min}(\frac{x-1}{2}) + f_{min}(\frac{x}{2}))*0.5/2}}

{ \displaystyle{ S = \frac{1}{4}\sum_{x=1}^{2T}(f_{min}(\frac{x-1}{2}) + f_{min}(\frac{x}{2}))}}

ポイント DoubleFunctionとOptionalDoubleを使い関数を表現する

Java8から追加されたDoubleFunction1インターフェースとOptionalDouble2クラスをうまく使うことで、関数を表現しました。

DoubleFunctionインターフェースを使うことで動的に関数を生成できます。

また、OptionalDoubleクラスは値が含まれていない可能性を考慮してくれるもので、Optional.empty()のように値がない状態を明示して返すことができます。

また、ifPresentisPresentなどの条件メソッドも標準であるので便利です。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
390 ms 49440 KB

うーん…厳しいですね… ACできればOKという事で。なんだかぐちゃぐちゃなプログラムになってしまいましたが、独自性は抜群なのではないでしょうか?(開き直り) こんな面倒な方法取る人いないでしょう…(´;ω;`)

まとめ

難しかったですが、最終的にはすべてACできてよかったです。本当ならば本番中にすべてクリアしたいですが、まだまだ難しそうですね。

頑張っていきたいと思います。

今回はCの問題が考えててとても楽しかったです。Cのような問題にまた出会いたいですね。

終わりに

ここまで読んでくださってありがとうございます!

AtCoderの復習もようやく終わりました。と思いきや?

今月の予定がびっしりと!

今週末から三週連続でABCがあるようです。頑張っていきたいと思います。

スターやブックマーク、読者登録いつもありがとうございます!大変励みになっています!

またね('ω')ノ

AtCoderの過去問に挑戦 ABC003 AtCoder Beginner Contest 003

こんにちは、鬱太郎です。という事(?)でAtCoder Beginner Contestの3回目の過去問をやったのでそれを記事にしていきたいと思います。

atcoderの画像を使わせていただきました。問題があれば削除します。

はじめに

私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。

公式URL

abc003.contest.atcoder.jp

使用したもの等

名称 使用したもの
言語 JavaSE8
エディタ pleiades All in one var.4.7.0
プラグイン addons.mozilla.org

A - AtCoder社の給料

問題

問題文

AtCoder社の社員である青木さんの給料は以下のように決められます。
ある月に、青木さんがタスクをこなした数を x とします。
この月の給料は、1 から x までの整数が 1 面ずつに書かれた x 面ダイスを振って出た目 × 1 万円がもらえます。
ただし、このダイスは、どの面が出る確率も等しく 1x です。
青木くんは、暮らしていくのに十分な給料が得られるかどうかが心配で、平均いくら程度給料がもらえるか調べたいです。
毎月、青木くんはちょうど N 個のタスクをこなすこととし、毎月の給料の平均値を求めるプログラムを書いてください。

A問題では、提出した結果、全てのテストに対する判定がWAまたはREになってしまった場合のみ、質問タブにて可能な限りのトラブルシューティングを受け付けます。

提出結果のURLを添えて、お気軽にご質問ください。

また、ページ下部、「よくある質問」も、併せてご活用ください。


入力

入力は以下の形式で標準入力から与えられる。
N
  1. 1 行目には、整数で、青木くんが毎月こなすタスクの数 N (4≦N≦100) が与えられる。

出力

青木くんがもらえる毎月の給料(単位は円)の平均値を 1 行で出力せよ。
絶対誤差、または、相対誤差が 10−6 以下であれば許容される。
また、出力の末尾には改行を入れること。

入力例 1

  1. 6

出力例 1

  1. 35000
  • 1 万円から 6 万円がもらえる確率がそれぞれ 16 であるので、答えは
    • 10000×(16)+20000×(16)+30000×(16)+40000×(16)+50000×(16)+60000×(16)=35000
  • となります。

入力例 2

  1. 91

出力例 2

  1. 460000

見出しをクリックすると開きます。↓↓

回答

コードを書いたものは「Streamを使いたかった」という供述をしており…

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
214 ms 28116 KB

Streamを使っているので実行時間が長いですね( ;∀;)

B - AtCoderトランプ

問題

問題文

AtCoder社では 1 人で行うトランプを使ったゲームが流行っています。
AtCoder社特製トランプでは、各カードにアルファベット小文字 1 文字(az)、または@の文字が書かれています。

ゲームは以下の手順で行います。
  1. カードを同じ枚数ずつ 2 列に並べて文字列を 2 つ作ります。
  2. @のカードは、それぞれa,t,c,o,d,e,rのどれかのカードと置き換えます。
  3. 2 つの列が指し示す文字列が同じであれば勝ち、同じでなければ負けです。
手順 1. で並べられた 2 つの列が指し示す2つの文字列与えられるので、適切に@を置き換えて、このゲームで勝つことができるかどうかを判定するプログラムを書いてください。

入力

入力は以下の形式で標準入力から与えられる。
S
T
  1. 1 行目には、1 列目のトランプが表す文字列 S が与えられる。
  2. 2 行目には、2 列目のトランプが表す文字列 T が与えられる。
    1. ST ともにアルファベット小文字、および、@のみから構成されることが保証される。
    2. ST の文字数は等しく、1 文字以上、10文字以下であることが保証される。

出力

このゲームで勝つことが可能であればYou can winと、不可能であればYou will loseと(シングルクォーテーションを除いて)1 行で出力せよ。また、出力の末尾には改行を入れること。

入力例 1

ch@ku@ai
choku@@i

出力例 1

You can win
  • 例えば、@をうまく置き換えることによって、両方ともchokudaiと一致させることが可能です。

入力例 2

aoki
@ok@

出力例 2

You will lose
  • 4 文字目において、@i を置き換えることができないので、一致させることができません。

入力例 3

arc
abc

出力例 3

You will lose
  • 2 文字目において、一致させることができません。

見出しをクリックすると開きます。↓↓

回答

文字列の比較の問題ですね。問題を見ると、S・Tともにn番目の文字をそれぞれ比較していけばよさそうですね。

ポイント:文字の比較にはString::indexOf(int ch)を使う

回答のソースコードを見ると、indexOfを使っていますね。

比較文で文字をそれぞれ比較してもいいのですが、コード量が増えてしまうのでできるだけやめた方がいいでしょう。

if(s.charAt(i) == '@'){
  char c = t.charAt(i);
  if(!(c == 'a' || c == 't' || ...)){
   ...
  }
}

上記のように書いてしまうと、ケアレスミスのもととなるため、String::indexOfを使いましょう。

if (s.charAt(i) == '@') {
  if ("atcoder@".indexOf(t.charAt(i)) < 0){
  ...
  }
}

String::indexOf(int ch)は引数の文字がその文字列に含まれている場合はそのインデックスを返し、含まれていない場合は-1を返します1。-1が出る挙動をうまく駆使して、0以上なら含まれていて0未満なら含まれていないという条件文として使うことができます。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
83 ms 25044 KB

C - AtCoderプログラミング講座

問題

問題文

AtCoder社では、優秀な競技プログラマーの講座動画を N 個配信しています。
初心者競技プログラマーの高橋くんは、AtCoder社が配信している動画を見て修練しようとしています。
高橋くんの実力はレートという実数値で表され、レートが高いほど実力が高いことを表します。

高橋くんのレートが C の時に、レート R の競技プログラマーの講座動画を見ると、高橋くんのレートは (C+R)2 に変化します。
高橋くんは、講座動画を合計で K 個まで好きな順番で見ることができますが、同じ競技プログラマーの講座動画は一度までしか見ることができません。
講座動画を配信している N 人のレートが与えられた時、高橋くんが講座動画を見ることによって達成できるレートの最大値を求めるプログラムを書いてください。
ただし、高橋くんの初期レートは 0 です。

入力

入力は以下の形式で標準入力から与えられる。
N K
R1 R2 ... RN
  1. 1 行目には、講座動画の数を表す整数 N (1≦N≦100) と高橋くんが見ることのできる動画の数を表す整数 K (1≦KN) がスペース区切りで与えられる。
  2. 2 行目には、講座動画を配信している競技プログラマーのレートを表す整数 Ri (1≦Ri≦4,000) がスペース区切りで与えられる。

出力

高橋くんが達成できる最大レートを 1 行で出力せよ。
絶対誤差、または、相対誤差が 10−6 以下であれば許容される。
また、出力の末尾には改行を入れること。

入力例 1

  1. 2 2
  2. 1000 1500

出力例 1

  1. 1000.000000
  • 以下の方法が最適です。
    • まず、レート 1000 の競技プログラマーの講座動画を見ます。これにより、高橋くんはレート 0 から (0+1000)2=500 になります。
    • 次に、レート 1500 の競技プログラマーの講座動画を見ます。これにより、高橋くんはレート 500 から (500+1500)2=1000 になります。
  • しかし、例えば、以下の方法は最適ではありません。
    • まず、レート 1500 の競技プログラマーの講座動画を見ます。これにより、高橋くんはレート 0 から (0+1500)2=750 になります。
    • 次に、レート 1000 の競技プログラマーの講座動画を見ます。これにより、高橋くんはレート 750 から (750+1000)2=875 になります。

入力例 2

  1. 2 1
  2. 1000 1500

出力例 2

  1. 750
  • このケースでは高橋くんは 1 個の講座動画しか見ることができません。
  • レート 1500 の競技プログラマーの講座動画を見るのが最適です。

入力例 3

  1. 10 5
  2. 2604 2281 3204 2264 2200 2650 2229 2461 2439 2211

出力例 3

  1. 2820.031250000

見出しをクリックすると開きます。↓↓

回答

問題を要約すると、レートの降順でk個選んだあと、それを昇順で並べ替えて計算しなさいという事ですね。

Streamの出番だぁ!

  • 18行目Stream.of(br.readLine().split(" "))で入力されたRの文字列配列をStreamにします。
    String[] -> Stream<String>
  • 19行目.map(Integer::parseInt)でStringからIntegerに変換します。
    Stream<String> -> Stream<Integer>
  • 20行目.sorted((s1, s2) -> s2.intValue() - s1.intValue())でStreamを降順に並べ替えます。
  • 21行目.limit(k)でStreamの最初からk件に絞り込みます。
  • 22行目.sorted()で絞り込んだStreamを昇順で並べ替えます。
  • 23行目.collect(Collectors.toList());でStreamをリストにします。(終端処理)
    Stream<Integer> -> List<Integer>

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
183 ms 26964 KB

D - AtCoder社の冬

問題

問題文

AtCoder社の社員室は R×CRC 列)の区画に区切られており、各区画には、社員のデスク、サーバーラックのどちらかがあるか、何もない空きスペースのどれかです。
AtCoder社のある地域の冬は寒く、暖房代をできるだけ節約するため、社員室の必要なスペースのみを区切って使用することに決めました。
しかし、資材の問題で、区画に平行な長方形の領域で区切らなければいけません。
そこで、
  • デスク、または、サーバーラックのある最も上の行のすぐ上、
  • デスク、または、サーバーラックのある最も下の行のすぐ下、
  • デスク、または、サーバーラックのある最も左の列のすぐ左、
  • デスク、または、サーバーラックのある最も右の列のすぐ右
4 辺で囲まれた区画を壁で囲みました。
すると壁で囲まれた領域は X×YXY 列)の区画になりました。
また、AtCoder社の社員室には、D 個のデスクと、L 個のサーバーラックがあります。
もともと、社員室に、どのようにデスクとサーバーラックの配置されていたのか、考えうるパターン数を 1000000007=109+7 で割った余りを求めるプログラムを書いてください。

入力

入力は以下の形式で標準入力から与えられる。
R C
X Y
D L
  1. 1 行目には、AtCoder社の社員室の区画の行数、列数を表す整数 RC (1≦R,C≦30) がスペース区切りで与えられる。
  2. 2 行目には、社員室の壁に囲まれた部分の区画の行数、列数を表す整数 XY (1≦XR, 1≦YC) がスペース区切りで与えられる。
  3. 3 行目には、社員室にある社員のデスクの数、サーバーラックの数を表す整数 DL (D,L≧0, 1≦D+LX×Y) がスペース区切りで与えられる。

出力

社員室にどのようにデスクとサーバーラックの配置されていたのか、考えうるパターン数を 1000000007=109+7 で割った余りを 1 行で出力せよ。
また、出力の末尾には改行を入れること。

部分点

D+L=X×Y の場合のテストケースに全て正解した場合、101 点満点中の 100 点が与えられる。
満点解法は非常に難しいので、部分点を確実に取ることから考えましょう。

入力例 1

  1. 3 2
  2. 2 2
  3. 2 2

出力例 1

  1. 12
  • このケースは D+L=X×Y を満たすため、部分点のテストケースに含まれる可能性があります。
  • 以下の 12 通りの配置が考えられます。ここでDはデスク、Lはサーバーラック、.は何もないことを表します。
DD  DL  DL  LD  LD  LL  ..  ..  ..  ..  ..  ..
LL  DL  LD  DL  LD  DD  DD  DL  DL  LD  LD  LL
..  ..  ..  ..  ..  ..  LL  DL  LD  DL  LD  DD

入力例 2

  1. 4 5
  2. 3 1
  3. 3 0

出力例 2

  1. 10
  • このケースは D+L=X×Y を満たすため、部分点のテストケースに含まれる可能性があります。

入力例 3

  1. 23 18
  2. 15 13
  3. 100 95

出力例 3

  1. 364527243
  • このケースは D+L=X×Y を満たすため、部分点のテストケースに含まれる可能性があります。
  • 社員室の配置パターンは 145180660592914517790287604376765671109248284280228061640640 通りで、これを 109+7 で割った余りである 364527243 を出力してください。

入力例 4

  1. 30 30
  2. 24 22
  3. 145 132

出力例 4

  1. 976668549
  • このケースは D+L=X×Y を満たさないため、部分点のテストケースに含まれることはありません。
  • 無理に正解しようとせず、余裕のある人だけ挑戦してみてください。

見出しをクリックすると開きます。↓↓

回答

難しいですね… ABC3回目にして部分点というのを始めてみてとても驚きました。私は120分では解けませんでした。ただ、さらに1時間かけて部分点まで取れたので満足です。

部分点しかもらえない回答です。

部分点のみの場合の大体のアルゴリズムは30分くらいかかりましたが、何とかわかりました。

XYの範囲内におけるdとlの組み合わせ×(縦におけるXYの移動範囲)×(横におけるXYの移動範囲)

{ \huge{\displaystyle{Ans = {}_{d + l} \mathrm{C}_d ×{}_{1 + r - x} \mathrm{C}_1 × {}_{1 + c - y} \mathrm{C}_1}}}

ですが、nC1=nなので、

{ \huge{\displaystyle{Ans = {}_{d + l} \mathrm{C}_d (1 + r - x)(1 + c - y)}}}

ですね。実際はmod1000000007をとるわけですが。

入力例1の場合

f:id:neet-utsu-taro:20171027155948p:plain

R*Cの中にあるXYの箱の配置が2通りあり、XYの箱の中の組み合わせが4C2ですね。

{ \displaystyle{Ans = {}_{2 + 2} \mathrm{C}_2 (1 + 3 - 2)(1 + 2 - 2)}}

{ \displaystyle{Ans = {}_4 \mathrm{C}_2×2×1}}

{ \displaystyle{Ans = 2_4 \mathrm{C}_2}}

{ \displaystyle{Ans = 2×\frac{4\cdot3}{2\cdot1}}}

{ \displaystyle{Ans = 12}}

入力例2の場合

f:id:neet-utsu-taro:20171027161333p:plain

入力例2の場合はXYの組み合わせが1なので、縦×横の計算のみですね。

{ \displaystyle{Ans = {}_{3 + 0} \mathrm{C}_3 (1 + 4 - 3)(1 + 5 - 1)}}

{ \displaystyle{Ans = 1 × 2 × 5}}

{ \displaystyle{Ans = 10}}

入力例3の場合

ちょっと桁数がまずいですねぇ…さすがに図を描いている余裕はないので式だけ書きます。

{ \displaystyle{Ans = {}_{100 + 95} \mathrm{C}_{100} (1 + 23 - 15)(1 + 18 - 13)}}

{ \displaystyle{Ans = {}_{195} \mathrm{C}_{95} × 9 × 6}}

{ \displaystyle{Ans = {54}_{195} \mathrm{C}_{95}}}

お客様の中に195C95の答えが分かる方、いらっしゃいませんか?w

ちなみに、答えは

{ \displaystyle{Ans = 145180660592914517790287604376765671109248284280228061640640}}

ですって奥さん!桁数がやばいw

恐らく、プログラムを実装する際にmod1000000007を使うんでしょうね。計算途中でもmodを使わないと桁があふれて答えが合わなくなってしまいます。

{ \displaystyle{XY \mathrm{mod} P = (X \mathrm{mod} P)(Y \mathrm{mod} P)\mathrm{mod} P}}

のような暗号でも使われている(?)分配公式(?)を使うんでしょうけど、いかんせん詳しくなくて分数の場合などにどうすればいいのかわかりませんでした。

BigDecimalを使って実装する

注:邪道です

Javaユーザーの皆さん!朗報です!BigDecimalが使えますよ!

BigDecimalとは

BigDecimalNumberクラスのサブクラスでmathパッケージに属しているクラスです。

変更が不可能な、任意精度の符号付き10進数です。BigDecimalは、任意精度のスケールなしの整数値と、32ビット整数のスケールで構成されます。0または正の場合、スケールは小数点以下の桁数です。負の場合、スケールなしの数値に、スケールの正負を逆にした値を指数とする10の累乗を乗算します。つまり、BigDecimalで表される数値は(unscaledValue×10^-scale)です2

とんでもない大きな桁数を正確に計算できますという便利なクラスです。もちろん、intdoubleといったプリミティブよりははるかに計算速度が遅くなるらしいです。最終手段ですね。

BigDecimalはクラスであって、プリミティブではないです。計算する際はクラスに付属している各メソッドを使う必要があります。下にプリミティブとBigDecimalの計算記述の違いを書いておきます。

プリミティブの場合

int a = 3;
int b = 2;

int v = a+b;
int w = a-b;
int x = a*b; 
int y = a/b;
int z = a%b;

BigDecimalの場合

BigDecimal a = new BigDecimal(3);
BigDecimal b = new BigDecimal(2);

BigDecimal v = a.add(b); 
BigDecimal w = a.subtract(b);
BigDecimal x = a.multiply(b);
//BigDecimal y = a.divideAndRemainder(b)[0]; //a/bの整数値の商を求める
BigDecimal y = a.divide(b);//無限小数になる場合は注意!
BigDecimal z = a.divideAndRemainder(b)[1];

BigDecimalは割り算をする際に無限小数の場合にどうするかなど色々と面倒ですが、今回は組み合わせを求めるので少数の値は出ません。ですので普通にBigDecimal::divideを使っていけますね。

ソースコード

BigDecimalを使って先ほどの式を実装するだけですね。桁あふれの心配をしないとあっけなくて少し邪道な気がします。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

※ACじゃありません。部分点100点です。

実行時間が一番長かったテストケースのデータです。

実行時間 メモリ使用量
101 ms 20052 KB

意外と実行時間が短くて震える(((( ゚Д゚))))

BigDecimalの計算に1秒近く取られると思ったら全然でした。少なくとも今回の問題では問題なく使えるのではないでしょうか?

もっと桁数や計算数が増えてきたら厳しいかも?

改善

改善1 組み合わせをパスカルの三角形で求める

私の回答ではBigDecimalを使い半ば強引に求めました。解説を見ると、パスカルの三角形で組み合わせを求めることができるらしいです!

なんか授業でやったようなw

https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Pascal_triangle.svg/588px-Pascal_triangle.svg.png

パスカルの三角形 - Wikipedia

このままだとプログラムを組む際に混乱するので、下のように直しました。

f:id:neet-utsu-taro:20171027191418p:plain

この表から

int[][] map = new int[11][11];
map[0][0] = 1;
for(int i=1;i<=10;i++)
 for(int j=0;j<=i;j++)
  map[i][j] = map[i-1][j-1] + map[i-1][j];

という式が思い浮かぶのは簡単でしょう。

IndexOutOfBoundsExceptionを考慮すると

int[][] map = new int[11][11];
map[0][0] = 1;
for(int i=1;i<=10;i++)
 for(int j=0;j<=i;j++)
   map[i][j] = ((j-1<0)?0:map[i-1][j-1]) + map[i-1][j];

こうですね。こうしてできたパスカルの三角形の表から組み合わせの数を求めることができます。10C5の場合はmap[10][5]ですね。

必要なのは最後の1行であって途中の計算結果は保存しておく必要がないことに気づいた方もいるのではないでしょうか?

int tmp[] = new int[11];
int value[] = new int[11];
tpm[0] = 1;
for(int i=1;i<=10;i++){
 for(int j=0;j<=i;j++)
   value[j] = ((j-1<0)?0:tmp[j-1]) + tmp[j];
 
 for(int j=0;j<=i;j++)
  tmp[j] = value[j];
}

こうすることで、メモリの消費量を抑えることができます。10C5はvalue[5]が保持しています。

さらに、この問題ではmod1000000007を取らないと桁数があふれる可能性があります。ですのでmodを計算に加えてあげます。

int tmp[] = new int[11];
int value[] = new int[11];
tpm[0] = 1;
for(int i=1;i<=10;i++){
 for(int j=0;j<=i;j++){
   value[j] = ((j-1<0)?0:tmp[j-1]) + tmp[j];
   value[j] %= 1000000007;
 }
 
 for(int j=0;j<=i;j++)
  tmp[j] = value[j];
}

こうすればパスカルの三角形を使って組み合わせを求めることができます。

下はソースコードです。満点は取れません!部分点の100点のみです。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
77 ms 21204 KB

やっぱり実行時間が早くなりました!

組み合わせはパスカルの三角形で求められるという事はとても大事なことでしょう。もしかしたら、これからやる問題にもこれを使ったものがちょろっと出てくるかもしれません。

満点回答

解説を見たのですが、すぐにはわからなかったので保留です。(´;ω;`)

まとめ

初の部分点問題という事で少し動揺しました。ですが、これまでの問題の経験から比較的楽に問題を解けたのかなと思います。

着々と成長している感じがするぞ |д゚)

終わりに

ここまで読んでくださってありがとうございます!解説を見て完答させるつもりでしたが、ちょっと力不足でした。明日本番のコンテストが始まるまで少し粘ってみますね。それでもできなければいったん棚上げします。

スター、ブックマーク、読者登録ありがとうございます!とても励みになっています!

またね('ω')ノ

AtCoderの過去問に挑戦 ABC002 AtCoder Beginner Contest 002

atcoderの画像を使わせていただきました。問題があれば削除痛いします。

はじめに

私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。

公式URL

使用したもの等

名称 使用したもの
言語 JavaSE8
エディタ pleiades All in one var.4.7.0
プラグイン addons.mozilla.org

A - 正直者

B - 罠

問題

問題文

B問題のリジャッジ(再採点)が終了しました。21: 50
B問題のテストケースにミスがあったので、提出されたコードをリジャッジ(再採点)してます。21: 40

神の恵みで財産を築いた高橋くんですが、なんとそこには罠がありました。
神は、高橋くんの発した言葉から母音 aiueo を全て盗んでいったのです。
高橋くんが発した言葉を表す文字列 W が与えられるので、周囲の人が聞く言葉を表す文字列を出力するプログラムを書いてください。

入力

入力は以下の形式で標準入力から与えられる。
W
  1. 1 行目には、高橋くんの発した言葉を表す文字列 W が与えられる。
    • W の長さ |W|1≦|W|≦30 を満たす。
    • W は半角英小文字(a から zまで)のみで構成される。
    • W には母音以外の文字が少なくとも 1 文字含まれることが保証されている。

出力

W から母音を全て除いた文字列を 1 行で出力してください。
また、出力の末尾には改行を入れること。

入力例 1

  1. chokudai

出力例 1

  1. chkd
  • chokudai から aiueo を除くと chkd になります

入力例 2

  1. okanemochi

出力例 2

  1. knmch
  • okanemochi から aiueo を除くと knmch になります

入力例 3

  1. aoki

出力例 3

  1. k
  • aoki から aiueo を除くと k になります
  • このように、与えられる文字列 W には母音以外の文字が少なくとも 1 文字含まれます

入力例 4

  1. mazushii

出力例 4

  1. mzsh

見出しをクリックすると開きます。↓↓

回答

母音を取り除くという問題ですね。

正規表現を使って解く

正規表現を使って解くのが一番わかりやすく、かつコードもシンプルなものになると思います。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
  public static void main(String[] args) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      String w = br.readLine();
      System.out.println(w.replaceAll("[aiueo]", ""));
    }
  }
}

正規表現を使った置換のメソッドは多くの言語が実装しているのではないでしょうか?Javaの場合はStringクラスにreplaceAll(String regex, String replace)というメソッドがあります1。それを使い正規表現を元に空文字に置換してあげましょう。正規表現は他言語で共通している部分が多いですが、言語によっては方言のように詳しく指定できるものもあります2

問題ではa,i,u,e,oを取り除いてあげるという事ですね。

正規表現では[aiueo]と簡単に書けます。

後はその正規表現をメソッドを使い、空文字に置換しましょう。

System.out.println(w.replaceAll("[aiueo]", ""));

Streamを使って解く

Java8から追加されたStreamを使っても解くことができます。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
  public static void main(String[] args) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      String w = br.readLine();
      StringBuilder sb = new StringBuilder();
      w.chars()
       .filter(c -> !(c == 'a' || c == 'i' || c == 'u' || c == 'e' || c == 'o'))
       .forEach(c -> sb.append((char) c));
      System.out.println(sb.toString());
    }
  }
}

配列を使って解く

勿論配列を使って問題を解くこともできます。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
  public static void main(String[] args) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      String w = br.readLine();
      char[] ans = new char[w.length()];
      int index = 0;
      for (char c : w.toCharArray()) {
        if (!(c == 'a' || c == 'i' || c == 'u' || c == 'e' || c == 'o')) {
          ans[index++] = c;
        }
      }
      // new String(ans)だとchar=0が入り、改行文字がなくなる
      System.out.println(String.valueOf(ans, 0, index));
    }
  }
}

このときnull文字が入って、改行文字が消されないように気を付けましょう。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
79 ms 24916 KB

C - 直訴

問題

問題文

神に盗まれた母音を取り戻すため、高橋くんは神へ直訴しました。
「神様、どうかお願いです。僕の母音を返してください。」
神はこう言いました。
「そんなに母音がほしいのか。ならば私の仕事を手伝ってもらおう。」

現在、神は天界のいたるところで測量を行っており、高橋くんは神の測量を手伝わなければなりません。
今回は三角形の測量です。高橋くんには 2 次元平面上の 3 つの点 ABC が与えられます。
少しでも早く母音を取り戻すために、三角形 ABC の面積を出力するプログラムを書いてください。

入力

入力は以下の形式で標準入力から与えられる。
xa ya xb yb xc yc
  1. 1 行目には、3ABC の座標が半角空白区切りで与えられる。
    • A の座標が (xaya)、点 B の座標が (xbyb)、点 C の座標が (xcyc) であることを表す。
    • 各座標の値 xayaxbybxcyc−1,000 以上 1,000 以下の整数であることが保証されている。
    • 3ABC が同一直線上に配置されていることはない。

出力

三角形 ABC の面積を 1 行で出力してください。
また、出力の末尾には改行を入れること。
出力は絶対誤差が 10−2 以下であれば許容される。

ヒント

3(0,0), (a,b), (c,d) で構成される三角形の面積は、|adbc|2 となります。
(このヒントは、コンテスト開始 1 時間後に公開されたものです。)

入力例 1

  1. 1 0 3 0 2 5

出力例 1

  1. 5.0
    1:入力例 1 を図示したもの

入力例 2

  1. -1 -2 3 4 5 6

出力例 2

  1. 2.0

入力例 3

  1. 298 520 903 520 4 663

出力例 3

  1. 43257.5

見出しをクリックすると開きます。↓↓

回答

3点から三角形の面積を求める問題ですね。学校でやったなぁ…でももう忘れたよという私のような方も多いのでは。

ヘロンの公式で3角形の面積を求める

import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

  public static void main(String[] args) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      String[] array = br.readLine().split(" ");

      Point x = new Point(Integer.parseInt(array[0]), Integer.parseInt(array[1]));
      Point y = new Point(Integer.parseInt(array[2]), Integer.parseInt(array[3]));
      Point z = new Point(Integer.parseInt(array[4]), Integer.parseInt(array[5]));

      double a2 = x.distanceSq(y);
      double b2 = y.distanceSq(z);
      double c2 = z.distanceSq(x);

      double t = Math.sqrt((a2 + b2 + c2) * (a2 + b2 + c2) - 2 * (a2 * a2 + b2 * b2 + c2 * c2)) / 4.0;

      System.out.println(t);
    }
  }

}

3角形の面積を求める方法はいろいろあったのですが、学校で習った記憶がかすかにあるなと思ったこの公式で面積を求めてみましょう。

ヘロンの公式は辺a,b,cに対して

{ \huge {\displaystyle{
T = \sqrt{s(s-a)(s-b)(s-c)} \\
s = \frac{a+b+c}{2}
}}}

これで求めることができます。懐かしい!その公式のままプログラムを書いてもいいですが、辺abcを求めるときに平方根を取ります。平方根はできるだけ最後にした方が、計算の誤差が少なくなるため変形した公式を使いましょう。

{ \huge {\displaystyle
T = \frac{\sqrt{(a^2+b^2+c^2)^2-2(a^4+b^4+c^4)}}{4}
}}

この公式ですと、abcがそれぞれ2乗4乗されてますね。距離を求めるときに平方根を取らないでよいという事ですね。

JavaにはPoint2D::distanceSq(Point2D)というメソッドがあります3。距離を求める計算の途中で平方根を取らない値を返してくれます。

これを使うことで、計算の最後のみに平方根をとるようにできます。

1点を原点にずらす

問題のヒントにもあるように、原点、他2点から作られる三角形の面積は

{ \huge {\displaystyle
T = \frac{1}{2}|ad-bc|
}}

で求まるようです。そんな便利なのがあるんですね!なんだか行列の計算を思い出します。

という事で、与えられた3点のうちの最初の点を原点とみなすようにしてあげましょう。

package abc002.c;

import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

  public static void main(String[] args) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      String[] array = br.readLine().split(" ");

      Point a = new Point(Integer.parseInt(array[0]), Integer.parseInt(array[1]));
      Point b = new Point(Integer.parseInt(array[2]), Integer.parseInt(array[3]));
      Point c = new Point(Integer.parseInt(array[4]), Integer.parseInt(array[5]));

      // aを原点にするように全体をずらす

      Point b2 = new Point(b.x - a.x, b.y - a.y);
      Point c2 = new Point(c.x - a.x, c.y - a.y);

      double s = Math.abs(b2.getX() * c2.getY() - b2.getY() * c2.getX()) / 2.0;

      System.out.println(s);
    }
  }

}

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
85 ms 23252 KB

D - 派閥

問題

問題文

神からの財産と、母音を取り戻した高橋くんは、AtCoder国の腐敗した政治を正すため、国会議員となろうと決めました。
もともと人心掌握術とスピーチに定評があった高橋くんは、何の苦労をすることもなく当選しました。
しかし、議員になってからが本番です。国を正すためには、首相に任命される必要があります。

AtCoder国には高橋くんを除いて N 人の国会議員と、M 個の人間関係 (xy) が存在します。
人間関係 (xy) とは、議員 x と議員 y が知り合いであることを意味します。
高橋くんは N 人の議員から何人かを選んで派閥を作ろうと企んでいます。
派閥に含まれるすべての議員は互いに知り合いでなければなりません。
高橋くんが作成することができる最大の派閥に属する議員数を求めるプログラムを書いてください。

入力

入力は以下の形式で標準入力から与えられる。
N M
x1 y1
x2 y2
:
xM yM
  1. 1 行目には、高橋くん以外の国会議員の数 N (1≦N≦12) と、人間関係の数 M (0≦MN(N1)2) が半角空白区切りで与えられる。
  2. 2 行目から M+1 行目までの M 行で、人間関係が与えられる。
    • 各議員は 1 から N までの整数で番号がつけられている。
    • 2 行目を基準とした第 i (1≦iM) 行において、議員 xi と議員 yi は知り合いであることを意味する。
    • xiyi はともに整数で、 1≦xi<yiN を満たす。
    • ij のとき、(xiyi)(xjyj) であることが保証されている。

出力

高橋くんが作成することができる最大の派閥に属する議員数を 1 行で出力してください。
また、出力の末尾には改行を入れること。

入力例 1

  1. 5 3
  2. 1 2
  3. 2 3
  4. 1 3
  • 1 行目:5 人の議員と 3 つの人間関係が存在する。
  • 2 行目:議員 1 と議員 2 は知り合いである。
  • 3 行目:議員 2 と議員 3 は知り合いである。
  • 4 行目:議員 1 と議員 3 は知り合いである。

出力例 1

  1. 3
  • 議員 1、議員 2、議員 3 は互いに知り合いなので、この 3 人は派閥を構成することができる。

入力例 2

  1. 5 3
  2. 1 2
  3. 2 3
  4. 3 4

出力例 2

  1. 2
  • 議員数 2 の派閥として
    1. 議員 1 と議員 2 の派閥
    2. 議員 2 と議員 3 の派閥
    3. 議員 3 と議員 4 の派閥
    3 通りが考えられます。

入力例 3

  1. 7 9
  2. 1 2
  3. 1 3
  4. 2 3
  5. 4 5
  6. 4 6
  7. 4 7
  8. 5 6
  9. 5 7
  10. 6 7

出力例 3

  1. 4

入力例 4

  1. 12 0

出力例 4

  1. 1
  • たとえ 12人の議員がいても、誰も知りあいでなければ 1 人からなる派閥しか作成することはできません。

見出しをクリックすると開きます。↓↓

回答

難問でした…この問題では組み合わせを考慮する必要があります(たぶん)。 bit演算を使うなんて変態のすることだ!なんて思ってましたが、どうやら私は変態になったようです(´;ω;`)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
  public static void main(String[] args) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
      String[] array = br.readLine().split(" ");

      int n = Integer.parseInt(array[0]);

      HumanMap map = new HumanMap(n);

      String str = null;
      while ((str = br.readLine()) != null) {
        map.put(str);
      }
      System.out.println(map.max());
    }
  }

  private static class HumanMap {
    private final int[] map;
    private final int size;
    private final int[] key;

    public HumanMap(int n) {
      map = new int[n];
      key = new int[n];
      for (int i = 0; i < n; i++) {
        map[i] = 1 << i;
      }

      size = n;

    }

    public void put(String str) {
      String[] array = str.split(" ");
      this.put(Integer.parseInt(array[0]), Integer.parseInt(array[1]));
    }

    public void put(int a, int b) {
      map[a - 1] |= (1 << (b - 1));
      map[b - 1] |= (1 << (a - 1));
    }

    public int max() {
      int max = 1;

      for (int line : map) {
        if (Integer.bitCount(line) > max) {
          for (int filter = Integer.lowestOneBit(line); filter <= line; filter++) {
            int combination = filter & line;
            if (combination > 0 && Integer.bitCount(combination) > max) {
              int keySize = setKey(combination);
              int value = combination;
              for (int k = 0; k < keySize; k++) {
                value &= map[key[k]];
              }
              max = Math.max(Integer.bitCount(value), max);
            }
          }
        }
      }
      return max;
    }

    private int setKey(int line) {
      int index = 0;
      for (int i = 0; i < size; i++) {
        if ((line & (1 << i)) > 0) {
          key[index++] = i;
        }
      }
      return index;
    }
  }
}

ポイント1 人間関係を対戦表に入れる

問題では、人間関係(x,y)が入力されます。人間関係をPointクラスのように新しく作ってもいいのですが、クラス作成時やリスト追加などの処理でメモリ・時間のリソースを奪ってしまいます。

ABC001-Dから学んだように人間関係を入れて置ける配列を用意しましょう。具体的には総当たりの対戦表のようなものをイメージします。下の例は入力例1の場合です。

f:id:neet-utsu-taro:20171024212513p:plain

こんな風に配列を用意しておけば、どんなに人間関係が増えても配列の大きさに影響はありません。

人間関係(x,y)が与えられた場合、この配列の[x-1][y-1][y-1][x-1]に○(true)を入れてあげるだけです。

人間関係の配列を作る場合、2次元配列はできるだけやめましょう。私の経験不足なだけかもしれませんが、2次元配列でいろいろと処理をしようとすると、頭の中が混乱してしまいます。下のように配列の行をビットとして考え、intの数値配列として保存するのがいいと思います。

f:id:neet-utsu-taro:20171024213808p:plain

  • 対戦表の行を検索する場合はint[i]などのアクセス
  • 対戦表の列を検索する場合はビット演算によるアクセス

という風に分けることで混乱を最小限に抑えました。

またビット演算&を使うことで、人間関係で共通の部分を簡単に求めることができます。

例えば、人間関係1,2,3の共通の関係を求める場合は

7(111) & int[0] & int[1] & int[2] = 7(111)

と求めることができます。

ポイント2. 組み合わせをビット演算で表現する

問題の後半高橋くんが作成することができる最大の派閥に属する議員数を求めるプログラムを書いてください。の部分を求める際に、組み合わせを考えなくてはいけません。

{ \huge {\displaystyle{
\sum_{r=1}^{n}{}_n C _r
}}}

この数だけ、可能性を考慮する必要があります。私にはよくわからなかったので、ビット演算を使って組み合わせを表現しました。

先ほどの例があるとします。

f:id:neet-utsu-taro:20171024213808p:plain

人間1の人間関係で共通している人数を求めるとします。

  1. 人間1の人間関係を調べる。
    人間1の人間関係は7(111)です。

  2. 1から7までの数値と&演算して組み合わせを求める。
    人間関係7の最小ビットの数値1からその値7(111)までの値を使って組み合わせを求めます。
    7 & 1 = 1, 7(111) & 2(010) = 2(010), 7(111) & 3(011) = 3(011)のようにします。すると、1,2,4, 3,5,6, 7という7通りの関係を取得できます。これは

3C1 + 3C2 + 3C3 = 3 + 3 + 1 = 7

という考え方と同じですね。

人間3の人間関係の場合も同様に

最小のビット1からその値23(10111)までの値で&演算します。すると、
1,2,4,16, 3,5,17,6,18,20, 7,19,22,21, 23の15通りの関係を取得できます。

4C1 + 4C2 + 4C3 + 4C4 = 4 + 6 + 4 + 1 = 15

と同じです。

成績

プログラムの実行時間およびメモリ使用量をまとめました。

実行時間 メモリ使用量
86 ms 23252 KB

まとめ

問題Dは最大クリーク問題と呼ばれるものの小さいものらしいですね!問題の正答に1日以上かかったわけですが、解説を見ると改善するところはあまりなかったのが嬉しかったです

終わりに

ここまで読んでくださってありがとうございます!

長かったですが、ようやくABC002クリアできました! 今週末にABCのコンテストがあるらしいので、参加したいと思います。(前回あったの知らなかった(´;ω;`))

スター、ブックマーク、読者登録等ありがとうございます!いつも励みになってます!

ブログ巡りもまだなので明日したいと思います。

またね('ω')ノ

立憲民主党のフォロワーは英数字のみの名前率が高い! 各政党のフォロワー情報を比較してみた

こんにちは鬱太郎です。今日もまだ比較中なので、そのデータを貼り付けます。

終わらない(´;ω;`)

ソースコード

クリックしてソースコードを見る

nameプロパティを調べる

nameプロパティはTwitterの名前を意味します。よく変えたりする方も多いのではないでしょうか?

名前の文字列のサイズで比較してみる

名前のサイズで比較してみます。lengthでグループ分けですね!

f:id:neet-utsu-taro:20171018200659p:plain

うわ・・・線が多すぎてどれがどれだかわかりませんね(´;ω;`)

でも4文字の名前の人が1番多いというのが分かりますね!これは日本語の名前が4文字が多いからでしょうか?こういったデータを見ると和みますね!(私だけかな?)

しいて言えば20文字で急にぴょんとデータが跳ねているのが気になるところです。

そのままでは見にくいので、平均からの差のグラフを作りました。

f:id:neet-utsu-taro:20171018201003p:plain

ますますわからん・・・w( ;∀;)

政党名 最大 最小 合計 平均 中央値 標準偏差
公明 24 0 488076 6.62 5 4.28
自民 23 0 839717 6.75 5 4.30
立民 29 0 1215297 6.95 5 4.34
日本 22 0 258753 6.83 5 4.37
維新 22 1 93210 6.80 5 4.37
希望 20 1 73912 6.97 5 4.45
幸実 23 0 47743 7.07 5 4.52
共産 26 1 264532 7.20 6 4.54
民進 28 1 182694 7.21 6 4.61
自由 24 0 214001 7.58 6 4.75
社民 28 1 164356 7.59 6 4.78

各政党別の文字列の長さの詳細です。データを出してみたものの…わからん!(*'ω'*)

クリックして表1を見る

文字列の長さ 立民 民進 社民 幸実 共産
0 0.00% 0.00% 0.00% 0.01% 0.00%
1 1.38% 1.77% 1.44% 1.66% 1.39%
2 7.04% 6.70% 5.95% 6.83% 6.23%
3 11.14% 10.32% 9.34% 10.22% 9.88%
4 18.79% 17.92% 17.27% 18.82% 18.63%
5 11.96% 12.46% 11.99% 12.79% 13.19%
6 8.58% 8.33% 8.36% 8.80% 8.58%
7 6.63% 6.36% 6.47% 6.50% 6.27%
8 6.13% 5.70% 5.84% 5.27% 5.84%
9 4.46% 4.61% 4.45% 4.25% 4.46%
10 3.81% 3.80% 4.18% 4.01% 3.82%
11 3.33% 3.46% 3.50% 3.57% 3.54%
12 3.22% 3.16% 3.55% 3.08% 3.20%
13 2.94% 3.09% 3.26% 2.64% 2.81%
14 2.63% 2.43% 2.65% 2.19% 2.42%
15 2.11% 2.16% 2.53% 2.13% 2.31%
16 1.60% 1.75% 1.98% 1.66% 1.71%
17 1.24% 1.50% 1.78% 1.42% 1.51%
18 1.00% 1.43% 1.59% 1.38% 1.24%
19 0.88% 1.22% 1.59% 1.14% 1.23%
20 1.12% 1.81% 2.27% 1.61% 1.74%
21 0.00% 0.00% 0.00% 0.00% 0.00%
22 0.00% 0.00% 0.00% 0.00% 0.00%
23 0.00% 0.00% 0.00% 0.01% 0.00%
24 0.00% 0.00% 0.00% 0.00% 0.00%
25 0.00% 0.00% 0.00% 0.00% 0.00%
26 0.00% 0.00% 0.00% 0.00% 0.00%
27 0.00% 0.00% 0.00% 0.00% 0.00%
28 0.00% 0.00% 0.00% 0.00% 0.00%
29 0.00% 0.00% 0.00% 0.00% 0.00%

クリックして表2を見る

文字列の長さ 自民 希望 公明 日本 維新 自由
0 0.00% 0.00% 0.00% 0.02% 0.00% 0.01%
1 1.59% 1.59% 1.60% 1.58% 1.49% 1.37%
2 7.71% 7.18% 8.29% 8.02% 7.62% 5.74%
3 11.18% 11.15% 12.03% 11.43% 11.41% 9.59%
4 19.34% 19.17% 19.23% 18.16% 19.46% 17.44%
5 12.86% 11.27% 13.75% 12.46% 12.44% 11.87%
6 8.55% 8.62% 8.53% 8.69% 8.73% 8.53%
7 6.61% 6.86% 5.94% 6.60% 6.76% 6.32%
8 5.74% 6.10% 5.24% 5.82% 5.57% 5.84%
9 4.29% 4.32% 3.95% 4.63% 4.18% 4.44%
10 3.66% 3.92% 3.46% 3.97% 3.80% 4.07%
11 3.23% 3.07% 3.02% 3.19% 2.98% 3.65%
12 2.85% 2.85% 2.77% 2.77% 2.77% 3.57%
13 2.49% 2.90% 2.55% 2.47% 2.57% 3.13%
14 2.21% 2.40% 2.20% 2.08% 2.13% 2.88%
15 1.91% 1.86% 1.85% 1.88% 1.88% 2.52%
16 1.46% 1.58% 1.47% 1.48% 1.34% 2.08%
17 1.23% 1.46% 1.15% 1.29% 1.32% 1.78%
18 1.00% 1.04% 0.96% 1.10% 1.08% 1.59%
19 0.87% 1.10% 0.87% 1.02% 0.99% 1.46%
20 1.19% 1.54% 1.11% 1.35% 1.48% 2.11%
21 0.00% 0.00% 0.00% 0.00% 0.00% 0.01%
22 0.00% 0.00% 0.00% 0.00% 0.01% 0.00%
23 0.00% 0.00% 0.00% 0.00% 0.00% 0.00%
24 0.00% 0.00% 0.00% 0.00% 0.00% 0.01%
25 0.00% 0.00% 0.00% 0.00% 0.00% 0.00%
26 0.00% 0.00% 0.00% 0.00% 0.00% 0.00%
27 0.00% 0.00% 0.00% 0.00% 0.00% 0.00%
28 0.00% 0.00% 0.00% 0.00% 0.00% 0.00%
29 0.00% 0.00% 0.00% 0.00% 0.00% 0.00%

名前が英数字のみのフォロワー

Twitterの名前が英数字のみ(-_も含む)の人を検索します。

正規表現で

^[a-zA-Z0-9_\-]+$

と書けますね。

f:id:neet-utsu-taro:20171018202019p:plain

党名 スクリーン名 英数字のフォロワー フォロワー数 英数字率 偏差値
立民 CDP2017 47562 174880 0.272 71.79
希望 kibounotou 2677 10606 0.2524 62.74
自民 jimin_koho 29791 124317 0.2396 56.83
自由 seikatsu1pr 6508 28240 0.2305 52.58
維新 osaka_ishin 3043 13705 0.222 48.69
民進 MinshintoNews 5500 25333 0.2171 46.41
共産 jcp_cc 7892 36727 0.2149 45.38
日本 nipponkokoro 8121 37905 0.2142 45.08
公明 komei_koho 15603 73702 0.2117 43.91
社民 SDPJapan 4524 21644 0.209 42.66
幸実 hr_party_TW 1284 6753 0.1901 33.93
名称
平均 0.224872486895227
標準偏差 0.0216113775137216

立憲民主党が英数字の名前を付けているフォロワーが多いという結果になりました。これが、件の疑惑の元といえるんじゃないですかね。英数字のアカウントが多いという噂は聞いていましたが、本当に他党に比べて多いことが分かりました。

逆に幸福実現党は英数字の名前のフォロワーが少ないという結果が出ました。

クリックしてーターミナルの結果を見る

f:id:neet-utsu-taro:20171018200344p:plain

名前に@を付けてるフォロワー

Twitterの名前を名前@状況などのように使っている方をよく見かけますね。そんな人を検索します。

正規表現で

^[^@]+@[^@]+$

と書けますね。

f:id:neet-utsu-taro:20171018202826p:plain

党名 スクリーン名 名前に@を使用 フォロワー数 名前に@使用率 偏差値
幸実 hr_party_TW 245 6753 0.0363 66.86
日本 nipponkokoro 1322 37905 0.0349 64.08
維新 osaka_ishin 445 13705 0.0325 59.3
民進 MinshintoNews 781 25333 0.0308 56.05
社民 SDPJapan 605 21644 0.028 50.34
希望 kibounotou 285 10606 0.0269 48.19
共産 jcp_cc 954 36727 0.026 46.42
自民 jimin_koho 3131 124317 0.0252 44.85
自由 seikatsu1pr 639 28240 0.0226 39.77
公明 komei_koho 1661 73702 0.0225 39.59
立民 CDP2017 3496 174880 0.02 34.54
名称
平均 0.0277814617448422
標準偏差 0.00504040916871676

全体の約2.7%の方が名前に@を使っているようですね。名前に@を使っているからアクティブとかそんなわけではないと思いますが、こういったデータでも政党別に違いがあるんだなと思いました。

幸福実現党はフォロワー数が7000と少ないものの、先ほどの英数字の使用率が低いことも合わせると、フォロワーの(生身の人間としての)質が高いという推測ができますね。

逆にフォロワー数が多い政党ほど、質が低いという事がいえるのかも…(不安げ)

まあ、名前からすべてわかるわけないですけどね!

クリックしてーターミナルの結果を見る

f:id:neet-utsu-taro:20171018200016p:plain

終わりに

ここまで読んでくださってありがとうございます!

なんかもう…疲れた…

読者さんのブログを見るのもをくれてしまって申し訳ないです。でもfeedlyにたまっているので、ひと段落したら見て回りたいと思います。

読者登録が100人を越えました!ありがとうございます!

またね('ω')ノ

各政党フォロワーのユーザー情報を取得してみた

こんにちは鬱太郎です。昨日取得したフォロワーIDからユーザー情報を取得してみました。ですので、それについて記事にしたいと思います。

ソースコード

取得したデータ

プログラムを起動して約2時間ほどですべてのデータが集まりました!データを取得してから、データベースに追加するなどの処理をしていたためレートリミット回復の時間はあまりいりませんでした。

取得したデータの詳細を表にまとめておきますね。

政党 IDの数 取得したデータ数 ロス サイズ(MB)
自民党 124,328 124,317 11 131.5
公明党 73,705 73,702 3 72.2
民進党 25,335 25,333 2 30.1
日本維新の会 13,707 13705 2 15.8
立憲民主党 174,896 174,880 16 195.2
希望の党 10,607 10,606 1 12.2
日本のこころ 37,913 37,905 8 47.0
共産党 36,732 36,727 5 43.1
社民党 21,649 21,644 5 27.1
自由党 28,244 28,240 4 35.5
幸福実現党 6,754 6,753 1 7.6

どうしても、取得時にロスが発生してしまうようです。フォロワーのIDを取得してからユーザーの情報を取得する間に、アカウント削除などの理由から取れないユーザー情報があったようです。

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171015151917p:plain f:id:neet-utsu-taro:20171015154433p:plain

ユーザー情報のJSONの例

取得したデータの一例を表示したいと思います。こんな感じのデータをTwitterAPIで取得できます。

{
        "_id" : ObjectId("59e1823fae898d323863ba37"),
        "miniProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg",
        "screenName" : "neet_utsu_taro",
        "contributorsEnabled" : false,
        "profileUseBackgroundImage" : false,
        "profileBackgroundTiled" : false,
        "createdAt" : "Tue Aug 29 09:12:49 GMT+09:00 2017",
        "profileBackgroundImageURL" : "http://abs.twimg.com/images/themes/theme1/bg.png",
        "biggerProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg",
        "protected" : false,
        "miniProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg",
        "profileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg",
        "id" : NumberLong("902323111994916864"),
        "profileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg",
        "profileSidebarBorderColor" : "000000",
        "utcOffset" : -25200,
        "URLEntity" : {
                "displayURL" : "neetaro.com",
                "start" : 0,
                "end" : 23,
                "text" : "https://t.co/8tj7yW4gCF",
                "expandedURL" : "http://www.neetaro.com",
                "URL" : "https://t.co/8tj7yW4gCF"
        },
        "timeZone" : "Pacific Time (US & Canada)",
        "defaultProfile" : false,
        "profileLinkColor" : "91D2FA",
        "originalProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg",
        "profileSidebarFillColor" : "000000",
        "rateLimitStatus" : {
                "limit" : 75,
                "secondsUntilReset" : 900,
                "remaining" : 74,
                "resetTimeInSeconds" : 1507952068
        },
        "profileBannerMobileURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile",
        "name" : "ニート鬱太郎",
        "followersCount" : 69,
        "followRequestSent" : false,
        "status" : {
                "inReplyToUserId" : -1,
                "userMentionEntities" : [ ],
                "source" : "<a href=\"http://twitter.softama.com/\" rel=\"nofollow\">ツイタマ for Android</a>",
                "retweeted" : false,
                "currentUserRetweetId" : -1,
                "createdAt" : "Sat Oct 14 10:10:19 GMT+09:00 2017",
                "hashtagEntities" : [ ],
                "mediaEntities" : [ ],
                "inReplyToStatusId" : -1,
                "extendedMediaEntities" : [ ],
                "id" : NumberLong("919007427701248000"),
                "text" : "おはようございます❗☀🙋❗",
                "lang" : "ja",
                "favorited" : false,
                "retweet" : false,
                "accessLevel" : 0,
                "URLEntities" : [ ],
                "truncated" : false,
                "quotedStatusId" : -1,
                "possiblySensitive" : false,
                "contributors" : [ ],
                "retweetedByMe" : false,
                "symbolEntities" : [ ],
                "retweetCount" : 0,
                "favoriteCount" : 1
        },
        "showAllInlineMedia" : false,
        "geoEnabled" : false,
        "profileBannerMobileRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile_retina",
        "translator" : false,
        "description" : "ニートです。どうでもいいこと言います。趣味アニメ等 だけども最近全く見てない。。。 フォローされたら、bot等でない限りフォロー返します。  犬は柴犬、猫は黒猫が好き。  柴犬っていいよね…The犬って感じで _(:3」∠)_ ブログやってます。下のリンクからどうぞ。",
        "profileTextColor" : "000000",
        "descriptionURLEntities" : [ ],
        "URL" : "https://t.co/8tj7yW4gCF",
        "biggerProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg",
        "profileBannerIPadURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad",
        "lang" : "ja",
        "defaultProfileImage" : false,
        "statusesCount" : 192,
        "accessLevel" : 2,
        "profileBackgroundImageUrlHttps" : "https://abs.twimg.com/images/themes/theme1/bg.png",
        "profileBackgroundColor" : "000000",
        "verified" : false,
        "favouritesCount" : 218,
        "friendsCount" : 105,
        "listedCount" : 0,
        "profileBannerURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web",
        "location" : "自宅",
        "profileBannerRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web_retina",
        "originalProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg",
        "profileBannerIPadRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad_retina"
}

ユーザー情報JSONのプロパティ説明

私が理解した範囲、およびできる範囲で調べたものを説明していきます。プロパティは大きく分けて

  • 数値
  • bool値
  • 文字列
  • URL
  • オブジェクト
  • 最近したツイート

に分けられます。これについて説明していきます。

数値

数値は主にIDやツイート数などの計測情報からなります。

プロパティ名 意味
_id MongoDBのデフォルトID
id ユーザーID
utcOffset UTCのオフセット値(秒)
followersCount フォロワー数
statusesCount ツイート数
accessLevel 不明。おそらくTwitterAPIのアクセスレベルか?
favouritesCount いいね数
friendsCount フォロー数
listedCount リスト数

ツイート数からフォロワー数等の有名な数値がデータとして格納されています。

私のデータはなぜかタイムゾーンがUSカナダになっているのでutcOffsetがおかしい値になっていましたね。

bool値

bool値というのはtruefalseで表現する状態を表す値です。trueならyesfalseならnoと考えるとわかりやすいと思います。

プロパティ名 意味
contributorsEnabled ユーザーがcontributor modeを有効にしたかどうか(認証アカウントで複数人数での管理をOKにしているか等)
profileUseBackgroundImage ホーム画面で背景に画像を使っているかどうか
profileBackgroundTiled ホーム画面で背景にタイル画像を使っているかどうか
protected 鍵垢かどうか
defaultProfile ユーザーがユーザープロファイルのテーマまたは背景を変更していないことを示します。
followRequestSent 不明
showAllInlineMedia 不明
geoEnabled 位置情報を有効にしているかどうか
translator ユーザーがTwitterの翻訳者コミュニティに参加しているかどうか
defaultProfileImage trueの場合、ユーザが自分のプロフィール画像をアップロードしておらず、代わりにデフォルト画像が使用されていることを示します。
verified 認証済みかどうか

Twitterの設定情報などが多いですね。鍵垢か認証済みがよく知られている項目でしょうか?

文字列

プロパティ名 意味
screenName スクリーン名(@に続く名前)
createdAt アカウント作成日時
timeZone タイムゾーン名
name 名前
description 自己紹介
lang 表示言語
location 場所(ユーザーが自由に決めれるやつ)

自己紹介なども取得できるようですね。

色はユーザーが設定したテーマの色等ですね。

プロパティ名 意味
profileSidebarBorderColor 不明
profileLinkColor 不明
profileSidebarFillColor 不明
profileTextColor 不明
profileBackgroundColor 不明

プロパティ名からどこの色のことを言っているのかはなんとなくわかるのですが、あまり意味のない数値だと思います。詳しく調べませんでした。

URL

URLは主に画像のリンク等の文字列がデータとして入っています。

オブジェクト

プロパティ名 意味
URLEntity プロフィールのURLの内容
rateLimitStatus TwitterAPIのレートリミットオブジェクト
status 最近したツイート

オブジェクトの中でも最近したツイート以外はたいした意味を持ちません。

最近したツイート

ユーザー情報の中には最近したツイートの内容が付属されています。statusというオブジェクトにツイート情報が入っています。

プロパティ名 意味
inReplyToUserId リプライ先のユーザーID(リプライでなければ-1)
userMentionEntities メンションの配列
source ツイートしたアプリの詳細
retweeted 不明
currentUserRetweetId 不明
createdAt ツイート日時
hashtagEntities ハッシュタグの配列
mediaEntities 画像等のメディアの配列
inReplyToStatusId リプライ先のツイートID(リプライでなければ-1)
extendedMediaEntities 画像等のメディアの配列(extended)
id ツイートID
text ツイート本文
lang ツイート言語
favorited 不明
retweet 不明
accessLevel 不明
URLEntities URLの配列
truncated 翻訳されたかどうか
quotedStatusId 引用ツイート元のツイートID(引用していなければ-1)
possiblySensitive 不明
contributors 不明
retweetedByMe 不明
symbolEntities 不明
retweetCount リツイート数
favoriteCount いいね数

まだ詳細な意味は分かりません。ごめんなさい!

実際に政党別で比べてみる

詳しい比較は後日やります。今日はフォロワーがどれくらい鍵垢かどうかを調べたいと思います。

MongoDBはdb[collection_name]db.collection_nameのように扱えます。db.getCollectionNames().forEachですべてのコレクションについてfunction()の中身を実行させます。

> db.getCollectionNames().forEach(function(e){ 
if(e.match(/_ids$/))return;
var all = db[e].count();
var count= db[e].find({protected:true}).count();
print(e +","+count+","+all+","+count/all); 
} 
)
党名 スクリーン名 鍵垢数 フォロワー数 鍵垢率 偏差値
立憲民主党 CDP2017 25722 174880 0.1470 60.68
民進党 MinshintoNews 3257 25333 0.1285 51.24
社民党 SDPJapan 2288 21644 0.1057 39.59
幸福実現党 hr_party_TW 874 6753 0.1294 51.68
共産党 jcp_cc 4076 36727 0.1109 42.27
自民党 jimin_koho 16327 124317 0.1313 52.65
希望の党 kibounotou 1795 10606 0.1692 71.98
公明党 komei_koho 9510 73702 0.1290 51.48
日本のこころ nipponkokoro 4047 37905 0.1067 40.12
維新の会 osaka_ishin 1807 13705 0.1318 52.91
自由党 seikatsu1pr 2750 28240 0.0973 35.34
名称
平均 0.1261
標準偏差 0.019611

フォロワーの鍵垢率が高い政党は希望の党,立憲民主党,維新の会ですね。偏差値で見ると希望の党立憲民主党が明らかに高いことが分かります。逆に鍵垢の率が極端に低い自由党社民党も目立ちます。

比較する値がbool値だとこんな感じに楽にできますね!

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171016163838p:plain

終わりに

ここまで読んでくださってありがとうございます!

Twitterのユーザー情報の取得が完了しました!これからデータを分析していきたいと思います。もしかしたら、2・3日かかるかもしれません。いいデータ取れるといいんですが…

またね('ω')ノ

Javaを使いデータをMongoDBに入れてみた

こんにちは、鬱太郎です。今日はプログラムからMongoDBにデータを入れる実験をしたので、それについてまとめたいと思います。

f:id:neet-utsu-taro:20171011211254j:plain

jarドライバーをダウンロードする

下記リンクからドライバーをダウンロードします。

MongoDB Java Driver

Index of /repositories/releases/org/mongodb/mongo-java-driver/3.5.0

mongo-java-driver-x.x.x.jarというものをダウンロードし、環境変数等に登録しておきましょう。私はEclipseの外部JARに追加しました。

f:id:neet-utsu-taro:20171014111651p:plain

f:id:neet-utsu-taro:20171014112055p:plainf:id:neet-utsu-taro:20171014112230p:plain

プログラムからMongoDBを検索する

  • MongoClient client = new MongoClient("localhost", 27017);で指定したアドレス、ポート番号で接続を確立させる。
  • MongoDatabase db = client.getDatabase("testdb");で指定したデータベースを使う。クライアントでのuse testdbと同じ
  • MongoCollection<Document> coll = db.getCollection("test");でコレクションを指定する。この変数に検索・追加等を行う場合はこのコレクションに行う。

特に特筆する点はありませんでした。Documentクラスは他のパッケージでも使われるため、org.bson.Documentという風に明示しておく必要があるくらいでしょうか?

実行結果は下のようになります。これまでにいろいろとデータを追加したりしていたので、汚れていますね…

8
Document{{_id=59ddaf21ee43c8a85e9dfea5, name=testinsert, message=hello mongodb, testv=org.bson.BsonUndefined@0, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb11dee43c8a85e9dfea6, name=ニート鬱太郎, message=テストメッセージ, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb5e19a2f587d7ea7001a, name=ニート鬱太郎, message=ストメッセージ, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb5ff9a2f587d7ea7001b, test=false, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb8879a2f587d7ea7001c, testname=tet, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddb9c09a2f587d7ea7001d, id=9.0232311199491686E17, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}
Document{{_id=59ddbd099a2f587d7ea7001e, created_at=Tue Aug 29 09:12:49 GMT+09:00 2017}}
Document{{_id=59ddbf9b9a2f587d7ea7001f, createdAt=Tue Oct 10 19:00:05 GMT+09:00 2017, created_at=Thu Jan 01 09:00:00 GMT+09:00 1970}}

プログラムからMongoDBにデータを追加する

  • db.createCollection("test1");でデータベースにコレクションを追加します。
  • coll.insertOne(Document.parse(json));でコレクションにデータを追加します。

データを追加する際はorg.bson.Documentクラスとして追加する必要があります。文字列のJSONがある場合は下の例のようにDocument.parse(json)Document型に変換できます。

結果

> db.test1.find()
{ "_id" : ObjectId("59e17ea9ae898d27ec86e0e9"), "name" : "test", "value" : 111,"created_at" : "Sat Oct 14 12:04:09 GMT+09:00 2017" }

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014121148p:plain

Twitterの自分のユーザー情報を追加してみる

目的であるフォロワーの情報の取得の前に、自分のユーザー情報を追加してみます。

  • JSONObject json = new JSONObject(user);でユーザー情報のJSONを作ります。
  • coll.insertOne(Document.parse(json.toString()));でJSONの文字列からDocumentクラスに変換しMongoDBに追加します。

結果です

> db.test.find({},{_id:0,status:0})
{ "miniProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg", "screenName" : "neet_utsu_taro", "contributorsEnabled" : false, "profileUseBackgroundImage" : false, "profileBackgroundTiled" : false, "createdAt" : "Tue Aug 29 09:12:49 GMT+09:00 2017", "profileBackgroundImageURL" : "http://abs.twimg.com/images/themes/theme1/bg.png", "biggerProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg", "protected" : false, "miniProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_mini.jpg", "profileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg", "id" : NumberLong("902323111994916864"), "profileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg", "profileSidebarBorderColor" : "000000", "utcOffset" : -25200, "URLEntity" : { "displayURL" : "neetaro.com", "start" : 0, "end" : 23, "text" : "https://t.co/8tj7yW4gCF", "expandedURL" : "http://www.neetaro.com", "URL" : "https://t.co/8tj7yW4gCF" }, "timeZone" : "Pacific Time(US & Canada)", "defaultProfile" : false, "profileLinkColor" : "91D2FA", "originalProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg", "profileSidebarFillColor" : "000000", "rateLimitStatus" : { "limit" : 75, "secondsUntilReset" : 900, "remaining" : 74, "resetTimeInSeconds" :1507952068 }, "profileBannerMobileURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile", "name" : "ニート鬱太郎", "followersCount": 69, "followRequestSent" : false, "showAllInlineMedia" : false, "geoEnabled" :false, "profileBannerMobileRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/mobile_retina", "translator" : false, "description" : "ニートです。どうでもいいこと言います。趣味アニメ等 だけども最近全く見てない。。。フォローされたら、bot等でない限りフォロー返します。  犬は柴犬、猫は黒猫が好き。  柴犬っていいよね…The犬って感じで _(:3」∠)_ ブログやってます。下のリンクからどうぞ。", "profileTextColor" : "000000", "descriptionURLEntities" : [ ], "URL" : "https://t.co/8tj7yW4gCF", "biggerProfileImageURLHttps" : "https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_bigger.jpg", "profileBannerIPadURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad", "lang" : "ja", "defaultProfileImage" : false, "statusesCount" : 192, "accessLevel" : 2, "profileBackgroundImageUrlHttps" : "https://abs.twimg.com/images/themes/theme1/bg.png", "profileBackgroundColor" : "000000", "verified" : false, "favouritesCount" : 218, "friendsCount" : 105, "listedCount" : 0, "profileBannerURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web", "location" : "自宅", "profileBannerRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/web_retina", "originalProfileImageURL" : "http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E.jpg", "profileBannerIPadRetinaURL" : "https://pbs.twimg.com/profile_banners/902323111994916864/1505292216/ipad_retina" }
>

希望の党のフォロワーIDを取得する

試しに、希望の党のフォロワーIDを取得してみます。TwitterAPIのfollowers/idsは15分に15回しかアクセスできません。1回に5000人のIDを取得します。

f:id:neet-utsu-taro:20171014124126p:plain

プログラムを作る前には10600人のフォロワーがいます。3回のアクセスで取得できますね。

プログラムの標準出力

5000件取得
5000件取得
607件取得

MongoDBの結果

> db.ki
db.kibounotou_ids  db.killOP(         db.killOp(
> db.kibounotou_ids.find({},{_id:0});
{ "user_id" : NumberLong(152582955) }
{ "user_id" : NumberLong("805586963134722048") }
{ "user_id" : NumberLong(207533598) }
{ "user_id" : NumberLong("2366735000") }
{ "user_id" : NumberLong("2578806756") }
{ "user_id" : NumberLong(101443148) }
{ "user_id" : NumberLong("2381150839") }
{ "user_id" : NumberLong("858242448211836928") }
{ "user_id" : NumberLong("853963341563285505") }
{ "user_id" : NumberLong(1895710039) }
{ "user_id" : NumberLong("919038152525758464") }
{ "user_id" : NumberLong("701664499904819200") }
{ "user_id" : NumberLong("4026560532") }
{ "user_id" : NumberLong("2401011818") }
{ "user_id" : NumberLong("3969213373") }
{ "user_id" : NumberLong(124797590) }
{ "user_id" : NumberLong(189854952) }
{ "user_id" : NumberLong(108766513) }
{ "user_id" : NumberLong("2328720366") }
{ "user_id" : NumberLong(1458820586) }
Type "it" for more
> db.kibounotou_ids.find({},{_id:0}).count();
10607
>

クリックしてターミナルの結果を見る

f:id:neet-utsu-taro:20171014131304p:plain

10607人のユーザーIDを取得できました。私がプログラムを作っている間に7人のフォロワーが増えたようですね。

このユーザーIDはhttps://twitter.com/intent/user?user_id=の=の先につけることでそのユーザーの情報をブラウザでも見ることができます。ちなみに私の情報はhttps://twitter.com/intent/user?user_id=902323111994916864です。

まとめ

プログラムからMongoDBにデータを追加することができました!次はすべての政党のフォロワーのIDをデータベースに追加したいと思います。

その次に、追加したユーザーIDを元にユーザー情報を取得したいと思います。

またね('ω')ノ

Twitter4jを使い立憲民主党のフォロワーについて調べてみた

こんにちは、鬱太郎です。最近立憲民主党のフォロワーが急激に増加したせいで、フォロワーを買ったんじゃないかという疑惑が上がりましたよね?

今日はTwitter APIとtwitter4jを使ってツイートやユーザー情報を取得してみようと思います。

Twitterでアプリ登録をする

apps.twitter.com

上記公式サイトからアプリ登録をしましょう。

f:id:neet-utsu-taro:20171009210633p:plain

Create New Appから新しいアプリを登録しましょう。

f:id:neet-utsu-taro:20171009210930p:plain

必要事項を記入して、登録を済ませましょう。

携帯認証を済ませていないアカウントではアプリ登録はできません!携帯認証を済ませましょう。

f:id:neet-utsu-taro:20171009210741p:plain

アプリ登録が完了すると、ConsumerKeyというのが発行されます。それと合わせて、keys and Access TokensタブからAccess Tokenを取得しておきましょう。

twitter4jをダウンロードする

Twitter4J - A Java library for the Twitter API

上記公式サイトからダウンロードしましょう。ダウンロードしたlibファイルを使います。

f:id:neet-utsu-taro:20171009211352p:plain

これらのlibファイルを環境変数等に登録しておきましょう。私はeclipseに追加しました。

f:id:neet-utsu-taro:20171009211515p:plain:h400

自分の情報を取得してみる

twitter4jの詳しい使い方は公式サイトやjavadocにあります。

自分の情報を取得するには、Twitter::verifyCredentials()を使います。

JSON=UserJSONImpl{id=902323111994916864, name='ニート鬱太郎', screenName='neet_utsu_taro', location='自宅', description='ニートです。どうでもいいこと言います。趣味アニメ等 だけども最近全く見てない。。。 フォローされたら、bot等でない限りフォロー返します。  犬は柴犬、猫は黒猫が好き。  柴犬っていいよね…The犬って感じで _(:3」∠)_ ブログやってます。下のリンクからどうぞ。', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/902325250867716096/IXHm182E_normal.jpg', isDefaultProfileImage=false, url='https://t.co/8tj7yW4gCF', isProtected=false, followersCount=66, status=StatusJSONImpl{createdAt=Mon Oct 09 11:26:20 GMT+09:00 2017, id=917214617541124096, text='プログラム組んでるとTwitterするの忘れてしまう…😱😱', source='<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=1, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=0, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=-1, quotedStatus=null}, profileBackgroundColor='000000', profileTextColor='000000', profileLinkColor='91D2FA', profileSidebarFillColor='000000', profileSidebarBorderColor='000000', profileUseBackgroundImage=false, isDefaultProfile=false, showAllInlineMedia=false, friendsCount=102, createdAt=Tue Aug 29 09:12:49 GMT+09:00 2017, favouritesCount=204, utcOffset=-25200, timeZone='Pacific Time (US & Canada)', profileBackgroundImageUrl='http://abs.twimg.com/images/themes/theme1/bg.png', profileBackgroundImageUrlHttps='https://abs.twimg.com/images/themes/theme1/bg.png', profileBackgroundTiled=false, lang='ja', statusesCount=173, isGeoEnabled=false, isVerified=false, translator=false, listedCount=0, isFollowRequestSent=false, withheldInCountries=null}
ツイート数=173
フォロワー数=66
フォロー数=102
いいね数=204
アカウント作成日=Tue Aug 29 09:12:49 GMT+09:00 2017
最近のツイートJSON=StatusJSONImpl{createdAt=Mon Oct 09 11:26:20 GMT+09:00 2017, id=917214617541124096, text='プログラム組んでるとTwitterするの忘れてしまう…😱😱', source='<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=1, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=0, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=-1, quotedStatus=null}
最近のツイート本文=プログラム組んでるとTwitterするの忘れてしまう…😱😱
最近のツイート日時=Mon Oct 09 11:26:20 GMT+09:00 2017

本題の立憲民主党を取得してみる

自分のアカウントだけでなく、他のユーザの情報も取得できます。

Twitter::showUser()を使うと対象のユーザー情報がJSON形式で取得できます。

UserJSONImpl{id=914762049481084929, name='立憲民主党', screenName='CDP2017', location='', description='立憲民主党公式アカウントです。 代表 枝野幸男 @edanoyukio0531 選挙公約 https://t.co/aPeWMDlGNE', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', isDefaultProfileImage=false, url='https://t.co/QuM59HT4pJ', isProtected=false, followersCount=169816, status=StatusJSONImpl{createdAt=Mon Oct 09 19:27:09 GMT+09:00 2017, id=917335619180699648, text='比例中国に秋葉前広島市長=立憲民主、候補78人に【17衆院選】:時事ドットコム https://t.co/kcPLVejs9b @jijicomさんから', source='<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=392, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=231, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[UserMentionEntityJSONImpl{name='時事ドットコム', screenName='jijicom', id=143383314}], urlEntities=[URLEntityJSONImpl{url='https://t.co/kcPLVejs9b', expandedURL='https://www.jiji.com/jc/article?k=2017100900358&g=pol', displayURL='jiji.com/jc/article?k=2…'}], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=-1, quotedStatus=null}, profileBackgroundColor='F5F8FA', profileTextColor='333333', profileLinkColor='1DA1F2', profileSidebarFillColor='DDEEF6', profileSidebarBorderColor='C0DEED', profileUseBackgroundImage=true, isDefaultProfile=true, showAllInlineMedia=false, friendsCount=52, createdAt=Mon Oct 02 17:00:42 GMT+09:00 2017, favouritesCount=562, utcOffset=32400, timeZone='Tokyo', profileBackgroundImageUrl='null', profileBackgroundImageUrlHttps='null', profileBackgroundTiled=false, lang='ja', statusesCount=293, isGeoEnabled=false, isVerified=true, translator=false, listedCount=1616, isFollowRequestSent=false, withheldInCountries=null}

立憲民主党のフォロワーを調べてみる

立憲民主党のユーザーIDが分かったので、そこからフォロワーを取得することができます。

フォロワーを5000人取り出し、ツイート数を調べてみる

フォロワーはTwitter::getFollowersIDs()で取得できます。

実行結果がとても長いので見出しをクリックして見てください。もう一度見出しをクリックすると閉じます。

↓↓をクリックで結果が開きますもう一度クリックで閉じます

クリックして結果を見る

UserJSONImpl{id=914762049481084929, name='立憲民主党', screenName='CDP2017', location='', description='立憲民主党公式アカウントです。 代表 枝野幸男 @edanoyukio0531 選挙公約 https://t.co/aPeWMDlGNE', isContributorsEnabled=false, profileImageUrl='http://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', profileImageUrlHttps='https://pbs.twimg.com/profile_images/914764308894048256/fvmpSQk1_normal.jpg', isDefaultProfileImage=false, url='https://t.co/QuM59HT4pJ', isProtected=false, followersCount=169974, status=StatusJSONImpl{createdAt=Mon Oct 09 20:09:56 GMT+09:00 2017, id=917346386898706432, text='ありがとうございます!! https://t.co/2EgBMtM1gj', source='<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>', isTruncated=false, inReplyToStatusId=-1, inReplyToUserId=-1, isFavorited=false, isRetweeted=false, favoriteCount=233, inReplyToScreenName='null', geoLocation=null, place=null, retweetCount=101, isPossiblySensitive=false, lang='ja', contributorsIDs=[], retweetedStatus=null, userMentionEntities=[], urlEntities=[URLEntityJSONImpl{url='https://t.co/2EgBMtM1gj', expandedURL='https://twitter.com/sejiouen/status/917336855242170368', displayURL='twitter.com/sejiouen/statu…'}], hashtagEntities=[], mediaEntities=[], symbolEntities=[], currentUserRetweetId=-1, user=null, withHeldInCountries=null, quotedStatusId=917336855242170368, quotedStatus=null}, profileBackgroundColor='F5F8FA', profileTextColor='333333', profileLinkColor='1DA1F2', profileSidebarFillColor='DDEEF6', profileSidebarBorderColor='C0DEED', profileUseBackgroundImage=true, isDefaultProfile=true, showAllInlineMedia=false, friendsCount=52, createdAt=Mon Oct 02 17:00:42 GMT+09:00 2017, favouritesCount=562, utcOffset=32400, timeZone='Tokyo', profileBackgroundImageUrl='null', profileBackgroundImageUrlHttps='null', profileBackgroundTiled=false, lang='ja', statusesCount=294, isGeoEnabled=false, isVerified=true, translator=false, listedCount=1622, isFollowRequestSent=false, withheldInCountries=null}
5000件のフォロワーを取得しました。
50パックに小分けしました。
5000件のフォロワー情報を取得しました。立憲民主党のフォロワー5000人のツイート数の分布は
ツイート数 0 : 3667人
ツイート数 10241 : 1人
ツイート数 1 : 93人
ツイート数 4098 : 1人
ツイート数 2 : 67人
ツイート数 3 : 20人
ツイート数 4 : 30人
ツイート数 5 : 14人
ツイート数 6 : 23人
ツイート数 7 : 13人
ツイート数 8 : 9人
ツイート数 6153 : 1人
ツイート数 9 : 7人
ツイート数 10 : 11人
ツイート数 11 : 8人
ツイート数 26636 : 1人
ツイート数 12 : 9人
ツイート数 13 : 5人
ツイート数 14 : 5人
ツイート数 2063 : 1人
ツイート数 15 : 8人
ツイート数 16 : 8人
ツイート数 17 : 6人
ツイート数 18 : 9人
ツイート数 19 : 4人
ツイート数 4116 : 1人
ツイート数 20 : 6人
ツイート数 21 : 2人
ツイート数 14358 : 1人
ツイート数 6166 : 1人
ツイート数 22 : 6人
ツイート数 23 : 4人
ツイート数 24 : 7人
ツイート数 25 : 4人
ツイート数 26 : 1人
ツイート数 6171 : 1人
ツイート数 27 : 2人
ツイート数 28 : 6人
ツイート数 29 : 3人
ツイート数 30 : 3人
ツイート数 77854 : 1人
ツイート数 6175 : 1人
ツイート数 31 : 1人
ツイート数 32 : 2人
ツイート数 2081 : 1人
ツイート数 33 : 5人
ツイート数 2082 : 1人
ツイート数 34 : 1人
ツイート数 35 : 7人
ツイート数 36 : 2人
ツイート数 37 : 2人
ツイート数 38 : 2人
ツイート数 2087 : 2人
ツイート数 39 : 3人
ツイート数 40 : 2人
ツイート数 41 : 1人
ツイート数 42 : 3人
ツイート数 43 : 5人
ツイート数 44 : 2人
ツイート数 45 : 4人
ツイート数 46 : 2人
ツイート数 47 : 1人
ツイート数 48 : 1人
ツイート数 49 : 2人
ツイート数 2098 : 1人
ツイート数 50 : 2人
ツイート数 51 : 1人
ツイート数 8244 : 1人
ツイート数 52 : 2人
ツイート数 55 : 2人
ツイート数 55352 : 1人
ツイート数 57 : 3人
ツイート数 58 : 1人
ツイート数 59 : 1人
ツイート数 60 : 4人
ツイート数 61 : 1人
ツイート数 62 : 3人
ツイート数 64 : 2人
ツイート数 8257 : 1人
ツイート数 65 : 2人
ツイート数 66 : 2人
ツイート数 161857 : 1人
ツイート数 68 : 2人
ツイート数 6213 : 1人
ツイート数 70 : 2人
ツイート数 72 : 3人
ツイート数 73 : 6人
ツイート数 8267 : 1人
ツイート数 76 : 1人
ツイート数 32845 : 1人
ツイート数 77 : 1人
ツイート数 78 : 1人
ツイート数 79 : 2人
ツイート数 81 : 2人
ツイート数 82 : 1人
ツイート数 83 : 2人
ツイート数 6228 : 1人
ツイート数 85 : 1人
ツイート数 43096 : 1人
ツイート数 89 : 1人
ツイート数 91 : 2人
ツイート数 95 : 3人
ツイート数 96 : 2人
ツイート数 98 : 3人
ツイート数 102 : 4人
ツイート数 103 : 1人
ツイート数 104 : 1人
ツイート数 105 : 1人
ツイート数 108 : 1人
ツイート数 4205 : 1人
ツイート数 109 : 1人
ツイート数 110 : 2人
ツイート数 111 : 2人
ツイート数 113 : 1人
ツイート数 115 : 1人
ツイート数 2164 : 1人
ツイート数 116 : 2人
ツイート数 2165 : 1人
ツイート数 117 : 2人
ツイート数 2166 : 1人
ツイート数 110713 : 1人
ツイート数 120 : 1人
ツイート数 121 : 2人
ツイート数 124 : 2人
ツイート数 125 : 2人
ツイート数 127 : 1人
ツイート数 2176 : 1人
ツイート数 128 : 1人
ツイート数 2177 : 1人
ツイート数 130 : 3人
ツイート数 131 : 1人
ツイート数 6276 : 1人
ツイート数 132 : 2人
ツイート数 133 : 1人
ツイート数 134 : 1人
ツイート数 135 : 2人
ツイート数 4232 : 1人
ツイート数 137 : 2人
ツイート数 138 : 2人
ツイート数 139 : 1人
ツイート数 140 : 2人
ツイート数 141 : 1人
ツイート数 18575 : 1人
ツイート数 146 : 1人
ツイート数 2195 : 1人
ツイート数 147 : 2人
ツイート数 148 : 1人
ツイート数 150 : 2人
ツイート数 151 : 1人
ツイート数 8344 : 1人
ツイート数 152 : 2人
ツイート数 156 : 2人
ツイート数 2205 : 1人
ツイート数 158 : 2人
ツイート数 6304 : 1人
ツイート数 2211 : 1人
ツイート数 164 : 2人
ツイート数 165 : 3人
ツイート数 10407 : 1人
ツイート数 4263 : 1人
ツイート数 168 : 2人
ツイート数 10411 : 1人
ツイート数 171 : 1人
ツイート数 174 : 1人
ツイート数 175 : 1人
ツイート数 30896 : 1人
ツイート数 2224 : 1人
ツイート数 178 : 1人
ツイート数 24756 : 1人
ツイート数 180 : 1人
ツイート数 181 : 1人
ツイート数 108729 : 1人
ツイート数 2234 : 1人
ツイート数 186 : 2人
ツイート数 187 : 1人
ツイート数 188 : 1人
ツイート数 189 : 2人
ツイート数 190 : 1人
ツイート数 191 : 1人
ツイート数 196 : 3人
ツイート数 198 : 1人
ツイート数 199 : 1人
ツイート数 202 : 1人
ツイート数 10443 : 1人
ツイート数 4301 : 1人
ツイート数 2254 : 1人
ツイート数 206 : 1人
ツイート数 209 : 1人
ツイート数 210 : 2人
ツイート数 51412 : 1人
ツイート数 2262 : 1人
ツイート数 214 : 1人
ツイート数 2263 : 1人
ツイート数 8408 : 1人
ツイート数 217 : 2人
ツイート数 221 : 1人
ツイート数 223 : 2人
ツイート数 225 : 1人
ツイート数 4322 : 1人
ツイート数 226 : 1人
ツイート数 2275 : 1人
ツイート数 228 : 3人
ツイート数 14565 : 1人
ツイート数 32998 : 1人
ツイート数 231 : 3人
ツイート数 2282 : 1人
ツイート数 2283 : 1人
ツイート数 235 : 1人
ツイート数 236 : 1人
ツイート数 238 : 1人
ツイート数 6385 : 1人
ツイート数 241 : 1人
ツイート数 242 : 1人
ツイート数 243 : 1人
ツイート数 245 : 2人
ツイート数 246 : 1人
ツイート数 247 : 1人
ツイート数 10489 : 1人
ツイート数 249 : 1人
ツイート数 250 : 3人
ツイート数 28925 : 1人
ツイート数 4350 : 1人
ツイート数 254 : 1人
ツイート数 135427 : 1人
ツイート数 258 : 1人
ツイート数 259 : 1人
ツイート数 260 : 2人
ツイート数 10502 : 1人
ツイート数 6408 : 1人
ツイート数 266 : 1人
ツイート数 268 : 2人
ツイート数 6413 : 1人
ツイート数 55570 : 1人
ツイート数 274 : 2人
ツイート数 275 : 1人
ツイート数 279 : 1人
ツイート数 281 : 1人
ツイート数 286 : 2人
ツイート数 2335 : 1人
ツイート数 287 : 1人
ツイート数 296 : 1人
ツイート数 297 : 2人
ツイート数 298 : 1人
ツイート数 4401 : 1人
ツイート数 305 : 1人
ツイート数 310 : 1人
ツイート数 20791 : 1人
ツイート数 313 : 1人
ツイート数 10554 : 1人
ツイート数 4410 : 1人
ツイート数 314 : 1人
ツイート数 2365 : 1人
ツイート数 2367 : 1人
ツイート数 323 : 1人
ツイート数 10564 : 1人
ツイート数 324 : 1人
ツイート数 326 : 1人
ツイート数 327 : 1人
ツイート数 328 : 1人
ツイート数 330 : 1人
ツイート数 4430 : 1人
ツイート数 334 : 1人
ツイート数 24912 : 1人
ツイート数 4432 : 1人
ツイート数 339 : 1人
ツイート数 341 : 1人
ツイート数 4440 : 1人
ツイート数 344 : 1人
ツイート数 346 : 1人
ツイート数 2397 : 1人
ツイート数 349 : 1人
ツイート数 6495 : 1人
ツイート数 352 : 1人
ツイート数 356 : 1人
ツイート数 2405 : 1人
ツイート数 360 : 1人
ツイート数 361 : 1人
ツイート数 362 : 1人
ツイート数 364 : 1人
ツイート数 368 : 2人
ツイート数 371 : 1人
ツイート数 10612 : 1人
ツイート数 4469 : 1人
ツイート数 4470 : 1人
ツイート数 374 : 2人
ツイート数 375 : 1人
ツイート数 380 : 1人
ツイート数 100735 : 1人
ツイート数 383 : 1人
ツイート数 8578 : 1人
ツイート数 2434 : 3人
ツイート数 386 : 1人
ツイート数 10627 : 1人
ツイート数 387 : 2人
ツイート数 4485 : 1人
ツイート数 389 : 2人
ツイート数 390 : 1人
ツイート数 156037 : 1人
ツイート数 2439 : 1人
ツイート数 395 : 2人
ツイート数 396 : 1人
ツイート数 14737 : 1人
ツイート数 20882 : 1人
ツイート数 402 : 2人
ツイート数 403 : 1人
ツイート数 2454 : 1人
ツイート数 406 : 1人
ツイート数 408 : 1人
ツイート数 410 : 1人
ツイート数 10651 : 1人
ツイート数 412 : 1人
ツイート数 2467 : 1人
ツイート数 420 : 1人
ツイート数 421 : 1人
ツイート数 423 : 1人
ツイート数 425 : 1人
ツイート数 432 : 1人
ツイート数 433 : 1人
ツイート数 436 : 1人
ツイート数 437 : 2人
ツイート数 12727 : 1人
ツイート数 440 : 1人
ツイート数 442 : 1人
ツイート数 444 : 1人
ツイート数 445 : 1人
ツイート数 446 : 1人
ツイート数 447 : 1人
ツイート数 448 : 1人
ツイート数 452 : 1人
ツイート数 2503 : 1人
ツイート数 455 : 1人
ツイート数 2504 : 1人
ツイート数 12745 : 1人
ツイート数 8649 : 1人
ツイート数 463 : 1人
ツイート数 467 : 1人
ツイート数 468 : 1人
ツイート数 469 : 1人
ツイート数 6615 : 1人
ツイート数 10713 : 1人
ツイート数 2521 : 1人
ツイート数 478 : 1人
ツイート数 479 : 1人
ツイート数 483 : 1人
ツイート数 14821 : 1人
ツイート数 12777 : 1人
ツイート数 490 : 1人
ツイート数 2539 : 1人
ツイート数 12782 : 1人
ツイート数 2542 : 2人
ツイート数 76275 : 1人
ツイート数 2548 : 1人
ツイート数 502 : 2人
ツイート数 8696 : 1人
ツイート数 506 : 1人
ツイート数 14844 : 1人
ツイート数 508 : 1人
ツイート数 25085 : 1人
ツイート数 6654 : 1人
ツイート数 510 : 1人
ツイート数 12801 : 1人
ツイート数 513 : 2人
ツイート数 515 : 1人
ツイート数 14853 : 1人
ツイート数 518 : 2人
ツイート数 522 : 1人
ツイート数 523 : 1人
ツイート数 524 : 2人
ツイート数 4623 : 1人
ツイート数 530 : 1人
ツイート数 12819 : 1人
ツイート数 532 : 2人
ツイート数 533 : 1人
ツイート数 4636 : 1人
ツイート数 540 : 1人
ツイート数 542 : 1人
ツイート数 14882 : 1人
ツイート数 6691 : 1人
ツイート数 2595 : 1人
ツイート数 4644 : 1人
ツイート数 2597 : 1人
ツイート数 550 : 1人
ツイート数 2599 : 1人
ツイート数 553 : 1人
ツイート数 14892 : 1人
ツイート数 74284 : 1人
ツイート数 2605 : 2人
ツイート数 21039 : 1人
ツイート数 560 : 1人
ツイート数 562 : 1人
ツイート数 18995 : 1人
ツイート数 566 : 1人
ツイート数 567 : 2人
ツイート数 570 : 1人
ツイート数 573 : 1人
ツイート数 10814 : 1人
ツイート数 2627 : 1人
ツイート数 580 : 1人
ツイート数 39495 : 1人
ツイート数 25160 : 1人
ツイート数 584 : 1人
ツイート数 587 : 1人
ツイート数 6733 : 1人
ツイート数 592 : 1人
ツイート数 593 : 1人
ツイート数 2642 : 1人
ツイート数 10835 : 1人
ツイート数 127573 : 1人
ツイート数 35414 : 1人
ツイート数 599 : 1人
ツイート数 602 : 1人
ツイート数 603 : 1人
ツイート数 6752 : 1人
ツイート数 608 : 2人
ツイート数 611 : 1人
ツイート数 2662 : 1人
ツイート数 614 : 1人
ツイート数 2665 : 1人
ツイート数 617 : 1人
ツイート数 626 : 2人
ツイート数 4724 : 1人
ツイート数 2678 : 2人
ツイート数 635 : 3人
ツイート数 636 : 1人
ツイート数 17022 : 1人
ツイート数 2686 : 1人
ツイート数 642 : 1人
ツイート数 643 : 1人
ツイート数 645 : 1人
ツイート数 647 : 1人
ツイート数 2696 : 1人
ツイート数 51850 : 1人
ツイート数 2699 : 1人
ツイート数 2703 : 1人
ツイート数 655 : 2人
ツイート数 12944 : 1人
ツイート数 657 : 1人
ツイート数 6802 : 1人
ツイート数 658 : 1人
ツイート数 4757 : 1人
ツイート数 8854 : 1人
ツイート数 663 : 1人
ツイート数 2712 : 1人
ツイート数 12959 : 1人
ツイート数 4769 : 1人
ツイート数 8871 : 1人
ツイート数 8874 : 1人
ツイート数 6826 : 1人
ツイート数 8877 : 1人
ツイート数 688 : 1人
ツイート数 691 : 1人
ツイート数 2744 : 1人
ツイート数 698 : 1人
ツイート数 699 : 1人
ツイート数 704 : 1人
ツイート数 15042 : 1人
ツイート数 709 : 1人
ツイート数 10953 : 1人
ツイート数 8906 : 1人
ツイート数 720 : 1人
ツイート数 726 : 1人
ツイート数 2775 : 1人
ツイート数 736 : 1人
ツイート数 174816 : 1人
ツイート数 6886 : 1人
ツイート数 6888 : 1人
ツイート数 35561 : 1人
ツイート数 4842 : 1人
ツイート数 746 : 1人
ツイート数 2804 : 1人
ツイート数 758 : 1人
ツイート数 760 : 1人
ツイート数 4857 : 1人
ツイート数 761 : 1人
ツイート数 2812 : 1人
ツイート数 4866 : 1人
ツイート数 772 : 1人
ツイート数 2825 : 1人
ツイート数 778 : 2人
ツイート数 780 : 1人
ツイート数 8976 : 1人
ツイート数 786 : 1人
ツイート数 788 : 2人
ツイート数 789 : 1人
ツイート数 793 : 1人
ツイート数 796 : 1人
ツイート数 797 : 1人
ツイート数 2849 : 1人
ツイート数 21283 : 1人
ツイート数 21289 : 1人
ツイート数 809 : 1人
ツイート数 9008 : 1人
ツイート数 822 : 1人
ツイート数 6970 : 1人
ツイート数 826 : 1人
ツイート数 827 : 1人
ツイート数 4927 : 1人
ツイート数 23360 : 1人
ツイート数 13121 : 1人
ツイート数 833 : 1人
ツイート数 834 : 1人
ツイート数 835 : 1人
ツイート数 838 : 1人
ツイート数 2891 : 1人
ツイート数 37709 : 1人
ツイート数 848 : 1人
ツイート数 2898 : 1人
ツイート数 852 : 1人
ツイート数 853 : 1人
ツイート数 859 : 1人
ツイート数 861 : 1人
ツイート数 9058 : 1人
ツイート数 2914 : 1人
ツイート数 2916 : 2人
ツイート数 869 : 1人
ツイート数 875 : 1人
ツイート数 880 : 1人
ツイート数 70512 : 1人
ツイート数 881 : 1人
ツイート数 884 : 1人
ツイート数 2935 : 2人
ツイート数 891 : 1人
ツイート数 7037 : 1人
ツイート数 17279 : 1人
ツイート数 23426 : 1人
ツイート数 2946 : 1人
ツイート数 899 : 1人
ツイート数 107396 : 1人
ツイート数 7047 : 1人
ツイート数 5000 : 1人
ツイート数 907 : 1人
ツイート数 15245 : 1人
ツイート数 910 : 1人
ツイート数 7056 : 1人
ツイート数 912 : 1人
ツイート数 17297 : 1人
ツイート数 7058 : 1人
ツイート数 916 : 1人
ツイート数 923 : 1人
ツイート数 925 : 1人
ツイート数 9120 : 1人
ツイート数 2979 : 1人
ツイート数 2980 : 1人
ツイート数 50088 : 1人
ツイート数 23464 : 1人
ツイート数 943 : 1人
ツイート数 15285 : 1人
ツイート数 949 : 1人
ツイート数 953 : 1人
ツイート数 956 : 1人
ツイート数 5054 : 1人
ツイート数 967 : 1人
ツイート数 3019 : 1人
ツイート数 11218 : 1人
ツイート数 3028 : 1人
ツイート数 981 : 1人
ツイート数 54232 : 1人
ツイート数 3037 : 1人
ツイート数 994 : 2人
ツイート数 70626 : 1人
ツイート数 3048 : 1人
ツイート数 1004 : 1人
ツイート数 1007 : 1人
ツイート数 3061 : 1人
ツイート数 35830 : 1人
ツイート数 7159 : 1人
ツイート数 1019 : 1人
ツイート数 29693 : 1人
ツイート数 5118 : 1人
ツイート数 1027 : 1人
ツイート数 1033 : 1人
ツイート数 1034 : 1人
ツイート数 1035 : 2人
ツイート数 11276 : 1人
ツイート数 17421 : 1人
ツイート数 1042 : 1人
ツイート数 99348 : 1人
ツイート数 5141 : 1人
ツイート数 3096 : 1人
ツイート数 1049 : 1人
ツイート数 15388 : 1人
ツイート数 1052 : 1人
ツイート数 3101 : 1人
ツイート数 1054 : 1人
ツイート数 1058 : 1人
ツイート数 11302 : 1人
ツイート数 1065 : 1人
ツイート数 1067 : 1人
ツイート数 1068 : 1人
ツイート数 1072 : 2人
ツイート数 1076 : 1人
ツイート数 3125 : 1人
ツイート数 1077 : 1人
ツイート数 5176 : 1人
ツイート数 1080 : 1人
ツイート数 5178 : 1人
ツイート数 1087 : 1人
ツイート数 3138 : 1人
ツイート数 1104 : 1人
ツイート数 3157 : 1人
ツイート数 17505 : 1人
ツイート数 1123 : 1人
ツイート数 3173 : 2人
ツイート数 5231 : 1人
ツイート数 1135 : 1人
ツイート数 11378 : 1人
ツイート数 7282 : 1人
ツイート数 3187 : 1人
ツイート数 27765 : 1人
ツイート数 13439 : 1人
ツイート数 7295 : 1人
ツイート数 1151 : 1人
ツイート数 3202 : 1人
ツイート数 1161 : 1人
ツイート数 21642 : 1人
ツイート数 23691 : 1人
ツイート数 42131 : 1人
ツイート数 46231 : 1人
ツイート数 1177 : 1人
ツイート数 3226 : 1人
ツイート数 1181 : 1人
ツイート数 23710 : 1人
ツイート数 13472 : 1人
ツイート数 1185 : 1人
ツイート数 3240 : 1人
ツイート数 13490 : 1人
ツイート数 1203 : 1人
ツイート数 40120 : 1人
ツイート数 5308 : 1人
ツイート数 7357 : 1人
ツイート数 13507 : 1人
ツイート数 1221 : 2人
ツイート数 7382 : 1人
ツイート数 1241 : 1人
ツイート数 21727 : 1人
ツイート数 1249 : 1人
ツイート数 29927 : 1人
ツイート数 1255 : 1人
ツイート数 38127 : 1人
ツイート数 7409 : 1人
ツイート数 11510 : 1人
ツイート数 1271 : 1人
ツイート数 11512 : 1人
ツイート数 1281 : 1人
ツイート数 7428 : 1人
ツイート数 152840 : 1人
ツイート数 3340 : 1人
ツイート数 11536 : 1人
ツイート数 19729 : 1人
ツイート数 1300 : 1人
ツイート数 5405 : 1人
ツイート数 15654 : 1人
ツイート数 5417 : 1人
ツイート数 3377 : 1人
ツイート数 1331 : 1人
ツイート数 1334 : 1人
ツイート数 7482 : 1人
ツイート数 3393 : 1人
ツイート数 9543 : 1人
ツイート数 1360 : 1人
ツイート数 1361 : 1人
ツイート数 1363 : 1人
ツイート数 1367 : 1人
ツイート数 13656 : 1人
ツイート数 3417 : 1人
ツイート数 1369 : 1人
ツイート数 1371 : 1人
ツイート数 15715 : 1人
ツイート数 17764 : 1人
ツイート数 1380 : 1人
ツイート数 38246 : 1人
ツイート数 1383 : 1人
ツイート数 3433 : 1人
ツイート数 5490 : 1人
ツイート数 7541 : 1人
ツイート数 50550 : 1人
ツイート数 3447 : 1人
ツイート数 5498 : 1人
ツイート数 5503 : 1人
ツイート数 1407 : 1人
ツイート数 3456 : 1人
ツイート数 44419 : 1人
ツイート数 1413 : 1人
ツイート数 1426 : 1人
ツイート数 21907 : 1人
ツイート数 1428 : 1人
ツイート数 1431 : 1人
ツイート数 13724 : 1人
ツイート数 5532 : 1人
ツイート数 1442 : 1人
ツイート数 1446 : 1人
ツイート数 1447 : 1人
ツイート数 1450 : 1人
ツイート数 3501 : 1人
ツイート数 13744 : 1人
ツイート数 7602 : 1人
ツイート数 7603 : 1人
ツイート数 1460 : 1人
ツイート数 13749 : 1人
ツイート数 11701 : 1人
ツイート数 5559 : 1人
ツイート数 3516 : 1人
ツイート数 1469 : 1人
ツイート数 3522 : 1人
ツイート数 7624 : 1人
ツイート数 1481 : 1人
ツイート数 1484 : 1人
ツイート数 11728 : 1人
ツイート数 1492 : 1人
ツイート数 3547 : 1人
ツイート数 1503 : 1人
ツイート数 1508 : 1人
ツイート数 5607 : 1人
ツイート数 1512 : 1人
ツイート数 24041 : 1人
ツイート数 15850 : 1人
ツイート数 1515 : 1人
ツイート数 1516 : 1人
ツイート数 5617 : 1人
ツイート数 11765 : 1人
ツイート数 5624 : 1人
ツイート数 3593 : 1人
ツイート数 1549 : 1人
ツイート数 7697 : 1人
ツイート数 181786 : 1人
ツイート数 22054 : 1人
ツイート数 1580 : 1人
ツイート数 17965 : 1人
ツイート数 9777 : 1人
ツイート数 5683 : 1人
ツイート数 3639 : 1人
ツイート数 1599 : 1人
ツイート数 1609 : 1人
ツイート数 34382 : 1人
ツイート数 1615 : 2人
ツイート数 7762 : 1人
ツイート数 9813 : 1人
ツイート数 24151 : 1人
ツイート数 1623 : 1人
ツイート数 13916 : 1人
ツイート数 1628 : 2人
ツイート数 20061 : 1人
ツイート数 5727 : 1人
ツイート数 54887 : 1人
ツイート数 13935 : 1人
ツイート数 87668 : 1人
ツイート数 1667 : 1人
ツイート数 3720 : 1人
ツイート数 3728 : 1人
ツイート数 1684 : 1人
ツイート数 13978 : 1人
ツイート数 1693 : 1人
ツイート数 24222 : 1人
ツイート数 1698 : 1人
ツイート数 13989 : 1人
ツイート数 20136 : 1人
ツイート数 3753 : 1人
ツイート数 1711 : 1人
ツイート数 1730 : 1人
ツイート数 9924 : 1人
ツイート数 3782 : 1人
ツイート数 5835 : 1人
ツイート数 3788 : 1人
ツイート数 32461 : 1人
ツイート数 18128 : 1人
ツイート数 48855 : 1人
ツイート数 5854 : 1人
ツイート数 1758 : 1人
ツイート数 3811 : 1人
ツイート数 1763 : 1人
ツイート数 5862 : 1人
ツイート数 9961 : 1人
ツイート数 14070 : 1人
ツイート数 3832 : 1人
ツイート数 22269 : 1人
ツイート数 63230 : 1人
ツイート数 1796 : 1人
ツイート数 1800 : 1人
ツイート数 5900 : 1人
ツイート数 16142 : 1人
ツイート数 1807 : 1人
ツイート数 1810 : 1人
ツイート数 1815 : 1人
ツイート数 10017 : 1人
ツイート数 3875 : 1人
ツイート数 1829 : 1人
ツイート数 3892 : 1人
ツイート数 14135 : 1人
ツイート数 1850 : 1人
ツイート数 3900 : 1人
ツイート数 1855 : 1人
ツイート数 3908 : 1人
ツイート数 3911 : 1人
ツイート数 8008 : 1人
ツイート数 1869 : 1人
ツイート数 3923 : 1人
ツイート数 5976 : 1人
ツイート数 8027 : 1人
ツイート数 12127 : 1人
ツイート数 1892 : 1人
ツイート数 1896 : 1人
ツイート数 79731 : 1人
ツイート数 18290 : 1人
ツイート数 3955 : 1人
ツイート数 1907 : 1人
ツイート数 1909 : 1人
ツイート数 1912 : 1人
ツイート数 75644 : 1人
ツイート数 36735 : 1人
ツイート数 3967 : 1人
ツイート数 38801 : 1人
ツイート数 1945 : 1人
ツイート数 1954 : 1人
ツイート数 6051 : 1人
ツイート数 34724 : 1人
ツイート数 1961 : 1人
ツイート数 12203 : 1人
ツイート数 1967 : 1人
ツイート数 1968 : 1人
ツイート数 8116 : 1人
ツイート数 1972 : 1人
ツイート数 1980 : 1人
ツイート数 6077 : 1人
ツイート数 1985 : 1人
ツイート数 1988 : 1人
ツイート数 1997 : 1人
ツイート数 4050 : 1人
ツイート数 4058 : 1人
ツイート数 24545 : 1人
ツイート数 4067 : 1人
ツイート数 49129 : 1人

↑の見出しをクリックで結果が開きます

ちゃんとソートしたつもりでしたが、バラバラに表示されてしまいました。

約73%が1回もツイートしていないという結果に!

f:id:neet-utsu-taro:20171009204817p:plain

ツイート数 0 : 3667人
ツイート数 1 : 93人
ツイート数 2 : 67人
ツイート数 3 : 20人
ツイート数 4 : 30人
ツイート数 5 : 14人
ツイート数 6 : 23人
ツイート数 7 : 13人
ツイート数 8 : 9人
ツイート数 9 : 7人
ツイート数 10 : 11人

1回もツイートしてない人は3667/5000で約73.3%ですね。

ツイート数が10回以下の人数は3954/5000で約79.1%です。

恐ろしや…( ゚Д゚)

立憲民主党のフォロワーの人はシャイなのかな?(震え声)

追記:コメントで指摘がありました。一つはデータの質に関するもの。もう一つは他党との比較がないという事でした。前者は今すぐに求めることはできませんが、後者はプログラムの変数を変えるだけなのですぐに求めることができました。

政党別のものを出します。他の野党の政党のものは面倒なので省きました… 興味のある方は上のソースコードからぜひ試してください。

f:id:neet-utsu-taro:20171010010752p:plain

終わりに

ここまで読んでくださって、ありがとうございます。

もしかしたら、バグや勘違いしてるかも?気が付いた方はコメント等で知らせてくれると嬉しいです。

自分でプログラムを組んで分析してみるのも楽しいですね。プログラムに興味のある方はぜひ試してみてください。

もし好評なら、フォロワーのツイート数だけでなく他の要素からも分析してみたいと思います。

またね('ω')ノ

AtCoderの過去問に挑戦 ABC001 AtCoder Beginner Contest 001

こんにちは、鬱太郎です。数あるプログラミングコンテストの中の一つAtCoder。今日はAtCoderの過去問のABC(初心者向け問題)を解いてみたのでそれを記事にしたいと思います。プログラミングに興味のない方はごめんなさいm( _ _ )m

atcoderの画像を使わせていただきました。問題があれば削除痛いします。

はじめに

私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。

公式URL

abc001.contest.atcoder.jp

使用したもの等

名称 使用したもの
言語 JavaSE8
エディタ pleiades All in one var.4.7.0
プラグイン addons.mozilla.org

ほとんどの人がc++java使っている人あんまりいないのが悲しい( ;∀;) プラグインのおかげでスムーズにプログラムができました。お勧めです。

A - 積雪深差

見出しをクリックすると開きます。↓↓

問題

回答

B - 視程の通報

見出しをクリックすると開きます。↓↓

問題

回答

C - 風力観測

見出しをクリックすると開きます。↓↓

問題

回答

改善

D - 感雨時刻の整理

見出しをクリックすると開きます。↓↓

問題

回答

改善

まとめ

AtCoderの過去問を初心者クラスですが、すべて解くことができました!実際は2時間で解く必要があるタイムアタックなのですが、過去問の場合はその制限がありません。じっくりと考えることができました。問題をすべて解くのに3時間ちょっとかかったので、本番でしたら半分ほどしか解けていなかったことになります。練習を重ねて2時間ですべて解けるようになりたいです。

また、Dの設問ではメモリの使用量を考慮する必要があったため、ただ解くだけではなくそういった問題も考慮して常にプログラムを書く必要があるのだなと実感しました。

なけなし程度ですがJava8の要素も使えてよかったです。満足です!

終わりに

ここまで読んでくださってありがとうございます。ほとんどの方が興味のないものだったと思いますが、少しでもプログラミングに興味を持ってくださる方がいれば幸いです。

読者登録ありがとうございます。励みになっています。

今回は記事中にクリックしたら開閉するシステムを導入してみました。HTMLやjsの勉強にもなっていい感じです。

記事の文字数60000オーバーwHTMLでも記述したりしているのでそりゃそうなりますか。もしかしたらはてなブログ書いてる人の中で一番多い文字数書いたかも?w(*'ω'*)

今日ぎりぎりに記事にできてよかったです。おやすみなさい。_(:3」∠)_

またね('ω')ノ

AtCoderに登録してみた

こんにちは、鬱太郎です。今日は日本語が対応しているプログラミングコンテストAtCoderに登録してみたのでそれについて記事にしたいと思います。

AtCoderに会員登録をする

AtCoderの公式ページAtCoderから会員登録ができます。

右上にある会員登録をクリックします。

すると、会員登録に必要な項目の記入を促されるため、記入しましょう。

必須項目を記入して新規登録しましょう

サンプル問題に挑戦

会員登録すると、次のような画面が出ます。試しにサンプル問題を回答してみましょうか。

会員登録が完了するとこの画面が表示されます

画面中心にあるpractice contestに参加するボタンをクリックしてサンプル問題に参加してみましょう

サンプル問題に参加するとこの画面のようになります

問題タブを見ると2種類の問題があります。

サンプル問題が2種類あります

Aの問題をクリックしましょう。問題文が表示されます。

サンプル問題の問題文が表示されました

このページには様々なプログラミング言語のサンプルプログラムがあります。好きな言語の入出力の方法を詳しく見ておきましょう

私はJavaを選びました。

これを提出タブのコード欄に貼り付けて提出しましょう。

提出してしばらくすると結果が出ます

提出してしばらく経過すると採点された結果を見ることができます。実行時間およびメモリ使用量が詳しく表示されます。

ちなみにサンプル問題Bは私には早すぎたようです…( ;∀;)

頑張っていつか解けるようになりたいです。

終わりに

ここまで見ていただき、ありがとうございます!

今日はプログラムの話でした。興味のない方は申し訳ありません。

またね('ω')ノ

Androidの簡単な電卓アプリを作ろう レイアウト編

こんにちは、鬱太郎です。今日は、念願のAndroidアプリの作成です。比較的、簡単そうな電卓アプリを(デザインだけ)作ってみましたのでそれをまとめたいと思います。四則演算だけ!マイナスも考慮しないよ!面倒だから! f:id:neet-utsu-taro:20170914063241p:plain

過去の記事

Android Studioをインストールしていない方はこちら neet-utsu-taro.hatenablog.jp

解説動画

鋭意製作中(´;ω;`) ごめんなさい!

どんなアプリを作るのかをイメージしよう

簡単な設計図を描いてみよう

なんとなくでよいので簡単な設計図を書きました。下手でごめん!( ;∀;) f:id:neet-utsu-taro:20170914042624p:plain 見た目だけでなく、いろいろと制約も書いておきます。できるだけ機能を削ったデザインにしておきます。

フロント(デザイン)部分を抜き出してみよう

最初に作った設計図にデザインに特化した説明を書きたしました。

f:id:neet-utsu-taro:20170914085806p:plain

定義

下の様な計算を電卓アプリでしようとします。

a + b = c

その場合、ここの記事では

要素 名称
a 被演算子(左方)
b 被演算子(右方)
c 計算結果および被演算子(右方)
+,-,×,÷,= 演算子

として扱います。

実際に作ってみよう

今回はGUI形式でレイアウトしていきます。よくわからない方はXMLファイルのところに設定ファイルがあるので参考にしてください。もしくは解説動画をご覧ください。

1.数値表示部分とボタン部分を分けるためのLinearLayoutを追加

f:id:neet-utsu-taro:20170914131942p:plain

上の図のように数値表示部分とボタン部分を大きく分けるためにLinearLayout(vertical)を最初にあるConstraintLayoutの中に追加します。

f:id:neet-utsu-taro:20170914132612p:plain

LinearLayoutの各要素を下の表にまとめました。

変数名
android:layout_width match_parent(0dp)
android:layout_height match_parent(0dp)
android:orientation vertical
android:layout_marginEnd 16dp
android:layout_marginLeft 16dp
android:layout_marginRight 16dp
android:layout_marginStart 16dp
android:layout_marginTop 24dp
android:weightSum 1
app:layout_constraintBottom_toBottomOf parent
app:layout_constraintLeft_toLeftOf parent
app:layout_constraintRight_toRightOf parent
app:layout_constraintTop_toTopOf parent

外周から一定のサイズ隙間を作ります。下のgifのように操作しましょう(説明放棄・・・( ;∀;))。 f:id:neet-utsu-taro:20170914102757g:plain

同様に下、左右の隙間を作ります。もしくは、変数表を参考に数値を記入しましょう。下の図のようになったら完了です。 f:id:neet-utsu-taro:20170914101704p:plain

2.数値表示部分

f:id:neet-utsu-taro:20170914133401p:plain

2-1.上下のレイアウトを分けるためのLinearLayoutを追加

先ほど作ったLinerLayoutの中の一番上に数値表示部分を追加していきます。

f:id:neet-utsu-taro:20170914134045p:plain

LainearLayoutの要素を表にまとめました。

変数名
android:layout_width match_parent
android:layout_height 50dp
android:orientation vertical

これらの値を入力したら完成です。

f:id:neet-utsu-taro:20170914134931p:plain

2-2.上の部分に被演算子(左方)を表示するTextViewを追加

先ほど作ったLinearLayoutの上部に高さ15dpのTextViewを追加します。

f:id:neet-utsu-taro:20170914140344p:plain

追加するTextViewの要素を表にまとめました。

変数名
android:id sub_number_tv
android:layout_width match_parent
android:layout_height 15dp
android:text subNumberTV

これらの値を入力しましょう。その結果が下のスクショです。

f:id:neet-utsu-taro:20170914141544p:plain

2-3.下の部分に演算子用と被演算子(右方)と分けるためのLinearLayoutを追加

先ほど追加したTextViewの下の部分にLinearLayoutを追加します。

f:id:neet-utsu-taro:20170914142206p:plain

LinearLayoutの要素を表にまとめました。

変数名
android:layout_width match_parent
android:layout_height match_parent
android:orientation horizontal

この値を入力しましょう。

f:id:neet-utsu-taro:20170914142722p:plain

2-4.演算子用のTextViewを追加

先ほど追加したLinearLayoutの左側に演算子を表示するためのTextViewを追加します。

f:id:neet-utsu-taro:20170914143417p:plain

演算子は一文字なのでフォントサイズ大きめの30spで中央ぞろえにします。詳細を表にまとめました。

変数名
android:id op_tv
android:layout_width 50dp
android:layout_height match_parent
android:layout_weight 0
android:text
android:textAlignment center
android:textSize 30sp

入力した結果がこちら

f:id:neet-utsu-taro:20170914144350p:plain

2-5.被演算子(右方)のTextViewを追加

今度は右側にTextViewを追加します。

f:id:neet-utsu-taro:20170914145027p:plain

右から文字が始まることに注意しましょう。

変数名
android:id main_number_tv
android:layout_width match_parent
android:layout_height match_parent
android:layout_weight 1
android:text mainNumberTV
android:textAlignment textEnd
android:textSize 30sp

入力結果はこちら

f:id:neet-utsu-taro:20170914145633p:plain

2-6.被演算子(右方)の右に詰め物を追加

実際にデザインを作ってみて、右揃えの際にもう少し余白が欲しいと思いました。そこで新しいレイアウトを追加して余白を作ろうと思います。TextViewのmarginやpaddingで事足りますね。勉強不足で申し訳ありませんf:id:neet-utsu-taro:20170914153826p:plain

ConstraintLayoutの要素は主にwidthの10dpとweightの0です。

変数名
android:layout_width 10dp
android:layout_height match_parent
android:layout_weight 0

下の結果を見るとほんのちょっと隙間が追加されてますね。

f:id:neet-utsu-taro:20170914154048p:plain

3.ボタン部分

f:id:neet-utsu-taro:20170914154753p:plain

3-1ボタンを配置するためのTableLayoutを追加

1章で追加したLinearLayoutの中の下にボタン部分を表示させるTableLayoutを追加します。

f:id:neet-utsu-taro:20170914163350p:plain

TableLayoutは縦横ともにmatch_parentです。

変数名
android:layout_width match_parent
android:layout_height match_parent
android:layout_margin 10dp
tools:layout_editor_absoluteX 8dp
tools:layout_editor_absoluteY 8dp

入力した結果がこちら

f:id:neet-utsu-taro:20170914163239p:plain

3-2TableLayoutにTableRowを追加

TableLayoutにTableRowを合計5個追加していきます。デフォルトで4個追加されているのであと一個追加しましょう。

f:id:neet-utsu-taro:20170914164835p:plain

気を付ける要素としてそれぞれのTableRowにlayout_weight=0.2と設定することです。TableRowの要素を表にまとめました。各TableRowにこの値を入力していきます。

変数名
android:layout_width match_parent
android:layout_height match_parent
android:layout_weight 0.2

weightを設定するとしっかりと5等分されていると思います。

f:id:neet-utsu-taro:20170914165425p:plain

3-3TableRowにButtonを追加

各TableRowにボタンを追加していきます。4,4,4,4,2個Buttonを追加していきましょう!

f:id:neet-utsu-taro:20170914170004p:plain

Buttonにはlayout_widthとheightにmatch_parentを設定しておきましょう。追加すると次のようになります。

f:id:neet-utsu-taro:20170914170523p:plain

3-4各Buttonのフィールドを設定

各ボタンにそれぞれのIDや数値、textSizeなどを追加していきます。

f:id:neet-utsu-taro:20170914171127p:plain

追加する値は

変数名
android:id bn
android:layout_width match_parent
android:layout_height match_parent
android:layout_weight 1
android:text n
android:textSize 30sp

です。

nは0~9の数値です。演算子やC、ACなど特殊なものは

text id
+ bplus
- bsub
× bmul
÷ bdev
= beq
C bc
AC bac

としました。その結果がこちらです。

f:id:neet-utsu-taro:20170914172127p:plain

4.数値表示部分とボタン部分の間に詰め物を追加

上のTextViewとTableLayoutが少し近いと思ったので間に隙間を入れます。

f:id:neet-utsu-taro:20170914180010p:plain

ConstraintLayoutの各要素は

変数名
android:layout_width match_parent
android:layout_height 15dp

です。

f:id:neet-utsu-taro:20170914175349p:plain

これにてすべての作業が終了しました。やったぜ!

XMLファイル

GUIで作ったレイアウトの設定ファイルです。これをコピーすれば同じレイアウトが表示されます。

apkファイル

今回作った段階でアプリケーションインストーラを作りました。

goo.gl

良ければインストールして「ふーん」と思ってください。

レイアウトしか作ってないのでボタンとか押してもまだ動きませんが…w(´;ω;`)w

AndroidのOSやブラウザ、ウイルス対策ソフトによってはうまくダウンロードできないかもしれません。 かなしい(´;ω;`)

ブラウザ変えてダウンロードしてみるとダウンロードできるかも?(‘ω’)

動かしてみよう

レイアウトのビューで不具合がなくても実行してみるとレイアウトが崩れていたりすることもあります。試しに実行してみましょう

f:id:neet-utsu-taro:20170914071352p:plain

正常ですね!ちなみにボタンを押しても何も動きません。レイアウトしか作ってませんからね。

終わりに

自分でレイアウトするのと記事でまとめるのでは労力が段違いですね…

毎日ちょくちょく記事を書き貯めてようやく公開できました!

でもこれからも頑張っていきます

またね(‘ω’)ノ

話は変わりますが、読者登録してくださった方ありがとうございます。嬉しいです(´;ω;`)

次回の記事

制作中