日々精進

aikoと旅行とプログラミング

iTunesの再生回数をAppleScript + Ruby + gnuplotで表示してみる

AppleScriptRubyを使って, iTunesの再生回数を取得しグラフ化してみた.
 やろうと思ったきっかけは, 自分がaikoの曲をどれだけ聞いているか知りたかったから. よって, このあと出て来る例はすべてaikoを検索している.

developer.apple.com

AppleScriptで曲と再生回数を取得

AppleScriptなにもわからない. 雰囲気でAppleScriptを書いている.

tell application "iTunes"
        # 変数はsetで宣言
    set lst to {}
    
        # repeat with 変数 in オブジェクト(foreach)
    repeat with t in (file tracks whose artist contains "aiko")
        copy ((name of t as string) & " " & played count of t as string) to the end of lst
    end repeat
    
    return lst
end tell

分からなさすぎて検索しまくった. これを実行すると, 以下のような出力を得られる.

f:id:bath_poo:20170703140028p:plain

それっぽい結果が出ている. このスクリプトを次に作るrbファイルと同じ階層においておく.

Rubyでデータを加工

AppleScript辛い…しか言えない体になっていたので, ここでRubyにバトンタッチ.

コマンドを実行

とりあえず先ほどのAppleScriptを実行しないと話にならないので, ``を使って実行し結果を得る.

# scriptの実行
elements = `osascript itunes.scpt`.chomp.split(",").map{ |item| item.strip }
曲名ごとにカウントする

 aikoはアルバムを14枚(ベストアルバム込み), シングルも36枚ある. もちろん曲の被りがあるので, それは同じものとしてカウントしたい.
 そこでHashを使ってカウントする.

# 曲名ごとにカウント
hash = Hash.new(0)
elements.each do |elem|
  next if (elem.index("instrumental"))
  len = elem.rindex(" ")
  name = elem[0..len]
  time = elem[len..elem.length]
  hash[name] += time.to_i;
end

今回instrumentalはカウントしないことにしたので, 以下のように弾く処理を書いている.

next if (elem.index("instrumental"))

 また, “Do you think about me?"や"be master of life"のように空白が1つ以上出現する文字列もあるため, rindexで一番最後の空白を基準に曲名と回数を分割することにした.

len = elem.rindex(" ")
name = elem[0..len]
time = elem[len..elem.length]

そして, その名前をkeyとして回数を加算する.

hash[name] += time.to_i;
再生回数でソートする

 先程カウントしたハッシュをソートする必要がある. HashのSortは[key, value] を要素とする配列の配列に変換して,それをソー トした配列を返す。

# 再生数でソート
songs = hash.sort do |a, b|
  b[1] <=> a[1]
end

gnuplotで描画

 画面に文字列として出力するだけではわかりにくいので, gnuplotを使って表示することにした. ここではgnuplotのインストールについては省略する.

ラベルと回数を取得

ラベルと回数をそれぞれ別の配列として持たないといけないので, それ用の配列を作る.

# Gnuplot用にラベルと回数を別々に配列へ格納
labels = []
times = []
songs.each_with_index do |item, idx|
  labels << "\"#{item[0]}\""
  times << item[1]
  break if idx > 50
end

あまりに多いと格納できないので, 上位50曲程度で打ち切っている.

描画する

以下のgemを使ってRubyから描画する.

gnuplot | RubyGems.org | your community gem host

# 描画
Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "aqua font 'ヒラギノ角ゴ Pro W3,10'"
    plot.title  "視聴回数"
    plot.yrange "[0:300]"
    plot.ylabel "再生回数"
    plot.bmargin "8"
    plot.style "fill solid border -1"
    plot.xtics "rotate by -90"
    plot.unset "key"

    plot.data << Gnuplot::DataSet.new([labels, times]) do |ds|
      ds.using = "2:xtic(1)"
      ds.with = 'boxes lc rgb "orange"'
      ds.title = "再生回数"
    end
  end
end

 本当は, set terminal png enhanced font ‘GothicBBB-Medium-EUC-H, 10'のような感じにしたかったのだけどできなかったので, terminalに出してスクリーンショットに妥協した.
 最終的なソースコード以下のようになる.

require "gnuplot"

# scriptの実行
elements = `osascript itunes.scpt`.chomp.split(",").map{ |item| item.strip }

# 曲名ごとにカウント
hash = Hash.new(0)
elements.each do |elem|
  next if (elem.index("instrumental"))
  len = elem.rindex(" ")
  name = elem[0..len]
  time = elem[len..elem.length]
  hash[name] += time.to_i;
end

# 再生数でソート
songs = hash.sort do |a, b|
  b[1] <=> a[1]
end

# Gnuplot用にラベルと回数を別々に配列へ格納
labels = []
times = []
songs.each_with_index do |item, idx|
  labels << "\"#{item[0]}\""
  times << item[1]
  break if idx > 50
end

# 描画
Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "aqua font 'ヒラギノ角ゴ Pro W3,10'"
    plot.title  "視聴回数"
    plot.yrange "[0:300]"
    plot.ylabel "再生回数"
    plot.bmargin "8"
    plot.style "fill solid border -1"
    plot.xtics "rotate by -90"
    plot.unset "key"

    plot.data << Gnuplot::DataSet.new([labels, times]) do |ds|
      ds.using = "2:xtic(1)"
      ds.with = 'boxes lc rgb "orange"'
      ds.title = "再生回数"
    end
  end
end

ここまで書いたらGemfileを書く.

$ bundle init

bundle initを実行してGemfileを作る. Gemfileは

# frozen_string_literal: true
source "https://rubygems.org"

gem 'gnuplot'

とする. ここまできたらinstallをする.

$ bundle install --path vendor/bundle

これでインストールされるので, いよいよ実行.

$ bundle exec ruby ***.rb

実行結果(曲単位)

実行結果は次のようになった.

f:id:bath_poo:20170703143619p:plain

ランキングを見てみると, 上位5曲は以下のようになっていた.

  1. 恋のスーパーボール
  2. シアワセ
  3. 夢見る隙間
  4. もっと
  5. 花火

 意外とbe master of lifeとか聞いていないんだなという気持ちになっている. 1位が恋のスーパーボールなのは, いっとき狂ったように聞いていた時があったので適当. 夢見る隙間が3位にいるのは意外すぎる. ちなみに6位は何時何分なので, 発売時期を考慮するとMay Dreamは割りと聞いているということがわかった.
 これだけでは面白くないので, 先ほどのスクリプトを改造してアルバムごとの回数を見てみる.

