長すぎるカテゴリー欄をアニメーションですっきりさせてみた
こんにちは鬱太郎です。ブログを書いているとついつい色々なカテゴリーが増えてしまいますよね?私もそうなんです。カテゴリー数が増えてしまうと、サイドモジュールのカテゴリーが占める割合が大きくなってしまいます。他のモジュールが見えなくなってしまいます。
そんな悩みを解決してみたので記事にしたいと思います。
右のカテゴリー欄にマウスカーソルを合わせると…?
スマホの方はカテゴリー欄のタイトルをタップすると…?
アニメーションで開いたり閉じたりします!
何もしないとカテゴリー欄のサイズが小さくなります。カーソルを合わせると、カテゴリー欄がすべて表示されます。
使い方
下のコードをデザイン
→カスタマイズ
→サイドバー
→モジュール追加
→HTML
のコード欄に追加します。タイトルは不要です。一行目はjQueryの読み込みです。既にヘッダー等に同様の記述がある場合は必要ありません。
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script> $(function(){ var normalHeight = "300px"; $(".hatena-module-category").height(normalHeight).css("overflow","hidden").hover(function(e){$(this).animate({height:$(this).get(0).scrollHeight},{duration:"slow"})},function(e){$(this).animate({height:normalHeight},{duration:"slow"})}); }) </script>
私は既にヘッダーにjQueryの読み込み記述があるため、上の画像では同様の記述がありません。注意してください。
var normalHeight = "300px";
の数値はタイトルを含んだカテゴリモジュールを表示させる高さです。好きな値に変更してください。
はい。これだけで完成です!簡単ですね!
終わりに
何かと応用がききそうなのでぜひ試してください!何より楽しいです(*'ω'*)
スターやブックマーク、読者登録等いつもありがとうございます!大変励みになっています!
またね('ω')ノ
AtCoderの過去問に挑戦 ABC076 AtCoder Beginner Contest 076
こんにちは鬱太郎です。先週の土曜日に開催されたAtCoderのコンテストを復習したため、記事にしたいと思います。
はじめに
私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。
公式URL
結果
使用したもの等
名称 | 使用したもの |
---|---|
言語 | 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 回の操作後の、電光掲示板に書かれている整数として考えられる最小の値を求めなさい。
制約
- 1≤N,K≤10
- 入力はすべて整数である
入力
入力は以下の形式で標準入力から与えられる。
N K出力
square1001 が N 回操作を行った後の、電光掲示板に書かれている整数として考えられる最小値を出力しなさい。
入力例 1
4 3出力例 1
10高橋君は、操作 A, A, B, B の順でやると、整数を最小化できます。この時、電光掲示板に書かれている整数は 1 → 2 → 4 → 7 → 10 と変わり、最終的に 10 となります。
入力例 2
10 10出力例 2
76高橋君は、操作 A, A, A, A, B, B, B, B, B, B の順にやると、整数を最小化できます。この時、電光掲示板に書かれている整数は 1 → 2 → 4 → 8 → 16 → 26 → 36 → 46 → 56 → 66 → 76 と変わり、最終的に 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' を見つけ、これは文字列 S の 0 個以上 |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
,...,ztcoder
の 26 個がありますが、その中で最も辞書順で小さいものは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 以内で走っていなければならない。
ただし、列車の性能上、加速度は ±1m⁄s2 以内でなければならない。また、走行開始時と走行終了時には列車は止まっていなければならない。
列車が発車してから停車するまでに走れる最大の距離を求めなさい。
制約
- 1≤N≤100
- 1≤ti≤200
- 1≤vi≤100
- 入力はすべて整数である
入力
入力は以下の形式で標準入力から与えられる。
N t1 t2 t3 … tN v1 v2 v3 … vN出力
列車が発車してから停車するまでに走ることのできる最大の距離を出力しなさい。ただし、絶対誤差が 10−3 以内であれば、正解となります。
入力例 1
1 100 30出力例 1
2100.000000000000000
- 最初の 30 秒は、加速度を 1m⁄s2 にし、加速します。その間に列車は 450m 走ります。
- 次の 40 秒は、速度 30m⁄s を保ちます。その間に列車は 1200m 走ります。
- 最後の 30 秒は、加速度を −1m⁄s2 にし、減速します。その間に列車は 450m 走ります。
合計で、450 + 1200 + 450=2100m 走ることができます。
入力例 2
2 60 50 34 38出力例 2
2632.000000000000000
- 最初の 34 秒は、加速度を 1m⁄s2 にし、加速します。その間に列車は 578m 走ります。
- 次の 26 秒は、速度 34m⁄s を保ちます。その間に列車は 884m 走ります。
- 次の 4 秒は、加速度を 1m⁄s2 にし、加速します。その間に列車は 144m 走ります。
- 次の 8 秒は、速度 38m⁄s を保ちます。その間は列車は 304m 走ります。
- 最後の 38 秒は、加速度を −1m⁄s2 にし、減速します。その間に列車は 722m 走ります。
合計で、578 + 884 + 144 + 304 + 722=2632m 走ることができます。
入力例 3
3 12 14 2 6 2 7出力例 3
76.000000000000000
- 最初の 6 秒は、加速度を 1m⁄s2 にし、加速します。その間に列車は 18m 走ります。
- 次の 2 秒は、速度 6m⁄s を保ちます。その間に列車は 12m 走ります。
- 次の 4 秒は、加速度を −1m⁄s2 にし、減速します。その間に列車は 16m 走ります。
- 次の 14 秒は、速度 2m⁄s を保ちます。その間は列車は 28m 走ります。
- 最後の 2 秒は、加速度を −1m⁄s2 にし、減速します。その間に列車は 2m 走ります。
合計で、18 + 12 + 16 + 28 + 2=76m 走ることができます。
入力例 4
1 9 10出力例 4
20.250000000000000000
- 最初の 4.5 秒は、加速度を 1m⁄s2 にし、加速します。その間に列車は 10.125m 走ります。
- 最後の 4.5 秒は、加速度を −1m⁄s2 にし、減速します。その間に列車は 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
をグラフ関数として追加します。
ですね。ソースコードでは25行目からの部分です。
グラフにすると単なる横棒の関数です。
2.正順に調査し、加速を関数として追加する
i
区間で最大速度-現在速度が正ならば、加速させる必要があります。
こんな感じですね。
の様な傾き1の簡単な関数ですね。
3.逆順に調査し、加速(減速)を関数として追加する
i
区間で最大速度-現在速度が正ならば、加速(減速)させる必要があります。
逆順調査の時だけ、dxの計算が違いますのでご注意を。傾き-1の簡単な関数です。
4.全ての関数をまとめる
全ての関数をまとめます。関数をグラフにするとこんな感じです。
橙色が最大速度の関数(1)、黄色が正順調査の加速関数(2)、灰色が逆順調査の加速(減速)関数(3)です。
5.全ての関数の中で最小の値をマッピングする
集めた関数の中で最小の値を配列に入れましょう。公式解説によると、0.5ごとにマッピングすればよいとのことです。
マッピングをグラフにするとこんな感じです。
青色の部分が最小の値ですね。
6.面積を台形の公式を使って求める
マッピングした配列から台形の公式を使って面積を求めましょう。回答に必要なのは移動した距離です。
距離(m) = 速度(m/s)×時間(s)
ですね。つまり、面積が距離になるわけです。
台形の公式は
面積 = (上底+下底)×高さ÷2
ですね!懐かしい!
ポイント DoubleFunctionとOptionalDoubleを使い関数を表現する
Java8から追加されたDoubleFunction1インターフェースとOptionalDouble2クラスをうまく使うことで、関数を表現しました。
DoubleFunctionインターフェースを使うことで動的に関数を生成できます。
また、OptionalDoubleクラスは値が含まれていない可能性を考慮してくれるもので、Optional.empty()
のように値がない状態を明示して返すことができます。
また、ifPresent
やisPresent
などの条件メソッドも標準であるので便利です。
成績
プログラムの実行時間およびメモリ使用量をまとめました。
実行時間 | メモリ使用量 |
---|---|
390 ms | 49440 KB |
うーん…厳しいですね… ACできればOKという事で。なんだかぐちゃぐちゃなプログラムになってしまいましたが、独自性は抜群なのではないでしょうか?(開き直り) こんな面倒な方法取る人いないでしょう…(´;ω;`)
まとめ
難しかったですが、最終的にはすべてACできてよかったです。本当ならば本番中にすべてクリアしたいですが、まだまだ難しそうですね。
頑張っていきたいと思います。
今回はCの問題が考えててとても楽しかったです。Cのような問題にまた出会いたいですね。
終わりに
ここまで読んでくださってありがとうございます!
AtCoderの復習もようやく終わりました。と思いきや?
今週末から三週連続でABCがあるようです。頑張っていきたいと思います。
スターやブックマーク、読者登録いつもありがとうございます!大変励みになっています!
またね('ω')ノ
画面上に常に画像を表示させる方法
こんにちは鬱太郎です。昨日書いた記事
で画面の左上や左下に画像を常時表示させてみました。その方法があまりにも簡単だったため、記事にしてご紹介したいと思います。
スマホなど画面が小さい方は申し訳ありません。画面がうるさいですが、少し許してください...お願いします!
画面上に何かを常時表示させる
画面上に何かを常時表示させる場合はJavaScript
などのプログラム技術は一切いりません。多少のHTMLコードをかける知識(コピペ等で十分)があれば大丈夫です!
基本はこれposition:fixed
を使用していきます。
<div sylte="position:fixed; 位置指定"> </div>
です。これで常時表示させたい要素を囲むだけでOKです!
位置指定には
- top
- bottom
- left
- right
という上下左右から何ピクセルという指定方法があります。
実装例
画面左上に画像を常時表示させる
HTMLコードの場合(そのまま記法など)はHTML閲覧ページから、画像を表示しているタグ<img>
を見つけ、それをdiv
で囲みましょう。
<div style="position:fixed; top:50px; left:0px;"> <img class="hatena-fotolife" width="50px" title="f:id:neet-utsu-taro:20171031222939p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/n/neet-utsu-taro/20171031/20171031222939.png" alt="f:id:neet-utsu-taro:20171031222939p:plain" /> </div>
Markdown記法の場合は特に簡単で、はてな記法の画像表示部分を<div>
で囲むだけです。
<div style="position:fixed; top:50px; left:0px;"> [f:id:neet-utsu-taro:20171031222939p:plain:w50] </div>
top
やleft
等を指定をしないと、親の位置を元に初期値が決まります。
左下に読者登録ボタンを常時表示する
勿論、画像の部分を他のものに変えることもできます。文章だったり、読者登録ボタンだったり...
という事で、読者登録ボタンを左下に常時表示させてみましょう。読者登録ボタンは設定
->詳細設定
ページからコピペできます。
<div style="position:fixed; bottom:0px; left:0px;"> <iframe src="https://blog.hatena.ne.jp/neet-utsu-taro/neet-utsu-taro.hatenablog.jp/subscribe/iframe" allowtransparency="true" frameborder="0" scrolling="no" width="150" height="28"></iframe> </div>
はい。左下に読者登録ボタンが見えているかと思います。
応用編
マウスオーバーした時のアクションを消したい
ブログのテーマ等の影響で、画像ファイル等にマウスカーソルを合わせた場合にいろいろなアニメーションが表示されることがあります。
それを消したい場合は、pointer-events: none;
を追加しましょう。
<div style="position:fixed; top:120px; left:0px; pointer-events:none;"> <img class="hatena-fotolife" width="50px" title="f:id:neet-utsu-taro:20171031222939p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/n/neet-utsu-taro/20171031/20171031222939.png" alt="f:id:neet-utsu-taro:20171031222939p:plain" /> </div>
画面の左上の1番目が、何もしてないものです。2番目がpointer-events:none;
を追加した画像です。マウスを使づけても影が表示されず、タイトル(ID)も表示されません。
完全に背景としたい場合はおすすめです。ただ、読者登録ボタンなどのクリックしてアクションをするものと組み合わせる場合はそちらのアクションも停止させる恐れがあるため、注意が必要です。
真ん中に表示させる
中央揃えで表示させたい場合はまず表示させたい要素のサイズを調べる必要があります。表示させたいもののサイズが分からない場合は難しいので今回は省きます。
今回表示させたいのは画像幅50pxのものです。
左右に対して中央に表示させたい場合は、left:50%; margin-left:-25px
という風にします。
<div style="position:fixed; bottom:0px; left:50%; margin-left:-25px; pointer-events:none;"> <img class="hatena-fotolife" width="50px" title="f:id:neet-utsu-taro:20171031222939p:plain" src="https://cdn-ak.f.st-hatena.com/images/fotolife/n/neet-utsu-taro/20171031/20171031222939.png" alt="f:id:neet-utsu-taro:20171031222939p:plain" /> </div>
margin-left: -○
○
は幅/2
ですね。
上下に対して中央に表示させたい場合も同じです。高さが68pxのため、margin-top:-34px;
にしています。
<div style="position:fixed; right:0px; top:50%; width:60px; margin-top:-34px;"> <p style="font-size:10px;">いつも見ていただき、ありがとうございます!</p> </div>
こんな感じですね。
いつも見ていただき、ありがとうございます!
要素のサイズを調べるには
要素のサイズといってもどんくらいの大きさかわからない!という方はブラウザのデベロッパーツールをお勧めします。
chromeの例:
調べたい要素を右クリックし、検証を選択します。
すると、下のように要素の範囲を色付けし、詳細な情報を見ることができます。
左下の読者登録ボタンのdivは幅150px高さ36pxですね。
動かないといった場合は
うまく表示されない場合は、
- HTMLのタグが完全に閉じられていない
style
やposition
、fixed
等のスペルミスstyle="..."
が正しいが、style="...
という風になっているstyle
の記述を;
区切りで行っていない
などが考えられます。
注意
この手法は、ウィンドウのサイズや見ているユーザーの機種に関係なく表示させるものです。例えばスマホなどの画面が小さいものでも左上や左下に表示させてしまいます。
そういった場合分けを考慮すると、CSSやJavaScript等で動的に場合分けする必要があります。
ただ、特に何も考えずに表示したい場合はこの手法でOKです。
終わりに
ここまで読んでくださってありがとうございます!
ハロウィンやクリスマスなどのイベントの記事にこういった飾りつけをしてみてはいかがでしょうか?
ぜひ試してみてくださいね!
またね('ω')ノ
AtCoderの本番に初挑戦したよ!
こんにちは鬱太郎です。昨日の21時からAtCoderの生コンテストに参加しまてきました!そのことについて記事にしたいと思います。
AtCoderとは
プログラミングコンテストの一つです。問題が日本語であることが英語のできない私にとってとても大きな特徴です。
ルール
決められた制限時間の中で問題を解きます。問題はA-Dの4問あります。
問題には点数がつけられてます。難しい問題ほど配点が高くなっています。
今回私が挑戦したBeginner Contest 076
は制限時間が100分、配点がA:100,B:200,C:300,D:400でした。全問正解で1000点ですね。
また、同点数の場合は正答した時間で順番が決まります。また、誤答するとペナルティもあるため、回答速度と回答精度の両方が求められます。
結果
本番は初めてでした。
めっちゃ緊張したー_(:3」∠)_
しかも当たり前と言えば当たり前ですが、過去問でやってた初期の問題よりもそれぞれが若干難しくなってましたね。
4問中3問正解!600点GETです! 過去問でも3問目まではらくらく解けていたので、本番も練習と同じ実力が出せてよかったです。
緊張もあってか2問目3問目でしばらくフリーズしていましたw文章読んでも頭の中に入ってこない状態でしたが、過去問を数回解いたおかげで何とか解けました。
過去問を繰り返しやっていると、大体ABCDの問題の各難易度が分かってきます。
Bの問題は絶対難しくない!初心者でも解けるやつ!
Cの問題は高度なアルゴリズムは不要!
という風に自分に言い聞かせられたので、うまく解法にたどり着けたと思います。
いきなりやってたらCは解けなかったかも…
順位
そして、順位は
387位でした!問題を回答していたのが1145人でした。1000点満点の方は141人でした。1000点回答の方たちに加われるように頑張っていきたいです。
参加人数 | 1000点 | 私の順位 |
---|---|---|
1145人 | 141人 | 387位 |
私と同じ600点の方でも、240人の方は私よりも早く問題を解いたという事ですね。凄い…
レート
AtCoderに参加したので、私にレートが付きました!(*'ω'*)
レート:159
まだ始めたばかりで低いのでしょう。レートランキングは7244位です。これも徐々に上げていきたいですね。
日付 | コンテスト | 順位 | パフォーマンス | 新レート | 差分 |
---|---|---|---|---|---|
2017/10/28 22:40 | AtCoder Beginner Contest 076 | 387 | 1232 | 159 | - |
AtCoderのマイページにレートのグラフがあったので、サイドメニューにコピペしてみました。ちっこくてかわいいですね('ω')
終わりに
昨日はとても楽しかったです。大会終了後は興奮して少し眠れませんでした。これから昨日の問題の解けなかった部分に挑戦してみたいと思います。
ここまで読んでくださってありがとうございます!
スター、ブックマーク、読者登録等いつもありがとうございます!とても嬉しいです!
そろそろ10月も終わりですね…
ん?ハロウィン?
ニートにハロウィンなんて関係ないんだよぉ…!現実から逃げて妄想という名の仮装をしているニートなんていつもハロウィン状態でしょ…(´;ω;`)もう、魑魅魍魎状態よ!
冷静に考えるとニートって身だしなみ整えないままハロウィン会場に行ったらゾンビかなんかの仮装としていけるかも…?いや、無理か…
またね('ω')ノ
今日は包除原理について少し勉強したよ
昨日やったABC003-dの問題の解説で包除原理を使うという事を目にしたので、今日は包除原理について少し勉強しました。といっても記事にできる事は何もないのですが( ;∀;)
個人的なメモです。
これのD問題のラスト1点部分について
求めたいもの(灰色)は
|U|-白色の部分
なんですけど、白色の部分が、
それぞれ円の和 - 2つの円の共通部分の和 + 3つの円の共通部分の和 - 4つの円の共通部分の和
これで求められるらしいんですよね。記号で表すと、
|T| + |R| + |B| + |L| //それぞれの円の和 -(|T∩R| + |R∩B| + |B∩L| + |L∩T|) //2つの円の共通部分 +(|T∩R∩B| + |R∩B∩L| + |B∩L∩T| + |L∩T∩R|) //3つの円の共通部分 - |T∩R∩B∩L| //4つの円の共通部分
です。多分。
この理論でプログラムを実装してみたんですけど、一向に正答しないんですよね。
プログラムの実装の仕方でミスしてるのか、そもそもこの考えが間違っているのかわからなくて悩んでます。
しばらく棚上げですかね。
終わりに
ここまで読んでくださってありがとうございます!
今日はAtCoderのコンテストがあるため記事は簡略で早めに終わろうと思います。
機能やった問題を完答させることはできませんでしたが、しばらく寝かしておきます。もしかしたら、未来の成長した私が見事解いてくれるかも?(*'ω'*)
スター、ブックマーク、読者登録ありがとうございます!ものすごく励みになっています!そういえば豊田議員書類送検されたようですね
またね('ω')ノ
AtCoderの過去問に挑戦 ABC003 AtCoder Beginner Contest 003
こんにちは、鬱太郎です。という事(?)でAtCoder Beginner Contestの3回目の過去問をやったのでそれを記事にしていきたいと思います。
はじめに
私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。
公式URL
使用したもの等
名称 | 使用したもの |
---|---|
言語 | JavaSE8 |
エディタ | pleiades All in one var.4.7.0 |
プラグイン | addons.mozilla.org |
A - AtCoder社の給料
問題
問題文
AtCoder社の社員である青木さんの給料は以下のように決められます。
ある月に、青木さんがタスクをこなした数を x とします。
この月の給料は、1 から x までの整数が 1 面ずつに書かれた x 面ダイスを振って出た目 × 1 万円がもらえます。
ただし、このダイスは、どの面が出る確率も等しく 1⁄x です。
青木くんは、暮らしていくのに十分な給料が得られるかどうかが心配で、平均いくら程度給料がもらえるか調べたいです。
毎月、青木くんはちょうど N 個のタスクをこなすこととし、毎月の給料の平均値を求めるプログラムを書いてください。A問題では、提出した結果、全てのテストに対する判定がWAまたはREになってしまった場合のみ、質問タブにて可能な限りのトラブルシューティングを受け付けます。
提出結果のURLを添えて、お気軽にご質問ください。
また、ページ下部、「よくある質問」も、併せてご活用ください。
入力
入力は以下の形式で標準入力から与えられる。 N
- 1 行目には、整数で、青木くんが毎月こなすタスクの数 N (4≦N≦100) が与えられる。
出力
青木くんがもらえる毎月の給料(単位は円)の平均値を 1 行で出力せよ。
絶対誤差、または、相対誤差が 10−6 以下であれば許容される。
また、出力の末尾には改行を入れること。入力例 1
- 6
出力例 1
- 35000
- 1 万円から 6 万円がもらえる確率がそれぞれ 1⁄6 であるので、答えは
- 10000×(1⁄6)+20000×(1⁄6)+30000×(1⁄6)+40000×(1⁄6)+50000×(1⁄6)+60000×(1⁄6)=35000
- となります。
入力例 2
- 91
出力例 2
- 460000
見出しをクリックすると開きます。↓↓
回答
コードを書いたものは「Streamを使いたかった」という供述をしており…
成績
プログラムの実行時間およびメモリ使用量をまとめました。
実行時間 | メモリ使用量 |
---|---|
214 ms | 28116 KB |
Streamを使っているので実行時間が長いですね( ;∀;)
B - AtCoderトランプ
問題
問題文
AtCoder社では 1 人で行うトランプを使ったゲームが流行っています。
AtCoder社特製トランプでは、各カードにアルファベット小文字 1 文字(a
~z
)、または@
の文字が書かれています。
ゲームは以下の手順で行います。手順 1. で並べられた 2 つの列が指し示す2つの文字列与えられるので、適切に
- カードを同じ枚数ずつ 2 列に並べて文字列を 2 つ作ります。
@
のカードは、それぞれa
,t
,c
,o
,d
,e
,r
のどれかのカードと置き換えます。- 2 つの列が指し示す文字列が同じであれば勝ち、同じでなければ負けです。
@
を置き換えて、このゲームで勝つことができるかどうかを判定するプログラムを書いてください。入力
入力は以下の形式で標準入力から与えられる。 S T
- 1 行目には、1 列目のトランプが表す文字列 S が与えられる。
- 2 行目には、2 列目のトランプが表す文字列 T が与えられる。
- S、T ともにアルファベット小文字、および、
@
のみから構成されることが保証される。- S、T の文字数は等しく、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 行目には、講座動画の数を表す整数 N (1≦N≦100) と高橋くんが見ることのできる動画の数を表す整数 K (1≦K≦N) がスペース区切りで与えられる。
- 2 行目には、講座動画を配信している競技プログラマーのレートを表す整数 Ri (1≦Ri≦4,000) がスペース区切りで与えられる。
出力
高橋くんが達成できる最大レートを 1 行で出力せよ。
絶対誤差、または、相対誤差が 10−6 以下であれば許容される。
また、出力の末尾には改行を入れること。入力例 1
- 2 2
- 1000 1500
出力例 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
- 2 1
- 1000 1500
出力例 2
- 750
- このケースでは高橋くんは 1 個の講座動画しか見ることができません。
- レート 1500 の競技プログラマーの講座動画を見るのが最適です。
入力例 3
- 10 5
- 2604 2281 3204 2264 2200 2650 2229 2461 2439 2211
出力例 3
- 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×C(R 行 C 列)の区画に区切られており、各区画には、社員のデスク、サーバーラックのどちらかがあるか、何もない空きスペースのどれかです。
AtCoder社のある地域の冬は寒く、暖房代をできるだけ節約するため、社員室の必要なスペースのみを区切って使用することに決めました。
しかし、資材の問題で、区画に平行な長方形の領域で区切らなければいけません。
そこで、の 4 辺で囲まれた区画を壁で囲みました。
- デスク、または、サーバーラックのある最も上の行のすぐ上、
- デスク、または、サーバーラックのある最も下の行のすぐ下、
- デスク、または、サーバーラックのある最も左の列のすぐ左、
- デスク、または、サーバーラックのある最も右の列のすぐ右
すると壁で囲まれた領域は X×Y(X 行 Y 列)の区画になりました。
また、AtCoder社の社員室には、D 個のデスクと、L 個のサーバーラックがあります。
もともと、社員室に、どのようにデスクとサーバーラックの配置されていたのか、考えうるパターン数を 1000000007=109+7 で割った余りを求めるプログラムを書いてください。入力
入力は以下の形式で標準入力から与えられる。 R C X Y D L
- 1 行目には、AtCoder社の社員室の区画の行数、列数を表す整数 R, C (1≦R,C≦30) がスペース区切りで与えられる。
- 2 行目には、社員室の壁に囲まれた部分の区画の行数、列数を表す整数 X, Y (1≦X≦R, 1≦Y≦C) がスペース区切りで与えられる。
- 3 行目には、社員室にある社員のデスクの数、サーバーラックの数を表す整数 D, L (D,L≧0, 1≦D+L≦X×Y) がスペース区切りで与えられる。
出力
社員室にどのようにデスクとサーバーラックの配置されていたのか、考えうるパターン数を 1000000007=109+7 で割った余りを 1 行で出力せよ。
また、出力の末尾には改行を入れること。部分点
D+L=X×Y の場合のテストケースに全て正解した場合、101 点満点中の 100 点が与えられる。
満点解法は非常に難しいので、部分点を確実に取ることから考えましょう。入力例 1
- 3 2
- 2 2
- 2 2
出力例 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
- 4 5
- 3 1
- 3 0
出力例 2
- 10
- このケースは D+L=X×Y を満たすため、部分点のテストケースに含まれる可能性があります。
入力例 3
- 23 18
- 15 13
- 100 95
出力例 3
- 364527243
- このケースは D+L=X×Y を満たすため、部分点のテストケースに含まれる可能性があります。
- 社員室の配置パターンは 145180660592914517790287604376765671109248284280228061640640 通りで、これを 109+7 で割った余りである 364527243 を出力してください。
入力例 4
- 30 30
- 24 22
- 145 132
出力例 4
- 976668549
- このケースは D+L=X×Y を満たさないため、部分点のテストケースに含まれることはありません。
- 無理に正解しようとせず、余裕のある人だけ挑戦してみてください。
見出しをクリックすると開きます。↓↓
回答
難しいですね… ABC3回目にして部分点というのを始めてみてとても驚きました。私は120分では解けませんでした。ただ、さらに1時間かけて部分点まで取れたので満足です。
部分点しかもらえない回答です。
部分点のみの場合の大体のアルゴリズムは30分くらいかかりましたが、何とかわかりました。
XYの範囲内におけるdとlの組み合わせ×(縦におけるXYの移動範囲)×(横におけるXYの移動範囲)
ですが、nC1=n
なので、
ですね。実際はmod1000000007
をとるわけですが。
入力例1の場合
R*Cの中にあるXYの箱の配置が2通りあり、XYの箱の中の組み合わせが4C2
ですね。
入力例2の場合
入力例2の場合はXYの組み合わせが1なので、縦×横の計算のみですね。
入力例3の場合
ちょっと桁数がまずいですねぇ…さすがに図を描いている余裕はないので式だけ書きます。
お客様の中に195C95
の答えが分かる方、いらっしゃいませんか?w
ちなみに、答えは
ですって奥さん!桁数がやばいw
恐らく、プログラムを実装する際にmod1000000007
を使うんでしょうね。計算途中でもmodを使わないと桁があふれて答えが合わなくなってしまいます。
のような暗号でも使われている(?)分配公式(?)を使うんでしょうけど、いかんせん詳しくなくて分数の場合などにどうすればいいのかわかりませんでした。
BigDecimalを使って実装する
注:邪道です
Javaユーザーの皆さん!朗報です!BigDecimal
が使えますよ!
BigDecimalとは
BigDecimal
はNumber
クラスのサブクラスでmath
パッケージに属しているクラスです。
変更が不可能な、任意精度の符号付き10進数です。BigDecimalは、任意精度のスケールなしの整数値と、32ビット整数のスケールで構成されます。0または正の場合、スケールは小数点以下の桁数です。負の場合、スケールなしの数値に、スケールの正負を逆にした値を指数とする10の累乗を乗算します。つまり、BigDecimalで表される数値は(unscaledValue×10^-scale)です2。
とんでもない大きな桁数を正確に計算できますという便利なクラスです。もちろん、int
やdouble
といったプリミティブよりははるかに計算速度が遅くなるらしいです。最終手段ですね。
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
このままだとプログラムを組む際に混乱するので、下のように直しました。
この表から
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
はじめに
私はプログラムやプログラミングコンテストに対して何ら知識はありません。私が書くコードは、性能的にも優れているものではありません。私自身が考え、学んでいく過程でできたコードです。無駄がありますが、お許しください。また、改善等の指導があればコメント欄に記入していただけると助かります。
公式URL
使用したもの等
名称 | 使用したもの |
---|---|
言語 | JavaSE8 |
エディタ | pleiades All in one var.4.7.0 |
プラグイン | addons.mozilla.org |
A - 正直者
略
B - 罠
問題
問題文
B問題のリジャッジ(再採点)が終了しました。21: 50
B問題のテストケースにミスがあったので、提出されたコードをリジャッジ(再採点)してます。21: 40
神の恵みで財産を築いた高橋くんですが、なんとそこには罠がありました。
神は、高橋くんの発した言葉から母音a
、i
、u
、e
、o
を全て盗んでいったのです。
高橋くんが発した言葉を表す文字列 W が与えられるので、周囲の人が聞く言葉を表す文字列を出力するプログラムを書いてください。
入力
入力は以下の形式で標準入力から与えられる。 W
- 1 行目には、高橋くんの発した言葉を表す文字列 W が与えられる。
- W の長さ |W| は 1≦|W|≦30 を満たす。
- W は半角英小文字(
a
からz
まで)のみで構成される。- W には母音以外の文字が少なくとも 1 文字含まれることが保証されている。
出力
W から母音を全て除いた文字列を 1 行で出力してください。
また、出力の末尾には改行を入れること。
入力例 1
- chokudai
出力例 1
- chkd
chokudai
からa
、i
、u
、e
、o
を除くとchkd
になります入力例 2
- okanemochi
出力例 2
- knmch
okanemochi
からa
、i
、u
、e
、o
を除くとknmch
になります
入力例 3
- aoki
出力例 3
- k
aoki
からa
、i
、u
、e
、o
を除くとk
になります- このように、与えられる文字列 W には母音以外の文字が少なくとも 1 文字含まれます
入力例 4
- mazushii
出力例 4
- 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 つの点 A, B, C が与えられます。
少しでも早く母音を取り戻すために、三角形 ABC の面積を出力するプログラムを書いてください。
入力
入力は以下の形式で標準入力から与えられる。 xa ya xb yb xc yc
- 1 行目には、3 点 A, B, C の座標が半角空白区切りで与えられる。
- 点 A の座標が (xa, ya)、点 B の座標が (xb, yb)、点 C の座標が (xc, yc) であることを表す。
- 各座標の値 xa, ya, xb, yb, xc, yc は −1,000 以上 1,000 以下の整数であることが保証されている。
- 3 点 A, B, C が同一直線上に配置されていることはない。
出力
三角形 ABC の面積を 1 行で出力してください。
また、出力の末尾には改行を入れること。
出力は絶対誤差が 10−2 以下であれば許容される。
ヒント
3 点 (0,0), (a,b), (c,d) で構成される三角形の面積は、|ad−bc|⁄2 となります。
(このヒントは、コンテスト開始 1 時間後に公開されたものです。)
入力例 1
- 1 0 3 0 2 5
出力例 1
- 5.0
入力例 2
- -1 -2 3 4 5 6
出力例 2
- 2.0
入力例 3
- 298 520 903 520 4 663
出力例 3
- 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
に対して
これで求めることができます。懐かしい!その公式のままプログラムを書いてもいいですが、辺abc
を求めるときに平方根を取ります。平方根はできるだけ最後にした方が、計算の誤差が少なくなるため変形した公式を使いましょう。
この公式ですと、abc
がそれぞれ2乗4乗されてますね。距離を求めるときに平方根を取らないでよいという事ですね。
JavaにはPoint2D::distanceSq(Point2D)
というメソッドがあります3。距離を求める計算の途中で平方根を取らない値を返してくれます。
これを使うことで、計算の最後のみに平方根をとるようにできます。
1点を原点にずらす
問題のヒントにもあるように、原点、他2点から作られる三角形の面積は
で求まるようです。そんな便利なのがあるんですね!なんだか行列の計算を思い出します。
という事で、与えられた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 個の人間関係 (x, y) が存在します。
人間関係 (x, y) とは、議員 x と議員 y が知り合いであることを意味します。
高橋くんは N 人の議員から何人かを選んで派閥を作ろうと企んでいます。
派閥に含まれるすべての議員は互いに知り合いでなければなりません。
高橋くんが作成することができる最大の派閥に属する議員数を求めるプログラムを書いてください。
入力
入力は以下の形式で標準入力から与えられる。 N M x1 y1 x2 y2 : xM yM
- 1 行目には、高橋くん以外の国会議員の数 N (1≦N≦12) と、人間関係の数 M (0≦M≦N(N−1)⁄2) が半角空白区切りで与えられる。
- 2 行目から M+1 行目までの M 行で、人間関係が与えられる。
- 各議員は 1 から N までの整数で番号がつけられている。
- 2 行目を基準とした第 i (1≦i≦M) 行において、議員 xi と議員 yi は知り合いであることを意味する。
- xi と yi はともに整数で、 1≦xi<yi≦N を満たす。
- i≠j のとき、(xi, yi)≠(xj, yj) であることが保証されている。
出力
高橋くんが作成することができる最大の派閥に属する議員数を 1 行で出力してください。
また、出力の末尾には改行を入れること。
入力例 1
- 5 3
- 1 2
- 2 3
- 1 3
- 1 行目:5 人の議員と 3 つの人間関係が存在する。
- 2 行目:議員 1 と議員 2 は知り合いである。
- 3 行目:議員 2 と議員 3 は知り合いである。
- 4 行目:議員 1 と議員 3 は知り合いである。
出力例 1
- 3
- 議員 1、議員 2、議員 3 は互いに知り合いなので、この 3 人は派閥を構成することができる。
入力例 2
- 5 3
- 1 2
- 2 3
- 3 4
出力例 2
- 2
- 議員数 2 の派閥として
の 3 通りが考えられます。
- 議員 1 と議員 2 の派閥
- 議員 2 と議員 3 の派閥
- 議員 3 と議員 4 の派閥
入力例 3
- 7 9
- 1 2
- 1 3
- 2 3
- 4 5
- 4 6
- 4 7
- 5 6
- 5 7
- 6 7
出力例 3
- 4
入力例 4
- 12 0
出力例 4
- 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の場合です。
こんな風に配列を用意しておけば、どんなに人間関係が増えても配列の大きさに影響はありません。
人間関係(x,y)
が与えられた場合、この配列の[x-1][y-1]
と[y-1][x-1]
に○(true)を入れてあげるだけです。
人間関係の配列を作る場合、2次元配列はできるだけやめましょう。私の経験不足なだけかもしれませんが、2次元配列でいろいろと処理をしようとすると、頭の中が混乱してしまいます。下のように配列の行をビットとして考え、intの数値配列として保存するのがいいと思います。
- 対戦表の行を検索する場合はint[i]などのアクセス
- 対戦表の列を検索する場合はビット演算によるアクセス
という風に分けることで混乱を最小限に抑えました。
またビット演算&
を使うことで、人間関係で共通の部分を簡単に求めることができます。
例えば、人間関係1,2,3の共通の関係を求める場合は
7(111) & int[0] & int[1] & int[2] = 7(111)
と求めることができます。
ポイント2. 組み合わせをビット演算で表現する
問題の後半高橋くんが作成することができる最大の派閥に属する議員数を求めるプログラムを書いてください。
の部分を求める際に、組み合わせを考えなくてはいけません。
この数だけ、可能性を考慮する必要があります。私にはよくわからなかったので、ビット演算を使って組み合わせを表現しました。
先ほどの例があるとします。
人間1
の人間関係で共通している人数を求めるとします。
人間
1
の人間関係を調べる。
人間1
の人間関係は7(111)です。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のコンテストがあるらしいので、参加したいと思います。(前回あったの知らなかった(´;ω;`))
スター、ブックマーク、読者登録等ありがとうございます!いつも励みになってます!
ブログ巡りもまだなので明日したいと思います。
またね('ω')ノ
次のタグをアニメーションで表示非表示にできるようにしました
こんにちは鬱太郎です。先日作ったnext-hidden
を改良しました。良ければ見て言って下さい!
そう!アニメーションで動作をできるようにしました。
前の記事
改善のコメントありがとうございます。
要件見た感じもっとコンパクトにできそうな気がするけど気のせいかも
ghostbassさん
コメントありがとうございます!確かにそうですね!つぎのkathewさんのコメントを元にコードを改良したら確かにコンパクトになりました。でも要件追加して、コードが伸びましたww
eachで回さなくて大丈夫だよ。jQueryでイベントを仕込んだらセレクタにヒットする全ての要素にイベントが適用されるよ/初期状態で非表示化するのは$(セレクタ).next().hide() おすすめ
kathewさん
コメントありがとうございます!そうなんですね!教えていただいてありがとうございます!私はjQueryについて詳しくなくて、逆引きで調べて作って動けばOKみたいな感じでしたので本当に助かりました。
コメントから学んだことを書いていきますね。ありがとうございます。
end()を使ってメソッドチェーンが書ける
end()
はjQueryのメソッドの一つです。一つ前の選択状態に戻すという効果があります。
$(".next-hidden").next().hide();
は、hide()
のところでは$(".next-hidden).next()
を選択しています。end()
を付けることで、一つ前の$(".next-hidden")
の選択状態に戻すことができます。
$(".next-hidden").next().hide().end().click(function(){ $(this).next().toggle(); });
こんな感じにつなげて記述することができます。
これをメソッドチェーンと言うらしいです。
セレクタ.eachは必須じゃない
私が逆引きでいろいろとjQueryについて調べていた時に、セレクタ.eachで処理しているコード例が多かったので初めて知りました。nullの場合とかはエラーを吐かないんですね。
今回のコードのように中にif文とか書いてる場合はさすがにeachでいいのかな?
今回の改善の流れ
コメントで指摘を受けて、いろいろとjQueryについて調べているときに、
ん・・?
.toggle() 表示、非表示を切り替える。
デデーン!
そんな便利なものあったのか!
if($(this).next().is(":visible")){ $(this).next().hide(); }else{ $(this).next().show(); }
これが
$(this).next().toggle();
一行に!
そして、ふと上を見ると?
アニメーション…だと…?
という事で、next-hidden
はコードがシンプルになった途端にアニメーションも追加できる要件が追加されましたw
参考サイト
動作デモ
前回の動作
前回の動作に加え、新たに二つの動作が追加されました。
スライド表示非表示
jQueryのslideToggle()
を使った動作を追加しました。
フェードイン・アウト表示非表示
jQueryのfadeToggle()
を使った動作を追加しました。
ソースコードと使用例
実際の使い方を説明していきます。
1.スクリプトコードを記事に張りつける
下記コードを使用する記事の中に記述してください。そのまま記法の方はHTML編集タグから追加できます。先頭の1行はjQueryの読み込みコードなので、既にヘッダー等に同様の記述がある場合は不要です。
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script> $(function(){ var classSelector = ".next-hidden"; var attrForNext = "data-display"; var attrNextClass = "data-next-class"; var attrType = "data-type"; var attrTime = "data-time"; $(classSelector).next().hide().end().each(function(){ if($(this).next().length){ var time = $(this).attr(attrTime); var toggleArgument = (isNaN(time))?time:Number(time); switch($(this).attr(attrType)){ case "slide": $(this).click(function(){ $(this).next().slideToggle(toggleArgument); }); break; case "fade": $(this).click(function(){ $(this).next().fadeToggle(toggleArgument); }); break; default: $(this).click(function(){ $(this).next().toggle(toggleArgument); }); break; } $(this).next().css("display",$(this).attr(attrForNext)).addClass($(this).attr(attrNextClass)); } }); }) </script>
2.イベントを登録したいタグにクラス名や属性を追加する
ソースコードをコピペした後はタグにクラス名を付けるだけで機能します。
そのまま記法の方は、HTML編集ページから、Markdown記法の方は直接記述できます。
通常の動作
class="next-hidden"
を記述することで、そのタグに次のタグを表示非表示にさせるイベントを追加します。このとき、デフォルトで次のタグの要素を非表示にします。
<p class="next-hidden"><a>ここをクリック</a></p> <p>タグに<code>class="next-hidden"</code>を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。</p>
タグにclass="next-hidden"
を追加することで、クリックすると次のタグを表示非表示させるイベントを追加できます。
スライドしつつ表示非表示にさせる
class="next-hidden"
を記述し、属性data-type="slide"
を追記することで、スライド動作を有効にします。
<p class="next-hidden" data-type="slide"><a>ここをクリック</a></p> <p>タグに<code>class="next-hidden" data-type="slide"</code>を追加することで、クリックすると次のタグをスライド動作で表示非表示させるイベントを追加できます。</p>
タグにclass="next-hidden" data-type="slide"
を追加することで、クリックすると次のタグをスライド動作で表示非表示させるイベントを追加できます。
フェードしつつ表示非表示にさせる
class="next-hidden"
を記述し、属性data-type="fade"
を追記することで、フェード動作を有効にします。
<p class="next-hidden" data-type="fade"><a>ここをクリック</a></p> <p>タグに<code>class="next-hidden" data-type="fade"</code>を追加することで、クリックすると次のタグをフェード動作で表示非表示させるイベントを追加できます。</p>
タグにclass="next-hidden" data-type="fade"
を追加することで、クリックすると次のタグをフェード動作で表示非表示させるイベントを追加できます。
オプション
最初に次のタグを表示しておきたい場合
さらにdata-display="block"
という属性を追記することで、初期状態を表示状態にすることができます。通常の動作、スライド動作、フェード動作のすべてに追記することができます。次の例はフェード動作に初期状態を表示させる属性を追加します。
<p class="next-hidden" data-type="fade" data-display="block"><a>ここをクリック</a></p> <p>タグに<code>data-display="block"</code>を追記することで、クリックすると次のタグを表示非表示させるイベントを追加できます。また、次のタグは最初から表示されます。</p>
タグにdata-display="block"
を追記することで、クリックすると次のタグを表示非表示させるイベントを追加できます。また、次のタグは最初から表示されます。
次のタグにクラスを追加したい場合
さらにdata-next-class="hogehoge"
という属性を追記することで、次のタグにclass="hogehoge"
を追加します。もちろんhogehoge
の部分には好きなクラス名を記述できます。
これも動作に関わらず追記することができます。次の例はスライド動作にクラス名を追加します。
<style>.hogehoge{background-color: gray;}</style> <p class="next-hidden" data-type="slide" data-next-class="hogehoge"><a>ここをクリック</a></p> <p>タグに<code>data-next-class="hogehoge"</code>を追加することで、次のタグにクラス名<code>hogehoge</code>を追加できます。この例ではCSSで背景を変更しています。</p>
タグにdata-next-class="hogehoge"
を追加することで、次のタグにクラス名hogehoge
を追加できます。この例ではCSSで背景を変更しています。
アニメーション動作にかかる秒数を指定したい場合
全ての動作にかかる時間をミリ秒単位で指定できます。例えば、data-time="3000"
を追記することで、表示非表示に掛かる動作を3秒に指定できます。
通常の動作で3秒
<p class="next-hidden" data-time="3000"><a>ここをクリック</a></p> <p>タグに<code>data-time="3000"</code>を追記することで、クリックすると3秒かけて次のタグを表示非表示させるイベントを追加できます。</p>
タグにdata-time="3000"
を追記することで、クリックすると3秒かけて次のタグを表示非表示させるイベントを追加できます。
スライド動作で3秒
<p class="next-hidden" data-type="slide" data-time="3000"><a>ここをクリック</a></p> <p>タグに<code>data-time="3000"</code>を追記することで、クリックすると次のタグをスライド動作で3秒かけて表示非表示させるイベントを追加できます。</p>
タグにdata-time="3000"
を追記することで、クリックすると次のタグをスライド動作で3秒かけて表示非表示させるイベントを追加できます。
フェード動作で3秒
<p class="next-hidden" data-type="fade" data-time="3000"><a>ここをクリック</a></p> <p>タグに<code>data-time="3000"</code>を追記することで、クリックすると次のタグをフェード動作で3秒かけて表示非表示させるイベントを追加できます。</p>
タグにdata-time="3000"
を追記することで、クリックすると次のタグをフェード動作で3秒かけて表示非表示させるイベントを追加できます。
動作のまとめ
class="next-hidden"
で機能を追加data-type="slide"
でスライド動作data-type="fade"
でフェード動作data-type
を記述しない、もしくは上記2つ以外の値の場合は通常の動作- 読み込み時はデフォルトで次のタグを非表示にします。
data-display="block"
で読み込み時に表示 data-next-class="..."
で次のタグにクラス名を指定data-time=...
で表示非表示にそれぞれかかる秒数を指定できる。1秒の場合はdata-time="1000"
過去の記事も参考に
過去の記事で書いてあることはこの改良型でも動作します。
終わりに
次のタグをアニメーションで表示非表示にできるようにしました!
アニメーションの選択肢が3倍に増えたので3倍遊べますよ!ふふふ(*'ω'*)
スターやブクマ、コメント、読者登録ありがとうございます!すごい励みになってます。
またね('ω')ノ
立憲民主党のフォロワーは英数字のみの名前率が高い! 各政党のフォロワー情報を比較してみた
こんにちは鬱太郎です。今日もまだ比較中なので、そのデータを貼り付けます。
終わらない(´;ω;`)
ソースコード
nameプロパティを調べる
nameプロパティはTwitterの名前を意味します。よく変えたりする方も多いのではないでしょうか?
名前の文字列のサイズで比較してみる
名前のサイズで比較してみます。lengthでグループ分けですね!
うわ・・・線が多すぎてどれがどれだかわかりませんね(´;ω;`)
でも4文字の名前の人が1番多いというのが分かりますね!これは日本語の名前が4文字が多いからでしょうか?こういったデータを見ると和みますね!(私だけかな?)
しいて言えば20文字で急にぴょんとデータが跳ねているのが気になるところです。
そのままでは見にくいので、平均からの差のグラフを作りました。
ますますわからん・・・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 |
各政党別の文字列の長さの詳細です。データを出してみたものの…わからん!(*'ω'*)
文字列の長さ | 立民 | 民進 | 社民 | 幸実 | 共産 |
---|---|---|---|---|---|
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% |
文字列の長さ | 自民 | 希望 | 公明 | 日本 | 維新 | 自由 |
---|---|---|---|---|---|---|
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_\-]+$
と書けますね。
党名 | スクリーン名 | 英数字のフォロワー | フォロワー数 | 英数字率 | 偏差値 |
---|---|---|---|---|---|
立民 | 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 |
立憲民主党が英数字の名前を付けているフォロワーが多いという結果になりました。これが、件の疑惑の元といえるんじゃないですかね。英数字のアカウントが多いという噂は聞いていましたが、本当に他党に比べて多いことが分かりました。
逆に幸福実現党は英数字の名前のフォロワーが少ないという結果が出ました。
名前に@を付けてるフォロワー
Twitterの名前を名前@状況
などのように使っている方をよく見かけますね。そんな人を検索します。
正規表現で
^[^@]+@[^@]+$
と書けますね。
党名 | スクリーン名 | 名前に@を使用 | フォロワー数 | 名前に@使用率 | 偏差値 |
---|---|---|---|---|---|
幸実 | 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と少ないものの、先ほどの英数字の使用率が低いことも合わせると、フォロワーの(生身の人間としての)質が高いという推測ができますね。
逆にフォロワー数が多い政党ほど、質が低いという事がいえるのかも…(不安げ)
まあ、名前からすべてわかるわけないですけどね!
終わりに
ここまで読んでくださってありがとうございます!
なんかもう…疲れた…
読者さんのブログを見るのもをくれてしまって申し訳ないです。でも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を取得してからユーザーの情報を取得する間に、アカウント削除などの理由から取れないユーザー情報があったようです。
ユーザー情報の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値というのはtrue
とfalse
で表現する状態を表す値です。true
ならyes
、false
なら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値だとこんな感じに楽にできますね!
終わりに
ここまで読んでくださってありがとうございます!
Twitterのユーザー情報の取得が完了しました!これからデータを分析していきたいと思います。もしかしたら、2・3日かかるかもしれません。いいデータ取れるといいんですが…
またね('ω')ノ