メモやらログやら

考えたこととかメモする

失敗を大事にしたいと思っている

「失敗」に関して、最近なんとなく思っていることについてメモ。

失敗は不可避不可欠

  • 失敗は避けられない(永遠に成功し続けることは不可能)
  • 失敗しない = 過去の成功パターンの繰り返し -> 改善や進歩がない
    • 変化しない = 停滞 = 相対的に後退している
    • 失敗しない = 新しいことに挑戦していない可能性 -> 個人的につまらん
  • 失敗の原因を考え、改善していくことが大事

失敗に良し悪しはないのでは?

  • 失敗とは:そのときある取り組みや行動がその時点でうまくいっていないように思われること。
    • 失敗して落ち込んだり、引きずってさらにミスなどを犯せば悪い失敗といえるかも?
    • そこから改善案を見つけたり、なにか気付きが得られれば、その時点で成功するよりも、大きな価値があるかもしれない。
    • 要は考え方の問題
  • ある行動に失敗したことがマイナスの影響を及ぼす、ということと、失敗が悪いこと、というのは同じ問題ではない
  • ふりかえると、「あそこでミスっておいてよかったな」というのがちょいちょいある = 失敗は解釈次第

とはいえどんな失敗でも受け入れられるわけではない

  • 失敗に価値があること ≠ なんでも失敗してもいい
  • 失敗したときにソフトランディングできるなら、その失敗は受け入れやすい
    • なので、うまく失敗する方法(こけても泣かない方法)を身に着けておくのが大事
    • 助けてくれる人が周囲にいること、誰かが失敗したときに助けてあげられることも大事
      • コミュ力の問題ではなく、普段から互いに気にかけあう(気にかけていることを互いに伝え合う)ことが大事なのかも。
  • うまく失敗するために、(変な表現だが)失敗の練習が必要

うまく失敗するためには

  • そもそも失敗した場合の対応策を行動を起こす前に考えておく(こけて泣かない方法、すぐに立ち上がる方法を身に着ける)
    • これは広くやられていると思う
    • とはいえ、事前にすべての失敗を考慮できるわけではない。
  • 持っている勝ちパターンから外れた行動をたまにとる(探索的な行動をとることも必要)
    • カオスエンジニアリング的な考え方
    • 想像しない良い結果が得られる可能性
  • この時間は反省する/落ち込む時間、と決めておき、それ以降は分析する。
    • エシディシの「あァァァんまりだァァアァ」みたいな行動をとり、切り替える。
    • 失敗に傷ついたり、落ち込んだりしてはいけないわけでは決してない。そこにとらわれ続けるがよくないだけ。

失敗を受け入れる

  • 自分の失敗
    • 改善点や新しい観点が得られる
    • 引きずらなくなる
  • 他人の失敗
    • 腹が立ちにくい
    • 建設的

チェック

  • 最近ずっと失敗してない -> 持ってる勝ちパターンを使ってるだけで改善がない可能性。挑戦していない可能性
  • 失敗続き -> 失敗から学んでない可能性。学んだ情報を生かせる状態にない(外乱や体調不良などの問題)。そもそもそこに勝ち筋がない可能性(どれだけ手を尽くしてもどうにもならない状況はある)
  • 失敗を過度に肯定的・否定的にとらえてしまう -> 両側面を書き出すなどしてみる。失敗そのものに+や - のラベルがあるわけではない。うまく利用する。また、過度に否定的にとらえてしまう場合、心身の不調をうたがう。

またなんか思いついたら書く

AtCoder Beginner Contest 147 C

・N<=15なので全探索可能

・与えられる証言について、不親切な人の証言は参考にならない

・グラフっぽい構造ができそうだからといって、なんでもグラフにするのはよくない

 

まず問題の考察をするときに、

・全探索は間に合わないかどうか

を考えて、間に合うなら全探索でOK。また状態の取り方を変えることで全探索できる場合もある。今回は、全探索可能であり、不親切な人の証言を無視することがちゃんとわかれば解けるはずだった

 

atcoder.jp

 

CODE FESTIVAL 2017 qual B:C - 3 Steps

最近キョウプロを初めて一か月ぐらいで購入してすぐに投げた蟻本をやり直していて、2部グラフをやったので問題を探して挑戦した。

問題読んだけれども2部グラフどこで使うんだろうってなった。

解説読むとすごい分かりやすかったが、偶数個離れたところに奇数で行ける道のりが一つでもあれば(非2部グラフ)、最終的にすべてのノードが辺でつながり、なければ(2部グラフであれば)奇数個離れたやつがつながる、という感じだった。

これは面白かったので自分でも解けるようになりたい。

atcoder.jp

ABC80-D

チャンネルごとの状態が録画中or録画していないなので、各時刻ごとに全チャンネルの録画or未録画を求めて、最後に各時刻を見ていって一番録画しているチャンネルが多いタイミングの録画チャンネル数が答え。
チャンネル数が30と少ないので10^6オーダーでpythonでも間に合う。

atcoder.jp


と、解法は難しくないのだが、各時刻について、全チャンネルの状態を見るときに2重ループを使うのを解消できないとおもったら、うまいことやってる回答をしている人がいたので自分向けにメモ。

a = [[1,2,3], [4,5,6], [7,8,9]]

print(a)
# [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print(*a)
# [1, 2, 3] [4, 5, 6] [7, 8, 9]

print(list(map(sum,zip(*a))))
# [12, 15, 18]