アルバムごとに集計

AppleScriptを以下のように変更し(name→album)

tell application "iTunes"
    set lst to {}
    
    repeat with t in (file tracks whose artist contains "aiko")
        copy ((album of t as string) & " " & played count of t as string) to the end of lst
    end repeat
    
    return lst
end tell

集計部分のソースコード(Ruby)を多少変更した.

require "gnuplot"

# scriptの実行
elements = `osascript itunes.scpt`.chomp.split(",").map{ |item| item.strip }

# 曲名ごとにカウント
hash = Hash.new(0)
albums = ["小さな丸い好日", "桜の木の下", "夏服", "秋 そばにいるよ", "暁のラブレター", "夢の中のまっすぐな道", "彼女", "秘密", "BABY", "まとめ I", "まとめ II", "時のシルエット", "泡のような愛だった", "May Dream"]
elements.each do |elem|
  next if (elem.index("instrumental"))
  len = elem.rindex(" ")
  name = elem[0..len-1]
  time = elem[len+1..elem.length] 
  if albums.include?(name) then # アルバムであるかどうか
    hash[name] += time.to_i;
  end
end

# 再生数でソート
songs = hash.sort do |a, b|
  b[1] <=> a[1]
end

# グラフの上限を設定
# 1400なら2000にするなど.
tmp = songs[0][1].to_s
max_val = tmp[0].to_i + 1;
max_val *= (10 ** (tmp.size - 1))

# Gnuplot用にラベルと回数を別々に配列へ格納
labels = []
times = []
songs.each_with_index do |item, idx|
  labels << "\"#{item[0]}\""
  times << item[1]
  break if idx > 50
end

# 描画
Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "aqua font 'ヒラギノ角ゴ Pro W3,10'"
    plot.title  "視聴回数"
    plot.yrange "[0:#{max_val}]"
    plot.ylabel "再生回数"
    plot.bmargin "8"
    plot.style "fill solid border -1"
    plot.xtics "rotate by -90"
    plot.unset "key"

    plot.data << Gnuplot::DataSet.new([labels, times]) do |ds|
      ds.using = "2:xtic(1)"
      ds.with = 'boxes lc rgb "orange"'
      ds.title = "再生回数"
    end
  end
end

まとめⅠとⅡが微妙に違って集計されていなかった. つらいね.

実行結果(アルバム単位)

f:id:bath_poo:20170703151533p:plain  まとめ2枚と時のシルエット, May Dreamがずば抜けている. 確かによく聞いてるし, なによりまとめから入った人間なのでそれはそう.
 暁のラブレター全然聞いていないことに気づく. iTunesのカウントは, おそらく最後まで聞いた曲を1回とカウントしてるので, 終わったと思って飛ばしてしまうと1回とカウントされてないのではないだろうか. 彼の落書きとか結構聞いてると思うのだが…  先日書いたブログでも, 割と力を入れて書いたところが上位に来ているのでそれだけ聞いていたんだと実感した. グラフィカルに見られるのはいいことだ.

muttan1203.hatenablog.com

 あまりにも汎用性の低いコードすぎるので, albumでまとめるのか全部含めるのかなどなど色々更新していきたい.
 あとaikoはいいぞ.

OpenCVでボロノイ分割とドロネー分割

OpenCVを使ってボロノイ分割とドロネー分割をした.

実行環境

特徴点の抽出

画像から特徴点を取り出すのに, Shi-Tomashiのコーナー検出法を利用する.

void goodFeaturesToTrack(InputArray image,       // 入力画像  
             OutputArray corners,      // 検出されたコーナー  
             int maxCorners,         // コーナーの最大数  
             double qualityLevel,      // クオリティレベル(0.0~1.0)
             double minDistance,       // コーナー間の最小ユーグリット距離
             InputArray mask=noArray(),
             int blockSize=3,   
             bool useHarrisDetector=false,   
             double k=0.04 )

具体的には

// Shi-Tomasi Corner Detector
int maxCorners = 0;
vector<Point2f> corners;
goodFeaturesToTrack(img, corners, maxCorners, 0.01, 50);

のようにして行う.

Subdiv2Dの初期化

分割を行うために必要なSubdiv2Dを初期化する.

Mat out = imread(filename); // 出力用
Size size = out.size();
Rect rect(0, 0, size.width, size.height);
Subdiv2D subdiv(rect);

ボロノイ図を書く

ボロノイ分割, ドロネー分割を行う前に, 先程取得した点をSubdiv2Dに追加する.

subdiv.insert(corners);

ボロノイ図を書くには, getVoronoiFacetListを使う.

void cv::Subdiv2D::getVoronoiFacetList(const std::vector< int > &idx,
                                       std::vector< std::vector< Point2f > > &facetList,
                                       std::vector< Point2f > &facetCenters 
                                      ) 

このメソッドを呼び出すと, facetListにベクトルの集合が格納される. 今回はdraw_voronoiという関数を定義した.

void draw_voronoi(Mat &img, Subdiv2D &subdiv){
    vector<vector<Point2f> > facetList;
    vector<Point2f> facetCenters;
    subdiv.getVoronoiFacetList(vector<int>(), facetList, facetCenters);

    for(auto &trig : facetList){
        vector<Point2f>::iterator it = trig.begin();
        Point2f p1 = *it;
        it++;
        while(it != trig.end()){
            Point2f p2 = *it;
            line(img, p1, p2, Scalar(255, 255, 255));
            p1 = p2;
            it++;
        }
    }
}

もうちょっときれいにかけないものか.

ドロネー図を書く

方法としては2つ存在していて,

  1. getEdgeListメソッドですべての辺を取得する方法
  2. getTriangleListメソッドで三角形を取得する方法

が存在する. 今回はgetEdgeListを使う.

void cv::Subdiv2D::getEdgeList(std::vector< Vec4f > &edgeList)const

引数として与えたedgeListに辺が格納される.(変数名のとおりだが)今回は, draw_delaunayという関数を定義した.

