+を使わずにAdd関数を作成する方法
下のコードが実際に足し算として機能するのか、8ビット計算で試してみた
int add(int a, int b)
{
while (b != 0)
{
int c = (a & b) << 1;
a ^= b;
b = c;
}
return a;
}
例1 44+33の場合
a= 44
b =33
1回目のループ
a = 00101100
b = 00100001
(a & b) << 1で、And判定してさらに左に1ビットシフト
00100000
c= 01000000
a^ = bでXOR判定
a = 00001101
b = 01000000
2回目のループ
a、bともに1のダブりがないので、全部0に
c = 00000000
a^ = bでXOR判定
a = 01001101 => 64+8+4+1 = 77
b = 00000000
で、この後にaが帰るから・・・確かに足し算後の値になる。
肝はcでの繰上げなんだな。
もう一こ例をば
例2 127+127の場合
01111111 => 127
01111111 => 127
c= 11111110
a = 00000000
b = 11111110
c = 00000000
a = 11111110 => 254
まじだ・・・すげえな、これ
01 2色塗りグラフ、ベルマンフォード法
例によってあり本の写経
2色塗り
vector<int> G[MAX_V];
int V;
int color[MAX_V];
// color edge c or -c
bool dfs(int v, int c) {
// paint edge with color "c"
color[v] = c;
for (int i = 0; i < G[v].size; i++) {
//隣り合う辺で頂点がcのものはスルー
if (color[G[v][i]] == c) return false;
//頂点が色なしの0場合、C色の頂点と隣合うので逆の色として―Cで塗る
if (color[G[v][i]] == 0 && !dfs(G[v][i], -c)) return false;
}
return true;
}
void solve() {
for (int i = 1; i<V; i++) {
if (color[i] == 0) {
// if edge i is not colored, paint edge with "1"
if (!dfs(i,1)) {
printf("No\n");
return;
}
}
}
printf("Yes\n");
}
ベルマンフォード法
// a cost from edge "from" to edge "to"
struct {int from, to cost; };
edge es[MAX_E]; // side
int d[MAX_V]; //shortest distance
int V, E; // V: qty of edge, E: qty of side
// Calculate distance from edge "s" to each edge
void shortest_path(int s){
for (int i=0; i<V; i++) d[i] = INF;
d[s] = 0;
while(true){
bool update = false;
for (int j=0; j< E; j++) {
edge e = es[j];
if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
//移動先の頂点までかかるコストが移動先の頂点が持っている総コストより小さいかどうか
d[e.to] = d[e.from] + e.cost;
update = true;
}
}
if (!update) break;
}
}
// 閉路を見つけるため。V個頂点がある場合、開いて入ればV-1個の捜査で終わる。V個を捜査するのであれば、それは閉路となる。
bool find_negativeloop() {
memset(d, 0, sizeof(d));
for (int i=0; i<V; i++){
for (int j=0; j<E; j++){
edge e = es[j];
if (d[e.to] > d[e.from] + e.cost) {
d[e.to] = d[e.from] + e.cost;
if (i == V-1) return true; //配列だから、マイナ1でV個扱い
}
}
}
return false;
}
新人エンジニアサバイバルガイド
ロシアの天才ハッカーによる【新人エンジニアサバイバルガイド】 - Qiita
1の技術の話のところでの講座リストにコンパイラなどの講座があったので、受講してみようかな。
というか、Googleが提供しているこのリスト(Students - Guide to Technical Development - Google Careers)は新人だけではなく、どのランクの人でも一通り受講してみる価値はありそう。
生きることと勝負事の関連性に気がついた話
いつものようにプールを1kmほど泳ぎ切った後に休憩していると、仕事をはじめてからはずっとオリてばかりだったなとふと気がついた。オリてれば、いずれ負ける。そんなことは十二分にわかっていたつもりだったけど、実際はわかっていなかったのかもしれない。
麻雀の中では、オリることは良いことではないと経験と知識から十二分に知っているのだけれど、仕事の場だとどうしても保守的に動くべきだと命令する自分がでていたのだ。確かに、ゲームだと失敗できて、人生では失敗できない。それは正しい。しかし、失敗を恐れて何もしないことは、果たして自分の人生を生きる戦略として正しいのだろうか?そんな後ろ向きのメンタリティだから、仕事ではよい結果も出ないし、モチベーションもあがらいのではないのか?もちろん、突っ張れば、いつかは間違いなく失敗する。しかし、失敗することで何か失うものがあるのだろうか?名誉?他人からの評価?これらは社会で生きる上では大事なものであることは間違いないが、そんなものに振り回されて良いのか?一見、子供じみたような思考だ。しかし、その子供じみた考えが、それからの数日間ずっと頭の中をグルグルと回っていた。
「オリることが悪いのは仕事でも同じ」という考えが正しいのでは?と後押しするような出来事がつい最近あった。その日はたまたま、知り合いの今後の身の振り方の相談を焼肉を食べながら受けていた。その知り合いとの会話の中で、ある小さな会社を経営している人と話をした話を聞かせてもらった。話が長くなるので、詳細は省かせてもらうが、知り合い曰く、その経営者は「オリないこと」が経営の上で最も重要なことだと言っていたそうだ。こんなにすぐに先日自分が思いついた結論を聞くことになるとは思いもしなかった。そういえば、サイバーエージェントの藤田社長も同じようなことを言っていたな・・・。
自分はよく「振込みを恐れて突っ張れなくなれば、おれは麻雀をやめる!」といつも言っているが、どうやら知らず知らずの内に「生きること」をやめていたようだ。結局のところ、生きるというのは「前に出続ける」という態度を取り続けることなのかもしれない。
呼吸を止めないことの大切さ
システマのブリージングを生活に取り入れてみた。
まだはじめて5日目だが、今までいかに自分が生活の中で呼吸を止めて、力を入れながら生活していたかが、よくわかる。
肩肘張っていきるという言葉があるが、まさにその言葉通り、肩に力を入れて日常を過ごしていた。
ただ、呼吸を止めずにし続けることは、想像以上に難しい。
いつの間にか、呼吸を意識することを忘れてしまう。とくに何かに集中して作業するときは顕著にそれがでる。
ゲームをするとき、コードを書くとき、メールを書くとき、誰かと話すとき、何かを考えるとき・思い出すとき・・・
一体、ふつうに生活している中でどれだけの回数、息を止めて生きているのだろう?と思うレベルで息を止めている。
呼吸を止める必要があるシーンももちろんあるだろう。
しかし、そういった強い集中力が必要なシーンでも、呼吸を止めていることを自覚しているべきだとおもう。
呼吸をしている状態が当たり前で自然な姿なのであって、止めている状態が当たり前ではいけない。
呼吸を止めたまま日常を過ごし続けると、どんどん身体がこわばってしまう。
こわばった身体は感性を殺し、感覚がマヒしたような状態になる。
そんな状態で生き続けていると、いずれは身体か精神を壊してしまう。
自分の中にあるセンサーが機能しなくなり、危険信号が出ているにも関わらず、無理をし続けようとするからだ。
人間の身体は自分が思っている以上に頑丈ではないということをもう少し知っておいた方がいいと思う。
身体を壊してから気づくことも時には大事だが、身体を壊さないことが一番よいのだ。
リングゲーム用メモ(ホールデム)
1.自分が勝っていると確信しているときは、大きく張ることがけっこう大事
2.ポジションの優劣がうまく機能するのは、水族館じゃないときに限る
3.オールインするなら、もっと早い段階からオールインすべき
4.自分のハンドがナッツの場合は、相手にオールインさせるように誘導することができればベスト
5.癖は誰にでもある。相手から感じ取れる気配や動き、いつもと違う違和感を見逃さないこと
1から、ある数より少ない数の中に含まれる素数を数えるには?
こんな感じかな
#include<stdio.h>
#include<math.h>
int prime(){
int N; // 与えられた数
int flag; //素数か否かを判定するためのフラグ
int ans = 0;
for (int i = 3; i < N; i+=2) { //2の倍数を除く
for (int j = 3; j <= sqrt(i); j+=2) { //約数を求める場合、ルートで得られた数以下のもので割り切れればOKなので
flag = 0;
if(i%j==0) {
flag = 1;
break; //割切れた時点で計算をカットして、計算量を減らす
}
}
if (flag == 0) ans++;
}
printf("%d\n", ans);
}
参考資料