変数にポインタ(?)つけるとリストの要素を出力
zipで複数のリストを一括して操作
mapは第一引数の関数を第二引数に実行してもどす。
上の例では、zip(*a)で3つのリストの同じインデックスについてsumを行い、リストにしている。

atcoder.jp

200msぐらい早くなった。自力で解けても解説とほかの人の解法はみたほうがいいなやっぱり。

AtCoder ABC142 参加記録

Dまでの4完だったが、Dを解くのに時間をかけすぎた。

反省するべき点はあるけれど、実装力と論理的思考力はそこそこの水準になってきていると思っているので、うっかりミスとかを減らしていくことでどこかで飛躍的にパフォをあげられる気もする。また、Dは時間はかかったとしてもだいたい解けるようになってきているので、400点問題の精進もしつつ、500点問題も挑戦していく必要がある。

 

A問題

N=1かそうでないかで分ける。奇数の個数はN>=2のとき、N/2の小数点切り上げしたものになるので、これをNで割れば奇数の確率が求まる。

atcoder.jp

 

B問題

これは数えるだけ。頭使わない分Aより簡単な気もする。

atcoder.jp

 

C問題

登校時点で教室にいた人数が自分含めてA[i]なので、order[A[i]-1] = i+1 なるorderを用意してあげるとよい。

atcoder.jp

 

D問題

AとBの共約数のリストを求める→素でない約数を消していく

の手順で解いた。約数のリスト作成でミスするという作問者も意図していないであろうところでつまってしまった。

pがAの約数であるとき、(A/p)もAの約数という処理を入れるのを忘れていた。

たぶんAとBを素因数分解してsetの論理積で共通の部分をとるのが楽かな?

atcoder.jp

素因数分解して集合の論理積をとる方法で解きなおしたら早い&スッキリしてミスもなくできた。やっぱり変に愚直に実装せず、スマートな解き方の方がいいよなぁなどと感じた。

atcoder.jp

 

E問題

解けなかった。どう考えてもDPだよなとは思ったけど、DPは基本的な奴しかまだ解けないのであきらめた。

 

 

 

gRPCメモ 概要

gRPCとは

そもそもRPCとは

Remote Procedure Callの略。ここでいうProcedure=手続きは関数ぐらいの意味合い。
雑にいうと、ローカル環境で実行を命令した関数が、実際は別の環境で行われて処理の結果だけ享受できる感じ。
ローカルで関数を動かしてDB側でクエリが実行されるみたいなを想像するとわかりやすいか。

RPCの嬉しいところ

  • 別のマシンで処理して結果だけ受け取る(サーバ-クライアント、分散処理)
  • サーバとクライアントの 双方APIを実装し、通信時の規約が決まっていればよいので、OSやプログラミング言語などに依存しない。(逆に言うとこれらが決まってないと使えない)

RESTとの比較

RESTはURIリクエストメソッドベースで動作する。
ざっくり言って、RPCの方がやり取りされるデータの粒度というか規約やスキーマが細かいため、変更を加えにくい印象。そのため、外に開かれたWeb系のシステムには使いにくい。また、RPCは複数環境間で型などの整合を保ちつつ中身の処理を実装する必要があるので自分で丸っと作るのは難しい。インタフェースだけIDLという言語(というか、インタフェースを定義するための言語)で定義し、そこから書く環境の言語に向けたコードを生成、各環境で中身を実装することになる。 一方で、RESTだと、このパスにこのリクエストメソッドで来たときはこのハンドラが動作する~みたいなのを書き連ねなければならないためコードは冗長になる。

で、gRPCって?

Googleが作ったRPCのフレームワーク(gはgoogleのg)
RPCにおける、複数の環境間で守るべき規約の部分をうまいこと作成してくれる(Protocol Buffersを用いて、シリアライズをいい感じにしてくれる)

Protocol Buffersなんやねん

複数環境間で通信をうまいことするためにGoogleが作ったシリアライズのためのフォーマット。
情報のやり取りをjsonとかXMLでもできるけど、サイズやパース効率等がこれらより良いため、通信&パースが早く行える。
1. .protoという名前のファイルにAPIの構造というかリクエストやレスポンスを定義 2. 上記ファイルをコンパイルすることで各言語向けのコードが生成される 3. 2で作られたファイル内の構造体やインターフェースを使って実装。複数環境間でいい感じにやりとり出来る。

Protocol Buffersのメリット、デメリット

  • メリット

    • RESTよりコード&URI周りが汚くならない
    • 型が利用できる(URIだと無理)
    • 各言語向けにオブジェクトなどを自動で作ってくれるので、シリアライズに気を使わなくていい
  • デメリット

    • jsonをパースしてはい終わりみたいにはならないため、扱いは難しい。
    • .protoに変更を加えると、関係する環境のすべてに変更を反映する必要があるため、Webのサーバ、クライアント間では使えないっぽい。バックエンド側の各アプリとかの通信を高速でやるのに使う
    • 生データがやり取りされるわけではないので、問題が起こった時の切り分けがちょっと大変かも

Protocol BuffersはなんとなくわかったけどgRPCは結局なにがうれしいねん

Proto Buffによるシリアライズ周り&通信周りの処理を提供してくれる。この辺りを提供してくれるので、実際に行いたい処理の作成に集中できる

気になるところ

  • Goだとテスト関係の機能が標準で提供されてて非常に助かるけど、gRPC導入した場合のテストってどうなんだろう?なんか難しそうなイメージ
  • gRPCに限った話ではないけど、runeみたいなGo独特の型とかは使える?各言語間の型の互換性とか気になる
  • 概要はつかんだ気がするので、今度は実際に使ってみたい

参考