void draw_delaunay(Mat &img, Subdiv2D &subdiv){
    vector<Vec4f> edges;
    subdiv.getEdgeList(edges);

    for(auto &edge:edges){
        line(img, Point2f(edge[0], edge[1]), Point2f(edge[2], edge[3]), Scalar(0, 255, 0));
    }
}

ソースコード

以下に今回使用したソースコードを示す.

#include <iostream>
#include <random>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

void draw_point(Mat& img, Point2d p, Scalar color){
    circle(img, p, 5, color, -1);
}

void draw_delaunay(Mat &img, Subdiv2D &subdiv){
    vector<Vec4f> edges;
    subdiv.getEdgeList(edges);

    for(auto &edge:edges){
        line(img, Point2f(edge[0], edge[1]), Point2f(edge[2], edge[3]), Scalar(0, 255, 0));
    }
}

void draw_voronoi(Mat &img, Subdiv2D &subdiv){
    vector<vector<Point2f> > facetList;
    vector<Point2f> facetCenters;
    subdiv.getVoronoiFacetList(vector<int>(), facetList, facetCenters);

    for(auto &trig : facetList){
        vector<Point2f>::iterator it = trig.begin();
        Point2f p1 = *it;
        it++;
        while(it != trig.end()){
            Point2f p2 = *it;
            line(img, p1, p2, Scalar(255, 255, 255));
            p1 = p2;
            it++;
        }
    }
}

int main() {
    string filename = "ファイルのパス";

    cout << CV_VERSION << endl;
    // 対象画像をグレイスケールで読み込み
    Mat img = imread(filename, IMREAD_GRAYSCALE);


    // Shi-Tomasi Corner Detector
    int maxCorners = 0;
    vector<Point2f> corners;
    goodFeaturesToTrack(img, corners, maxCorners, 0.01, 50);

    // 出力用ファイルを作成
    Mat out = imread(filename);
    for(auto &point : corners){
        draw_point(out, point, Scalar(0,0,255));
    }

    // Delaunay分割のためのSubdiv2Dを初期化
    Size size = out.size();
    Rect rect(0, 0, size.width, size.height);
    Subdiv2D subdiv(rect);

    // 点を追加する
    subdiv.insert(corners);

    draw_voronoi(out, subdiv);
    draw_delaunay(out, subdiv);

    namedWindow("Delaunay");
    imshow("Delaunay", out);

    waitKey();

    return 0;
}

サンプル画像lena.pngにかけてみる.

参考サイト

www.learnopencv.com

schima.hatenablog.com

OpenCV: cv::Subdiv2D Class Reference

Shi-Tomasiのコーナー検出とGood Features to Track(追跡に向いた特徴) — OpenCV-Python Tutorials 1 documentation

AtCoder Beginner Contest #61

問題はこちらから abc061.contest.atcoder.jp

問題A : Between Two Integers

#include <iostream>
 
using namespace std;
 
int main(){
  int a, b, c;
 
  cin >> a >> b >> c;
 
  cout << ((a <= c && c <= b)?"Yes":"No") << endl;
}

問題B : Counting Roads

#include<bits/stdc++.h>
 
#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)
#define m0(x) memset(x, 0, sizeof(x))
 
using namespace std;
 
signed main(){
  int n, m;
  int field[51][51];
  int a, b;
  m0(field);
  
  cin >> n >> m;
 
  rep(i, m){
    cin >> a >> b;
    field[a][b]++;
    field[b][a]++;
  }
 
  REP(i, 1, n+1){
    int sum = 0;
    rep(j, n+1) sum += field[i][j];
    cout << sum << endl;
  }
 
}

問題C : Big Array

#include<bits/stdc++.h>
 
#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)
 
using namespace std;
 
typedef long long ll;
 
ll cnt[100001];
 
signed main(){
  int n;
  ll k;
  int a, b;
 
  cin >> n >> k;
  
  rep(i, n){
    cin >> a >> b;
    cnt[a] += b;
  }
 
  REP(i, 1, 100001){
    if(k <= cnt[i]){
      cout << i << endl;
      break;
    }
    k -= cnt[i];
  }
 
}

問題D : Score Attack

普通のベルマンフォード書いてたくさんWAした. つらい.(コーナーケース思いつけなかった)

#include <iostream>
#include <vector>
 
using namespace std;
 
#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)
#define pb push_back
#define N_MAX 1000
#define INF (1LL << 51)
 
typedef long long ll;
 
struct Edge{
  int from, to;
  ll cost;
  Edge(int f, int t, ll c) : from(f), to(t), cost(c) {}
};
 
int n, m;
vector<Edge> edges;
ll d[N_MAX+1];
 
bool bellman_ford(){
  rep(i, N_MAX+1) d[i] =-INF;
  d[0] = 0;
  rep(i, 2*n){
    for(auto &edge:edges){
      if(d[edge.from] != INF && d[edge.to] < d[edge.from] + edge.cost){
        d[edge.to] = d[edge.from] + edge.cost;
        if(i > n && edge.to == n-1) return true;
      }
    }
  }
  return false;
}
 
signed main(){
  int f, t;
  ll c;
  cin >> n >> m;
 
  rep(i, m){
    cin >> f >> t >> c;
    f--; t--;
    edges.emplace_back(f, t, c);    
  }
 
  if(bellman_ford()){
    cout << "inf" << endl;
  }else{
    cout << d[n-1] << endl;
  }
}
参考

最短経路問題(ベルマンフォード法・ワーシャルフロイド法) - アルゴリズム講習会

aikoのある生活【アルバム編】

aikoという歌手をご存知だろうか.

aiko.com  そう、あの有名な「カブトムシ」や「ボーイフレンド」を歌っているあのaikoである。 今年の7月でデビュー19周年となるaiko。デビュー当時から変わらない歌や振る舞い、その可愛らしい見た目から今もなお人気のある歌手である(とおもう)
 この記事を書こうと思ったのは、ファンクラブ「Baby Peenats」の継続用紙が届いていたからだ。今回の更新でちょうど2年、7月から3年目の会員となる。いい機会なので、今までに聞いてきたなかで良いと思った曲をアルバムごとに書き出してみたいと思う。
 

小さな丸い好日

小さな丸い好日

小さな丸い好日

小さな丸い好日 | aiko official website
発売は1999年4月21日。aikoのメジャーデビュー後初のアルバムとなる。

