パンうめぇ

園児ニアの日記帳

M-SOLUTIONS プロコンオープン 2020 C 累積和で解く

M-SOLUTIONS社のプロコンに参加しました.

C問題で累積積を書いて提出したのですが桁が大きすぎてWA. 解説をみたところ対数変換で累積和に直せば同じようなロジックで解けるとのことで実装して提出しました.

atcoder.jp

考え方

logで対数変換し,累積和を取りiからi-kの値を引くことでそれぞれの学期評価が求まります. あとはそれを比較し答えを求めます.

c++にはlog10という便利な関数があり,簡単に対数変換できることがわかりました. また対数変換の際には誤差に対応する必要があるため少数型にします.

f:id:kanekou:20200731132308p:plain
4学期の評価を求める場合(i=4, k=3)

解いたコード

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define reps(i, n) for (int i = 1, i##_len = (n); i <= i##_len; ++i)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; --i)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; --i)
#define INF 1000000000000
#define MOD 1000000007

 
int main() {
    ll n, k;
    cin >> n >> k;
    vector<long double> a(n + 1, 0);
    vector<long double> csum(n + 1, 0);
    reps(i, n) cin >> a[i];
    reps(i, n) csum[i] = log10(a[i]) + csum[i - 1];
 
    long double pre = csum[k];
    for (int i = k + 1; i <= n; i++) {
        long double result = csum[i] - csum[i - k];
        if (pre < result)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
        pre = result;
    }
    return 0;
}

ほんとはA[i] < A[i-k]を比較するだけで良いのですが,気付きませんでした... 算数強くなりたい.

DFS

競プロをしているのですが,DFSにまだ慣れないので,備忘録として問題と考え方を残してきたいと思います.

ABC114 C

atcoder.jp

7, 5, 3の組み合わせの数を求める問題です.

考え方としては,以下のように3, 5, 7それぞれを全探索し,[3,5,7]を組み合わせてできるn以下の数字をカウントすれば良いです.

f:id:kanekou:20200725143035p:plain
それぞれの木において[3,5,7]の組み合わせでできる数をカウントする.

解いたコード

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define reps(i, n) for (int i = 1, i##_len = (n); i <= i##_len; ++i)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; --i)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; --i)
#define INF 1000000000000
#define MOD 1000000007

using namespace std;
using ll = long long;
vector<ll> ans;
ll n;

void dfs(ll p) {
    if (p > n) {
        return;
    }
    if (to_string(p).find("3") != string::npos &&
        to_string(p).find("5") != string::npos &&
        to_string(p).find("7") != string::npos) {
        ans.push_back(p);
    }
    dfs(p * 10 + 3);
    dfs(p * 10 + 5);
    dfs(p * 10 + 7);
}

int main() {
    cin >> n;
    dfs(3);
    dfs(5);
    dfs(7);

    cout << ans.size() << endl;
    return 0;
}

わざわざvector<ll> anspush_backしたのはデバックのためです.普通にカウントすればいいです.

ATC 001

atcoder.jp

迷路を探索してゴールを目指す基本問題です. 解き方として,4方向でDFSしながら記録を取り,すでに探索した所や壁,枠外にきた際に戻る感じです.

座標がy,xなところに少し注意しなければいけないかも.

解いたコード

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define reps(i, n) for (int i = 1, i##_len = (n); i <= i##_len; ++i)
#define rrep(i, n) for (int i = ((int)(n)-1); i >= 0; --i)
#define rreps(i, n) for (int i = ((int)(n)); i > 0; --i)
#define INF 1000000000000
#define MOD 1000000007

using namespace std;
using ll = long long;
int h, w;
vector<string> field;
bool seen[500][500] = {{false}};

void dfs(int y, int x) {
    if (x < 0 || y < 0 || x >= w || y >= h) return;  //out
    if (field[y][x] == '#') return;  // wall
    if (seen[y][x]) return;          // already seen
    seen[y][x] = true;

    // 4 directions
    dfs(y + 1, x);  // ↑
    dfs(y, x + 1);  // →
    dfs(y - 1, x);  // ↓
    dfs(y, x - 1);  // ←
}

int main() {
    cin >> h >> w;
    field.resize(h);
    rep(i, h) cin >> field[i];

    // find start and end position
    int start_x, start_y, end_x, end_y;
    rep(y, h) rep(x, w) {
        if (field[y][x] == 's') {
            start_x = x;
            start_y = y;
        } else if (field[y][x] == 'g') {
            end_x = x;
            end_y = y;
        }
    }

    dfs(start_y, start_x);

    if (seen[end_y][end_x])
        cout << "Yes" << endl;
    else
        cout << "No" << endl;

    return 0;
}

ARC061

atcoder.jp

1 以上 9 以下の数字のみからなる文字列 Sが与えられた時に.+を入れた時の和を計算する問題です.ただし,+が連続してはいけません.+を入れるか入れないかの2択なのでbit全探索を解く方がベターだと思いますが,全探索で練習しました.

以下のように考えました.左から数えて,木の深さに対応する桁に対して+をつけるか付けないかで全探索しました.

f:id:kanekou:20200806131429p:plain
入力値が125の場合

解いたコード

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>

using namespace std;
using ll = long long;
int N;

ll dfs(string s, int deep, int last, ll left) {
    // 深さが桁数-1で打ち切り
    if (deep == N) {
        return left + stoll(s.substr(last, s.size() - last));
    }

    // depp番目までを数に直す
    string s_sub = s.substr(last, deep + 1 - last);
    ll right = stoll(s_sub);

    auto sum1 = dfs(s, deep + 1, deep + 1, left + right);  // yes
    auto sum2 = dfs(s, deep + 1, last, left);              // no

    return sum1 + sum2;
}

int main() {
    string s;
    cin >> s;
    N = s.size() - 1;
    auto ans = dfs(s, 0, 0, 0);
    cout << ans << endl;
    return 0;
}

参考サイト shoman.hatenablog.com

最近

自分自身のキャリアについてなんとなく固まってきた気がするので,言語化しときます.

  1. 3年以内にプロダクトの技術選定に携わりたい,オーナーシップを持ってプロダクトを作り上げたい.

  2. チーム開発が好きなので,4-5年でスクラムマスターとして開発を回したい.

この二つです. 1が優先順位が高くて,当事者意識を持ってプロダクトを開発したいです.責任を持つのは怖いですがその分成長できると思うし,「自分がこのサービスを作ってるんだ!」というやりがいが人一倍感じられるんじゃないかと思います.技術力は頑張ってつけます.

2はインターン活動の中で自分自身を振り返って時に,やっぱり1人よりチーム開発が好きだと再認識したからです.ある程度の技術力がついたのちに,チーム全体の生産性をあげるための潤滑油として活躍したいです.

スクラムマスターしてたら開発できないんじゃないかとかありますが,何かしらプログラミングをする機会を別に作っていきたいです(OSS貢献とかしたい).チーム開発のノウハウを知っている開発者になりたいです.

技育祭2日目に参加しました

技育祭2日目参加したので所感を書き綴ります.

キャリア相談

CAの方々と就活について話す機会がありました.

インターン活動ではコーディングテストで実力を図ることが多いですが,実力とビジョンをどのくらいの割合でみているのか気になって質問しました.

CAとしては,「どのように成長したいか,目的を明確にしている人を重視している」とのことでした. その中でどのように行動してきたかを示すような証拠(ポートフォリオ)があるとよいとのことです. やはりポートフォリオは目に見えてわかりやすいですよね.

その時の技術力というよりは,将来のポテンシャルをみているようです.

将来的には技術を用いて社会問題,あるいは身の回りの生活の課題を解決したり最適化したいと考えているので,話を聞いていて色々挑戦できそうな環境だなという印象を受けました.

あとはインターンシップ交流会で同志たちと友達になりました. みんなサマーインターンに苦労しているようです.僕もそれなりに選考に落ちて自信を失っていたので少し励みになりました. 通常選考より倍率が高いらしいので,神経質にならず挑戦していきたいお気持ちです.. 通常選考の方が受かることも普通にあるっぽいですし(とは言ってもやっぱり落ちたら落ち込む).

プログラミングコンテストのすゝめ 〜競プロはキャリアであり、趣味でもあり、学びである〜

AtCoder社長のchokudaiさんの登壇がとても面白かったです. アルゴリズムを改良することで計算量を数千倍削減できることを,面白おかしくわかりやすく伝えてくださり,めちゃくちゃ盛り上がっていました. コメント欄がニコニコ生配信かな?って思うほどギャグ線に溢れていました.

なんちゃって解法がまさかのACした時,腹捩れるぐらい笑いました.

キャリアがどうこうっていうより競プロの楽しさが伝わってきたのがよかったです. 僕も競プロやっていますが,キャリアのためというよりは単純に楽しいのでやってる感じです.(まだ灰色の雑魚ーダーです)

インターンのコーディング試験で「競プロちょっとやっといてよかった〜」と思うこともあり,それなりに役立つと思っていますが,それだけのモチベだと続かないのかなと感じます. chokudaiさんは「競プロ楽しい」という感覚を前面に押し出していて,「課題,勉強」という捉え方のみで取り組むのではなく,ゲーム感覚で楽しむことが一番実力アップにも繋がるし,いい付き合い方なんだろなと思いました. とはいえ解けないとかかなり落ち込みます.毎週落ち込んでいます.精進しよう.

LT大会

小学生のLTがクオリティ高すぎて感動しました.

ソフトフェア開発をしていると実感するのですが,自分が思い描いたものを形にすることって難しいですよね. それを1人で,しかもハードウェアとソフトウェアの両方を小学生が自作したというのはすごくないですか? クオリティの高さもさることながら,ゲームをクリアするとは背面から「たけのこ」と「きのこ」が現れるあのアイディア性には驚きました.

加えてプレゼンもハキハキしてて,説明もわかりやすかった.(声もよかった)

将来は発明家?になりたいと言ってましたがほんとになれそう. 将来が楽しみすぎます.

変化し、進化し続ける技術者になるために 〜メルカリ・メルペイCTOの場合〜

印象深い言葉として,名村さんのおっしゃっていた「自分で決めて動くことが大切」という言葉です. 自分が責任を追うのが怖い,だから他人に決定を押し付けるマインドは成長に繋がらないということですね. そういう節があるかもしれない,と思ったので自分で意思決定してプロダクトを動かしていくことを早いうちから経験していきたいと思いました. 正直怖いけど,乗り越えて成長したいお気持ち.

モチベ

インターン活動をしているのですが,同志がどのような状況なのかよくわからなかったので,交流を通して状況を知ることができたし仲間もできました. 最近は自信喪失気味だったのですが「自分は1人ではない」という思うことができたのは大きかったのかなと思います. またトップレベルのCTOや人事の方,LT発表を通して刺激をもらうことができて,純粋に頑張ろうと思いました(小並感).

技育祭1日目参加しました

就活生として,技育祭に参加したので所感を書き綴っていきます.

talent.supporterz.jp

働く上でのキャリアについて

メルカリエンジニアのcodehexさんのお話を聞いて強く感じたことです.

私はcodehexの出身学部と同じところに所属していて,codehexさんはコミュニティを運用しつつ,コードもバリバリに書けるつよい方という認識でした.

今回話を聞いて感じたとは,多くのインプットと継続的なアウトプットが高いコーディング能力の土台となっている,ということです. 「つよい」と思っている人はそれなりにインプットとアウトプットをこなしていることを再認したし,やるかやらないかの話なんだよな,と考えることができて少し前向きになれた気がします. どこか「自分のような凡才とは持ってるものが違うんだろうな...」みたいなマイナス思考に捉えていた節があるので.明らかにインプット量もアウトプット量もつよつよな人たちに負けてるし,全然言い訳できないですね. はてなの大西さんの話でもあったのですが,とにかくアウトプットは重要だと.だから今もブログ書いてます.継続できる範囲でアウトプットしていきたい.

あと印象深かったのは,「就職前はコードさえ書ければ良いと考えていたが,仕事をこなすうちにチーム全体の生産性を考えるようになった」ということです. 私は今現在インターン活動真っ只中で,自分のキャリアに悩みはじめてます.第一にコードを書き続けていたい,けどマネジメントも学んでいった方が良いのではないかと考えています.

話を聞くうちに,最初はバリバリにコーディングしたいという思いは強くなりました. そして働く中でキャリアについて考え方の変化があるかもしれないし,そのときキャリア選択を変えても良いんじゃないかな,という考えに至りました. マネジメントは開発者としても最低限必要スキルだと思うので,PMに回ったときのためにもちょくちょく勉強していきたいです.

CTOパネルディスカッションでもCTOの方が仰ってたように,「昔はコードしか書きたくないと思ってたけど,働くうちにキャリア像が変化して今に到る」みたいなことは割とあるのかなと思いました. (考えてみれば大学入学前と入学後でもやりたいことまるで違います)

2日目も楽しむ

ギークな話もあればキャリアに関わる話もあり,いろいろ考える機会になりました. 明日2日目も参加するので楽しみです.

goのdatabase/sqlの使い方備忘録

最近Goを触る機会があり,ちょっとハマりかけたdatabase/sql packageの使い方をメモ.

import

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

コネクションの確立

var db *sql.DB

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Println("Error loading .env file")
    }
    db, err = sql.Open("mysql", "root:"+os.Getenv("DB_PASSWORD")+"@tcp(127.0.0.1:3306)/bbs") //接続
    if err != nil {
        log.Println(err)
    }
    err = db.Ping() //接続確認
    if err != nil {
        log.Println(err)
    }
    defer db.Close()

sql発行例

func LoginHandler(w http.ResponseWriter, r *http.Request) {
        email := "hoge@hoge.com"
        err := db.QueryRow("select email from users where email = ?", email).Scan(&email) //発行
        if err != sql.ErrNoRows { 
          http.Redirect(w, r, "/index", http.StatusFound)
       }

注意点

Openは基本的に一回だけ

ドキュメント以下

The returned DB is safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB.

golang.org

書いてあるように,コネクションプールのおかげでsql.Open()の呼び出しは一回だけでいいっぽい. 最初hundlerごとにopen,closeしてたw

mainまたはinitで接続を確立し,コネクションプールで使い回す感じだと学びました.

接続確認にはdb.Ping()を呼び出す.

ドキュメント以下にあるように,db.Open()は引数の検証をするだけであるため接続確認はdb.Ping()を使用する.

Open may just validate its arguments without creating a connection to the database. To verify that the data source name is valid, call Ping.

所感

まだGolangを触り始めたばかりですが,小さいパーツからつくっていくこの感じ面白いです.

はやくチュートリアル終わらせて本格的なプロダクトをつくってみたいです. まだまだ知識不足なのでもっと勉強します.

ハッカーズチャンプルーで初めてイベント運営に携わりました!

2019年の6/29日に沖縄県最大のITカンファレンス,hackers-champlooが開催されました.

hackers-champloo.org

僕は初めてコミュニティーの運営スタッフとして,前夜祭,カンファレンス,懇親会に携わりました. 主に開催場所である琉球大学のネットワーク関連や,前夜祭の会場探し,当日のゴミ袋の準備や懇親会の受付等を行いました.

前夜祭

初めて前夜祭に参加しました.

結構人見知りなので,真ん中で挙動不振になってましたが話しかけてくださる方々のおかげで,酒を入れつつ色々お話を聞くことができました.

Railsチュートリアルで100時間以上見た安川さんが画面の向こう側からこちらにいらっしゃのはとても興奮しました(笑) しかも研究の話も聞いてくれました(僕より詳しい). Railsチュートリアルのおかげでenpitの開発や技術系バイトをすることができたので,その感謝を伝えることができてとてもうれしかったです.

話しかけてきてくださったPaulさんに,何者か存じ上げず(申し訳ないです)「仕事は何をなさってるんですか?」と聞いたところ「Doorkeeper作ってます」と言われてめちゃくちゃ驚きました.Paulさんごめんさない(スタッフなら把握しとけよ). RubyRailsの質問について日本語で親切に答えてくれてとてもいい人でした.本当Doorkeeperにはいつもお世話になっております🙇‍♂️

LTセッションもありすごく盛り上がってました.個人的にcodehexさんの快適な環境づくりがすごくよくて,速攻で実践してみようと思いました. 推しの映像流すと絶対集中できないので,水や火の映像を流しつつ作業するのもいいな~

あとポテトがうまかったです🍟

カンファレンス当日

スタッフ作業で見れなかった発表もあったのですが,ハッカーズチャンプルでみた発表は以下の通りです.

  • 開発向けの基盤をつくる(@deeeetさん)
  • JavaScriptで黒魔術(りゅうさん)
  • ぎのわん勉強会の紹介(@jewel_x12さん)
  • Stimulus × Jest × Direct Upload × Image Fluxで カオスなJS環境と画像アップロード機能を改善しつつユーザーの投稿率を上げた話(@Masahさん)
  • 現代のコンピュータにおける自作OS事情(hikaluimさん)
  • 好きなことをやり続けるということ(ちょまどさん)
  • Remote Work in Action(安川要平さん)
  • 脆弱性診断員の日常(仮)(@328__さん)
  • What can Emacs be?(@gongoZさん)
  • これがVtuberエンジニアなんだよなぁ(Naporiさん)
  • ラズパイは〇〇(仮)(miyaz697)
  • 意味不明プログラミング(tompongさん)

みなさんとても面白かった...トーク力も技術力も高い... 一部紹介していきます(:3 」∠ )_

開発向けの基盤をつくる(deeeetさん)

マイクロサービスとはなにか,なぜ必要なのか. なぜメルカリはシステムを複雑なマイクロサービス化しているのか. そしてなぜコンテナ,k8sを採用したのかについてのお話でした.

設計について興味があるので,結構難しい内容でしたがとても面白かったです.

小規模アプリしか設計,構築したことがないのでマイクロサービスは新鮮な感じがしました.どれくらいの規模からマイクロサービスが効果を発揮するんだろう.

チューニングがすごく難しいらしく,高い技術力を持ったエンジニアが多く所属するメルカリだからこそ構築できたのかなと思いました.

新しいコードを恐れなく本番に出すためのimmutable infrastructureや,Infrastructure as codeの考え方は勉強になりました.

JSで黒魔術(りゅうさん)

りゅうさんの闇落ちしたJSのお話でした.

変態度が高かった(笑) 文字を表現するために色々な工夫をしていてすごいなと感じました. メタプロで自分の言語を作るのとても面白そうで, 僕も意味不明な言語とかつくってみたいと思いました.なのでこの本買っていろいろ試してみたいと思います!

bookwalker.jp

言語系の仕組みにも詳しくなれそう.

好きなことをやり続けるということ(ちょまどさん)

www.slideshare.net

エモエモな話でした. 自分の好きなことを続けることで,必ずそれが役に立つ時がくるというお話です.

技術系を学ぶ際は有効性のことを考えて勉強しがちなのですが,強いエンジニアの方々は有効性や利便性を置いて自分が面白いと思ったことに力を注いている人が多いなと感じました(りゅうさんとか)

自分の好きなことをやってるときのモチベーションって半端ないですよね... そこで得た知識が業務にも生きてくるのかな~と. 好きでやってる人には努力だけでは勝てない気がする.

考えてみると中学のことからPCいじるのが好きで,気づいたら情報系の大学でたのしくプログラミングをしていて,好きなことが今の自分に繋がっているなとか思いました

損得考えず,今好きで打ち込んでいることに全力になろうと思える内容でした.

What can Emacs be?

speakerdeck.com

こちらも変態度の高い内容でした☺️

Emacsがメディアプレイヤー&サーバになったりゲーム機になったりドッタンバッタン大騒ぎでした. エディタってなんだろう...笑

大いなるEmacs愛を感じました.ここまでEmacsをカスタマイズする熱量がすごい...!

ユーモア溢れる発表で笑いが絶えませんでした😁

vimでも色々できたりするのかな..? いろいろ調べて遊んでみたい

ラズパイは○○(miyaz697さん)

www.slideshare.net

少しギター触っているので自分に刺さる発表でした!

これで足元にエフェクター置かなくていいじゃん...!

しかもジャイロセンサーを入力値とし,ギターを振ると音が変わるという仕様! UI的にも扱いやすいしライブで演奏したら絶対面白い!

懇親会で話を聞いたのですが,音波を解析して弄ることでディストーション等のエフェクトを再現しているらしいです...!マジスゴ...!

意味不明プログラミング(tompongさん)

www.slideshare.net

一番変態度が高い内容でした('д`)

どこからこのような発想がでてくるんだろう...

実行不可な画像ファイルを実行可能にするアイデアがすごすぎて唖然としてました.

前夜祭のLTも合わせて,一見無理と思うことをやってのける技術と発想力に驚きと感動です(゚〇゚;)

おわりに

初めてのイベント運営でした. 準備するにあたり,どうやればいいかわからない状況に陥った際はslackで質問すると親切に教えてくれたので安心度が高かったです.
また周りに学生運営メンバーが多くいたので,確認がすぐに取れるのも恵まれた環境にいたなと思います.

反省点としては,もう少し積極的に発言して運営に関わるべきだったなと.結果的に先輩に負担を集中させてしまった気がする...m( )m 当日については電源ケーブルが少なくて悲鳴が上がっていたので,どう供給するか改善が必要かなと感じました.

イベント運用は初めてでしたが良い経験になったと思います.できれば来年も運営に関わっていけたらうれしいです.

カンファレンスはとても楽しかったし,いい刺激をもらいました. できればPaulさんの話を最後まで聞きたかった...! 感動したという声を多く聞いたので... エモい話は大好きです😊

学生が半数を占めていたということで,学生と社会人を繋ぐ良いイベントだったのではないかと思います.

ありがとうハッカーズチャンプルー!!