オレンジな満月

 書き始めに言うのもどうかと思うのだが、aikoは「どれか一曲」を勧めるのが難しい。自分がファンというバイアスがかかっているからだとは思うが、どの曲も良いと言ってしまいそうになる。その気持ちを抑えて、「小さな丸い好日」からは「オレンジな満月」を選んだ。明るめのポップで、これから始まる「小さな丸い好日」に勢いを付けるような曲であるが、途中体調を崩していたり(消毒液が〜)、お互いうまくやり取りできていないのか投げたボールが返ってこなかったりといった歌詞である。
 aiko bonという本では、「大きな月というのが苦手だが、それにもすがるような気持ち」というのを歌ったとも書いてある。

余談

小さな丸い好日というパン屋さんが有ります。
長崎まちねた。●パンとコーヒーのお店「小さな丸い好日」オープン!

桜の木の下

桜の木の下

桜の木の下

桜の木の下 | aiko official website

 発売は2000年3月1日。aikoのアルバムの中では1,2を争う知名度のアルバムではないだろうか。  桜の木の下には、夏の星座にぶら下がる「花火」や甘い匂いに誘われる「カブトムシ」など有名曲が多い。

桜の時

 この中から1つ選べってのが無理があるように思う。迷った挙句、桜の時とした。カルピスウォーターのCMソングとして起用されている。
 桜の時という曲はタイトルから分かるように(そもそもアルバムタイトルが桜の木の下なのだが)桜を見る二人の曲。毎年桜の時期になると狂ったように聞いている。
 歌詞を聞くだけで幸せな世界が広がる気がする。「好き」が全面に押し出されているものではなくて、その気持を内面に秘めていてこの先もまた同じように一緒に桜を見たいというように感じられた。 f:id:bath_poo:20170622224156j:plain

余談

 シングル版の桜の時は、CDジャケットが和紙でできている。富山県の和紙職人の方に依頼したらしい。

夏服

夏服

夏服

夏服 | aiko official website
発売は2001年6月20日。テトラポット登ることで有名な「ボーイフレンド」が収録されているアルバムだ。テトラポット登るの危ないと思うんだけどね。

アスパラ

 aikoはついに野菜までタイトルにするようになってしまった。アスパラという曲は学生時代をイメージした曲である。aikoの学生時代の弁当にはアスパラが本当によく入っていたらしく、それが理由でアスパラになったらしい。
 まず歌い出しが好きだ。

あの子の前を上手に通る癖覚えたのは
もうずいぶん前の事長いなぁ
あなたの視線追うと必ずいるあの子の前を
通り過ぎてる事であたしに気付いて欲しくて

こういう歌詞を好きになる傾向が自分には絶対あると思う。アスパラを聞くと決まってかつての学生時代(中高ぐらいか)を思い出す。廊下を歩くだけでもドキドキする瞬間ってのがあるんだね。

余談

 夏服は最後の「初恋」のあとに「夏服」って曲が入ってます。まだaiko聞き初めの頃突然なり始めてかなり驚いた。桜の時でいう恋愛ジャンキーも同じである。にしてもこの夏服という曲は良い。寝る前とかにイヤホンで聞きたいタイプの曲。自分にとってはただの衣替えだというのに、aikoにかかると1曲できてしまうからaikoすごい。

秋 そばにいるよ

秋 そばにいるよ (初回限定盤)

秋 そばにいるよ (初回限定盤)

秋 そばにいるよ | aiko official website
発売は2002年9月4日。ライブで歌われる相合傘のアレンジバージョン「相合傘(汗かきMix)」も収録。

今度までには

 自分が初めて行った(aikoだけでなくライブというもの自体初だったのだが)LLP18のときにaikoが「久しぶりに歌う」と言って歌いだした曲。初めてのライブってあまりの衝撃に記憶があやふやなのだが、その中でも覚えていた好きな曲に入っているのがこの「今度までには」である。サビの

あれも素晴らしくってこれも素敵だった
悲しいけれど切ないけれど
あれもこれも忘れるのかなぁ
そして最後にあなたの温もりも忘れるのかなぁ

というところを聞きながら、「切ないなぁ」とひたすら繰り返すだけのaikoジャンキーになる曲である。  それにしても秋そばにいるよ全体を通して暗めなきがするのは気のせいだろうか。

余談

今度までには(single)に収録されている「あなたの唄」って曲も良い。先日のLLR8で初めて生で聞けた。aikoはシングルのカップリングにとんでもないの収録されているので、アルバムだけでなくシングルも聞いたほうが良い。

暁のラブレター

暁のラブレター

暁のラブレター

暁のラブレター | aiko official website
発売は2003年11月27日。人によってはグリコのカフェオレCMソング「アンドロメダ」を知っているだろうか。

彼の落書き

 1曲目の熱からつながっている曲。よかったら熱から聞いてみて欲しい。  歌い出しの

今日もやっぱ連絡はない
きっと忙しいんだと思ってみたり
到底クリアできないゲームを
願掛けするつもりでチャレンジしたり

容易に想像ができる。先の歌詞を読むとこの二人は付き合っていないんだろう。

落ちぬ 取れぬ 消えぬ あなたへの思いはまさに
体中の落書きみたい

女の子側の気持ちは、まるで落書きのようについて離れないのだろう。これから「恋」ってなんですかって聞かれたら、星野源ではなくaikoの「彼の落書き」を聞けばわかると諭してあげたいと思う。

余談

暁のラブレターには「蝶々結び」という曲が収録されている。ワウギターがとても心地良い。あと、MVみて「おさげだ…」ってなる。

交差点で君が立っていても もう今は見つけられないことで有名な「アンドロメダ」も収録されている。

 1曲ずつ紹介すると言いながら余談で3曲も紹介するのは本当にどうかしていると思うが許して欲しい。
 5年後あなたを見つけたら背筋を伸ばして声をかけられるような人になりたい。どう考えてもなれていないので、今後の人生ではそうなれるような努力をしよう。

夢の中のまっすぐな道

夢の中のまっすぐな道

夢の中のまっすぐな道

夢の中のまっすぐな道 | aiko official website
発売は2005年3月2日。12年も前になるのかという気持ち。ジャケットが鹿?トナカイ?みたいである。

明日もいつもどおりに

 迷った挙句、「明日もいつもどおりに」を選んだ。aikoは我々が想像もしないところから曲を生み出す天才である。この曲に関しては、こんな歌詞がある。

出の悪い水道 治し方もわからない
今は些細な事すらも軽く拭えない

悪いことがあると、連続して起こることが多いように思う。何か生活の中で辛いこと、aikoの曲で言うと相手とうまく行っていないとかかも知れないが、水道の出が悪いような些細な出来事でさらに落ち込む。まさかそれが出の悪い水道で表現されているとは思いもしないけれども。

かばん

1曲だけとか無理なので、他にもおすすめしたい曲を書いていこうと思う。

「あなたへの気持ちはこんなに大きなかばんにも収まらない」って意味でかばん。サビの歌詞が

大きなかばんにもこの胸にも 収まらないんじゃない?

「収まらないんじゃない?」なんだね。収まらないんだろうね。この大きな気持ちをあなたに知ってもらいたいけど、でも言い出せない。aikoワールド全開である。aikoは往々にして隣りにいる意中の男性には気持ちを伝えられない。でもそういう人は世の中いっぱいいるし、aiko聞くと「あー分かるわ」みたいな気持ちになるんじゃないだろうか。  ところで、かばんに関しては唄ももちろんのことMVが良い。途中でカーテンにaikoの頭が収まっちゃってるのも好き。頼むから落ち着いてくれと言いたくなるぐらいaikoはよく動いている。特にライブで。

三国駅

天使みたいな白いaikoが出てくることで有名な(?)三国駅aikoが学生時代過ごした三国にある「あそこのボーリング場」を見に行った人も少なくないと思う。aikoの歌うバラードはなぜこんなにも良いのだろうか。

彼女

彼女

彼女

彼女 | aiko official website
発売は2006年8月23日。彼女といえば「がんばっていきまっしょい」のテーマソングとなったキラキラが有名だろうか。他にも「あらしのよるに」というアニメーションの主題歌となった「スター」、docomoのCMにもなった「キスする前に」など盛り沢山である。

シャッター

このアルバムで1つを選べというのが無理があると思う。まず1曲目はシャッター。
先日この記事

amadamu.hatenablog.com に書かれていた以下の文

前髪を切りすぎた全人類のアンセムこと、名曲「シャッター」

aikoの言葉にはリアルが詰まっている 〜LLR vol.08 Zepp Tokyo公演を経て〜 - was neues

なるほど、シャッターはこれからこう説明すればいいのかと勝手に納得していた。「馬鹿野郎前髪を切りすぎているのはどう考えても三戸なつめじゃねーか」という方、ちょっとまって欲しい。 このシャッターという曲では、

切りすぎた前髪右手で押さえて少し背を向けた
嫌われたくないから
うつむくあたしをからかったあなた
今はそれもあたしの夢の中だけ

そういうことである(どういうことだ)切りすぎた前髪を抑える私をからかうあなたはもういないあたり切ない。
 最初に聞いたのはベストアルバムの「シャッター」だったため、彼女のシャッターのイントロは驚いた。カラオケで入れたとき何してたら良いかわからなくなる。

キラキラ

 これは知っている人も多いだろう。前途の通り、「がんばっていきまっしょい」の主題歌となっている。がんばっていきまっしょいといえば若かれし頃の錦戸亮くんがでているドラマである。
 どういう構成とかコードだみたいな話はさっぱりわからないけども、キラキラはとても好きだ。周りに好きって人も多い気がする。シルバーリングが黒くなるってよっぽど待ったんだねaikoは。

ライブのときはサビでみなが手を振る。この景色は壮観である。ちなみにこのライブの映像はLOVE LIKE ALOHAというおーいお茶が配られる無料ライブである(だいぶ端折った説明)

17の月

非常にゆったりとした曲。最初に

心変わりを許した訳じゃない
もうあたしに力が残ってない
傷付いたまま癒す事もない
お願い今日はこのまま寝かせて

とある。もう別れたのだろうか。その後の歌詞は、「帰るぐらいならいっそ迷ってしまえ」とか「逢えば逢う程恋は募る」とか気持ちは大きくなっているけど、

あなたはあたしよりうんと背が高いから
この道もきっと見晴らしがいいのだろう

結局あなたとあたしの見ている世界は違うみたいな歌詞に思えた。歌詞もいいけど曲調が好きだ。

 友人のために作った曲(だった気がする) 結婚式の両親への手紙とかそういうシーンで瞳を流されたら間違いなく手紙を読めなくなると思う。Googleとかで検索してても"結婚式"がサジェストされていた。  彼女というアルバムは何となく「スター」で終わりな感じがするが、そこからまた上がって瞳でしっかりと締める。そんなアルバムだと思う。

秘密

秘密 (通常仕様)

秘密 (通常仕様)

秘密 | aiko official website
 発売は2008年4月2日。この秘密というアルバムはフライパンの流星群(You & Me both)から始まるアルバムだ。他にも後ろに立ってる観覧車に乗りたかった二人とか、シアワセが収録されている。シアワセは自身が一番最初に好きなったaikoの曲だと思う。

秘密

 少し前で一番最初に好きなったのはシアワセと書いているが、秘密を聞いた結果今では「秘密」が一番好きなのでこの曲をおすすめしたい。aikoジャンキー1の秘密好きなんじゃないかという上田啓太さんの「真顔日記」にすべてが書かれている気がする。

diary.uedakeita.net

上田啓太さんのaiko記事はどれも面白い。ゴリラと綱引きしていた記事は夜中に大笑いしてしまった。

diary.uedakeita.net

 サビ前の「これ以上思いが〜済まなくなりそうで」から、サビに入る部分で鳥肌が立つ。これもまた寝る前に聞くことが多いのだが、何度聞いても飽きない。何度でも言うが、aikoバラードは最高だと思う。

シアワセ

 aikoの楽曲で一番聞いていると思う。最初に好きになった曲だし、MVも一番好きだと思う。ノースリーブaikoと麦わらaikoが交互に出てくるMV。

余談

二人といえば先日のaikoTwitterが可愛かった。

あんころもち(犬)もaikoも可愛い。このときはZepp Osaka Baysideでライブしてて、すぐ近くに天保山大観覧車があったというわけ。でも実際Zepp Osaka Baysideの後ろに立っているのはUSJなきもする。

BABY

BABY[通常仕様]

BABY[通常仕様]


BABY | aiko official website
発売は2010年3月31日。BABYといえば、花より男子Fにの劇中歌KissHugやアルベルトのCMにもなったmilkが収録されている。

あの子の夢

 BABYも勿論迷った。なんせ自分が最初に聞いたのが「BABY」「まとめⅠ」「まとめⅡ」を並行して聞いていた感じだからだ。アルバムの1曲目として申し分ないbeat、ライブで裏打ちするのが楽しいmilk(milkの紹介にこれは失礼な気がするが)、戻れない明日など迷った。が、あの子の夢を1番推したい。
 「あの子の夢」はウェルかめの主題歌にもなった曲。だがシングルでは発売されておらず、BABYにのみ収録されている。主題歌になってシングルになってないとは珍しい。
 あの子の夢は入りのドラムがまず良い。aikoのドラム担当といえば佐野康夫さん。ファンからはさのっちとも呼ばれいる。活動内容見ていると、この人はすごい人なのだと思い知らされる。この曲に関しては、歌詞云々というより完全に聞いてて「なんか良い」タイプの曲だった。一番好きなところはCメロです(物音に怯えて〜の部分)

milk

milkはライブでも盛り上がる定番曲。上でも書いたけど手拍子が楽しい。雪もミルクも霞んじゃうぐらいの光りに包まれたい。

時のシルエット

時のシルエット (初回仕様)

時のシルエット (初回仕様)

時のシルエット | aiko official website
発売は2012年6月20日。自分がいちばん好きなaikoのアルバムである。正直時のシルエットは好きな曲が多すぎる。好きだけじゃすまなくなりそう。

Aka

 このアルバムの1曲目となる曲。あなたとあたしの結びつきというか。どんなにうまくいかなくても、壁が立ちはだかったとしても、あなたと私の二人でなら乗り越えていける。そんな曲だと思う。

音の混ざった人混みの中
二人離れず手を繋いだ
愛してるよりも強い指で

aikoの言う愛してるはそんな軽いものでは無いんだろうし、それよりも強いってことは相当な結びつきなんだろう。なんせあたしが楽しく生きていくさじ加減はあなたが握っているのだから。  また思い出の話になってしまうのだが、LLP18のときにAkaを生で聞いて自然と涙が流れた。aikoのライブに行くと、今まで以上に曲を好きになる。自分の中でAkaはもう殿堂入りレベルだ。

くちびる

歌い出しが

あなたのいない世界には あたしもいない

歌い出しからaikoワールド全開だ。くちびるは、1番の「胸が粉々になる」がどう考えても「こなこなになる」に聞こえてしまう現象がある。 diary.uedakeita.net 歌詞だけではなくリズムも好きだ。なんだろうねこのゆらゆら揺れたくなるリズムは。

向かいあわせ

 ダーリンは外国人の主題歌にもなったこの曲。菜の花畑にいるaikoが可愛い。これもLLP18で好きになったかな。今思い返すとあのライブで更に深くハマったと思う。

冷たい嘘

 彼の落書きに続く、「彼からの連絡がないソング」である。「しかし連絡がないなあ」といった歌詞で始まる恋愛ソングって聞いたことが無い。「毎日ため息つくために息を吸う」とか「あなたを愛した事もさぁ いつかは嘘になるんだ」とか、しんどさのレベルが高すぎる。

恋のスーパーボール

 恋のスーパーボール/ホームという両A面シングルの1曲。今の子にはA面とか通じないんだろうか。これはカルピスウォーターのCMソングだった。夏になると聞きたくなる1曲だ。

出口は塞いでしまおう
2人で迷いたいの 今夜をあげる

出口を塞ぎたいタイプのaikoが出てきた。そういう表現はとてもいいと思う。
この時のaikoは髪の毛がベリーショートだったのだが、このaikoも個人的にはいいと思う。ロングもいいがショートはもっといい。

恋のスーパーボール/ホーム(通常盤)

恋のスーパーボール/ホーム(通常盤)

自転車

 Akaで始まって自転車で終わる。素晴らしいアルバムである。自分はアルバム最後にあるバラードをすごく好きになる(と思う)が、その中でも自転車は他よりも強い思い入れがある。これもまたLLP18の思い出だ。
 自転車には次のような歌詞がある。

明日あなたはあたしの事をどう思っていてくれるだろう

aikoは今日恋人でも明日にはどうなるかわからないという気持ちが強く出ている気がする。例えば、

あなたがあたしの事をどう思っているのか
それはそれは毎日不安です(Aka)

とか

明日あなたがいなくなってあさって心変わりして
いつか嫌いになられたら…(愛の病)

のような。aikoと言うのは常に不安なのだ。自分にも似たようなところがあるあたりがハマった要因なのかもしれない。

時のシルエットについて書きすぎじゃないですかね…)

泡のような愛だった


泡のような愛だった | aiko official website
発売は2014年5月28日。随分近づいてきた。時のシルエットに続いてaikoが飛んでいるジャケットである。aikoはCDジャケットでもライブでもよく飛び跳ねている。

これは最近のTwitterより。

明日の歌

 このアルバム1曲目に収録されている「明日の歌」が良い。言葉の数がすごい。それ故にちょこちょこ早口で歌うところもある。

暑いって言うかこの部屋には想い出が多すぎる またも歌い出しでびっくりする。思い出が多いといった趣旨の歌詞はあると思うが、「暑いって言うか」から始まるのだ。また、 明日が来ないなんて 思った事が無かった

とまた明日に絶望している。

この電池切れてもずっと点滅したままきっと止まってはくれないし
薄暗い冷たい廊下を歩くと冷たい床が足下から悲しくする

「明日もいつもどおりに」ばりに負の連鎖が続いて更に辛さが増している。つい元気だしてって言いそうになってしまうぐらい。

May Dream

May Dream(初回限定仕様盤A)(Blu-ray Disc付)

May Dream(初回限定仕様盤A)(Blu-ray Disc付)

May Dream | aiko official website
発売は2016年5月18日。執筆時点で1年以上前だ。ついこの間出たばっかりな気がしていたが、もう1年も経っていた。aikoも出演したことで話題になった素敵な選タクシーの主題歌「明日の向こう」や、フカキョンとディーンフジオカ出演のドラマ「ダメな私に恋してください」の主題歌「もっと」など、前作に比べるとタイアップソングが多い印象を受ける。このアルバムの大きな変更点は、

何時何分

 何時何分は、前作の1曲目「明日の歌」と同様言葉数の多い曲である。それはこの曲に限った話ではなく、May Dream収録曲は言葉数が多いように思える。この曲の歌詞は

あめちゃんあったら嬉しいな
がさごそ探るカバンの中
掴んでみたらゴミ屑と
偶然見つけたあの指輪

 aikoがあめちゃんとか言うと、完全に大阪のおばちゃんで再生されてしまう。そんなあめちゃんと一緒に見つかるのは、無くしたと思っていた指輪。あめちゃんという出だしから急転直下何か思いものがのしかかる。ちなみにタイトルは「何時何分地球が何周回ったとき?」っていうアレから来ているらしい。
 ちなみにこの曲はインポートしてから218回聞いているらしい。脅威のハイペース。

冷凍便

 これもまた何時何分に続いて言葉数が多い。

早く家に帰ったらなんかどうしていいかわからなくなる
あたしの楽しみにしてるラジオ もっと遅くにやるの

自分の中ではラジオっ子というとaikoの印象が強い。ついには歌の中に出てきた。冷凍便は歌詞よりもリズムというか、音自体が好きな曲。

信号

 セイコールキアのCMソングにもなっている曲。

「愛なんて~」とファルセットで歌い上げる部分のインパクトがすごい。1度聞いただけで耳に残る曲だと思う。愛もわからないし君のこともわからないけど、好きなんだろうね。

愛だけは

 最初にMay Dreamを通しで聞いたときには特に印象に残っていなかったのだが、そこは「スルメソング」で有名なaiko。聞いてるうちにハマっていった。聞き込んでいったことだけが要因ではなくて、ファンクラブ限定動画もかなり大きな理由なんだけども。

aikoの良さは何なのか

 自分がaikoをしっかり聞き始めたのが2014年、ファンクラブに入ったのが2015年の7月、初めてのライブが2015年の12月27日。まだaikoの良さを語れるほどの年数ではないようには思う、というのを断っておく。

  • ファンとの近さ
     aikoももう19年目に突入しようとしている。それだけのキャリアを経て、人気も出てきたアーティストというのはファンとの距離ができてもおかしくないと思う。aikoはLLP(ホールツアー), LLR(ライブハウスツアー), LLA(浜辺)の3つにわけられるのだが、どのライブでもお客さんからの呼びかけに答える(なんなら普通に会話する)し、ハイタッチやら握手やら触れ合える機会も多い。最初に行ったのがaikoで、この人についていきたいと思えた。
  • 変わらない良さ
     変わらないというのは難しいことだと思う。19年もやれば色々あるだろうし。でも歌う曲のジャンルも、前途のライブのスタイルも変わらない。よく走るしよく跳ねる。見た目もあまり変わらないですね。いや流石に歳相応なところもあるけども、驚異のキープ力だと思う。そしてこれからも変わらないで居てほしい。

 aikoの良さを1度に知るにはライブに行ってみるのが良いと思う。ライブDVD/BDを見るところからでも良い。でもDVD/BDだとMCがカットされているら、できれば会場に行ってもらいたい。「aikoしらない」という人から「aikoはCDで聞くぐらい」というライトなファンも、きっと会場の人もaikoも暖かく迎え入れてくれると思う。そして帰るときには、楽しかったと思えると思う。

muttan1203.hatenablog.com

最後に

 1stアルバム「小さな丸い好日」から12thアルバム「May Dream」まで振り返ってみた。普段アルバム単位で聞くことはなく、aiko全曲シャッフルで聞くことが多いためアルバムを意識して考えることは少なかった。aikoは昔から変わらず恋愛ソングを歌い続けている。歌い方とか声は変わっているけども、それはそれでいい味になっている。
 この記事を書くのは正直迷った。「それは違うでしょ」とか「こっちの曲のほうが良くない?」みたいな意見を持つ人もいると思う。それはまだファン歴が浅い人間が書いたものなのでどうか大目に見てほしい。
 より詳しくaikoのことを知りたいという方は、ぜひaiko bonを読んでみてほしい。中古でしか手に入らないと思うが…
 今回はアルバム編だったが、もし可能であればシングルカップリング曲の好きなものを紹介する記事も書きたいと思う。カップリングはよりaikoらしさが詰まっているのかもしれない。

AtCoder Beginner Contest #62

問題はこちらから.

abc062.contest.atcoder.jp

問題A: Grouping

#include <iostream>

using namespace std;
 
int main() {
    int x, y;
    
    int groups[] = {0, 1, 2, 1, 3, 1, 3, 1, 1, 3, 1, 3, 1};
    
    cin >> x >> y;
    cout << (groups[x] == groups[y]?"Yes":"No") << endl;
}

問題B: Picture Frame

#include <iostream>

using namespace std;
 
int main() {
    int h, w;
    
    cin >> h >> w;
    for(int j = 0 ; j < w + 2 ; j++) cout << "#";
    cout << "\n";
    for(int i = 0 ; i < h ; i++){
        string s;
        cin >> s;
        cout << "#" << s << "#" << endl;
    }
    for(int j = 0 ; j < w + 2 ; j++) cout << "#";
    cout << "\n";
}

問題C: Chocolate Bar

4種類分け方があるので, それを全部試す.

#include <iostream>
using namespace std;
 
#define int long long
 
signed main() {
    int h, w;
    long long ans = 1e11;
    cin >> h >> w;
 
    for(int h1 = 1 ; h1 <= h ; h1++){
        int area1 = h1 * w;
        
        int h2 = (h - h1)/2;
        int area2 = h2 * w;
        int area3 = (h-h1-h2) * w;
        int _min = min(area1, min(area2, area3));
        int _max = max(area1, max(area2, area3));
        ans = min(ans, _max - _min);
        
        int w2 = w/2;
        area2 = (h - h1) * w2;
        area3 = (h - h1) * (w - w2);
        _min = min(area1, min(area2, area3));
        _max = max(area1, max(area2, area3));
        ans = min(ans, _max - _min);
    }
    
    swap(w, h);
    for(int h1 = 1 ; h1 <= h ; h1++){
        int area1 = h1 * w;
        int h2 = (h - h1)/2;
        int area2 = h2 * w;
        int area3 = (h-h1-h2) * w;
        int _min = min(area1, min(area2, area3));
        int _max = max(area1, max(area2, area3));
        ans = min(ans, _max - _min);
        
        int w2 = w/2;
        area2 = (h - h1) * w2;
        area3 = (h - h1) * (w - w2);
        _min = min(area1, min(area2, area3));
        _max = max(area1, max(area2, area3));
        ans = min(ans, _max - _min);
    }
    
    cout << ans << endl;
}

問題D: 3N Numbers

どうやったらいいかわからず解説見ながら解いた(それでも最初わからないのでダメ)

#include<bits/stdc++.h>
 
#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)

using namespace std;
 
typedef long long ll;
 
signed main(){
  int n;
  int data[300001];
  ll s1[300001] = {0};
  ll s2[300001] = {0};
  
  scanf("%d", &n);
  REP(i, 1, 3 * n + 1) scanf("%d", data+i);
  
  priority_queue<int> q;
  
  REP(i, 1, n+1){
    q.push(-data[i]);
    s1[n]+= data[i];
  }
 
  REP(i, n+1, 2 * n + 1){
    s1[i] = s1[i-1];
    q.push(-data[i]);
    s1[i] += data[i];
    int _min = q.top();
    s1[i] += _min;
    q.pop();
  }
 
  priority_queue<int> q2;
  
  for(int i = 3 * n ; i > 2 * n ; i--){
    q2.push(data[i]);
    s2[2*n+1] += data[i];
  }
  
  for(int i = 2 * n ; i > n ; i--){
    s2[i] = s2[i+1];
    q2.push(data[i]);
    s2[i] += data[i];
    int _max = q2.top();
    s2[i] -= _max;
    q2.pop();
  }
  
  ll _max = numeric_limits<ll>::min();
  REP(i, n, 2*n+1){
    _max = max(_max, s1[i] - s2[i+1]);
  }
 
  printf("%lld\n", _max);
}

最後のmaxを取るところ, 添字ずれるのに気づいておらず, ずっとmax(ans, s1[i]-s2[i])で計算していて悩んだ. max(ans, s1[i] - s1[i + 1])ですね.
ところでpriority_queueって最小ヒープどうやるんだろう. いまのところ負にすることで対応しているが…(std::priority_queue<int, vector, greater>とかなのだろうか)

AtCoder Beginner Contest #63

問題はこちらからどうぞ.

abc063.contest.atcoder.jp

問題A: Restricted

#include <iostream>

using namespace std;

int main(){
  int a, b;
  cin >> a >> b;
  if(10 <= a + b) cout << "error" << endl;
  else cout << a + b << endl;
}

問題B: Varied

#include<bits/stdc++.h>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)

using namespace std;

signed main(){
  string s;
  cin >> s;
  set<char> st;
  rep(i, s.size()){
    st.insert(s[i]);
  }
  if((int)s.size() == (int)st.size()) cout << "yes" << endl;
  else cout << "no" << endl;

}

問題C: Bugged

#include<iostream>
#include<vector>
#include<algorithm>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)
#define pb push_back

using namespace std;

signed main(){
  int n;
  cin >> n;
  int sum = 0;
  vector<int> v;
  int in;
  rep(i, n){
    cin >> in;
    sum += in;
    if(in%10 != 0) v.pb(in);
  }
  
  sort(v.begin(), v.end());
    
  rep(i, v.size()){
    if(sum % 10 != 0) break;
    sum -= v[i];
  }
  
  if(sum % 10 == 0) sum = 0;
  cout << sum << endl;
}

問題D: Widespread

#include<bits/stdc++.h>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)

using namespace std;

typedef long long ll;

int h[100001];
ll n, a, b;

bool check(ll t){
  ll cnt = 0;

  rep(i, n){
    if(h[i] > b * t){
      cnt += (h[i] - b * t) / (a-b);
      if(((h[i] - b * t) % (a - b)) != 0) cnt++;
    }
  }
  return cnt <= t;
}

signed main(){

  scanf("%lld %lld %lld", &n, &a, &b);

  rep(i, n) scanf("%d", h+i);
    
  ll l, r, mid, ans;
  l = 0; r = 1e9;

  while(l <= r){
    mid = (l + r) / 2;
    
    if(check(mid)){
      ans = mid;
      r = mid - 1;
    }else{
      l = mid + 1;
    }
  }

  cout << ans << endl;
  
}

AtCoder Beginner Contest #64

問題はこちらからどうぞ.

abc064.contest.atcoder.jp

問題A: RGB Cards

#include <iostream>

using namespace std;

int main(){
  int r, g, b;
  cin >> r >> g >> b;
  cout << ((r * 100 + g * 10 + b)%4==0?"YES":"NO") << endl;
}

問題B: Traveling AtCoDeer Problem

#include<bits/stdc++.h>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)
#define INF 1e9

using namespace std;

signed main(){
  int N;
  int _max, _min, a;
  cin >> N;
  _max = -1; _min = INF;
  rep(i,N){
    cin >> a;
    _max = max(a, _max);
    _min = min(a, _min);
  }

  cout << _max - _min << endl;
}

問題C: Colorful Leaderboard

#include<iostream>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)

using namespace std;

signed main(){
  int N;
  int cnt[13] = {0};
  int a;
  cin >> N;
  
  rep(i, N){
    cin >> a;
    cnt[a/400]++;
  }

  int c1 = 0;
  rep(i, 8){
    c1 += (cnt[i] > 0?1:0);
  }
  int c2 = 0;
  REP(i, 8, 13){
    c2 += cnt[i];
  }
  
  cout << (c1==0?1:c1) << " " << c1 + c2 << endl;
}

問題D: Insertion

#include<bits/stdc++.h>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

int gcd(int a,int b){return b?gcd(b,a%b):a;}
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};

signed main(){
  int n;
  string s1, s2, ans;
  
  int l, r;
  cin >> n;
  cin >> s1;
  l = r = 0;
  ans = "";
  int a = 0;
  rep(i, s1.size()){
    if(s1[i] == '(') l++;
    else r++;    
    if(a > l - r) a = l-r;
  }
  
  rep(i, abs(a)){
    ans += "(";
  }
  ans += s1;  
  rep(i, l-r-a){
    ans += ")";
  }

  cout << ans << endl;
}