Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions 779/779.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
## 何も見ずに解いてみる

```cpp
class Solution {
public:
int kthGrammar(int n, int k) {
if (k == 1) return 0;
int k_parity = k & 1;
if (k_parity == 0) k_parity = 2;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この行が読みやすさに寄与しているか微妙だなと思い、取り除いてk_parity が 0 か 1 で良い気がしました。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そう思います。ちょっと1-indexedにとらわれすぎました。

int k_prev = k + 1 >> 1;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+>> のどちらの優先度が高いか、分かりづらいように思いました。

int k_prev = (k + 1) >> 1;

int prev = kthGrammar(n - 1, k_prev);
if (prev == 0 && k_parity == 1 || prev == 1 && k_parity == 2) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k_parity == 2 の時には prev とは違う文字になるの方が伝わりやすいと思いました。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

反転するという捉え方が書いているときになかったのでこんな感じになってしまいました。
ただその捉え方をするなら結局while文などで書いたほうがいい気もしますね。

return 0;
} else {
return 1;
}
}
};
```

1-indexedに慣れてなくて難しい

## 他の人のコードを見てみる

https://github.com/olsen-blue/Arai60/pull/47/files
https://github.com/Fuminiton/LeetCode/pull/46/files
https://github.com/ryosuketc/leetcode_arai60/pull/35/files
https://github.com/Ryotaro25/leetcode_first60/pull/49/files

後半部分が前半部分を反転したものになっている。なるほど。
ビットの数が反転した数であるというのも言われてみればたしかに。2で割ったときに余りが出る回数と考えると納得。

popcountの実装っぽいやつを一つ見つけました
https://github.com/llvm/llvm-project/blob/main/flang/include/flang/Common/bit-population-count.h
まとめてシフトしたほうが1個ずつシフトして数を数えるよりもCPUに対しての命令の数が少なくできてうれしいということですかね?

leetcodeでいろいろ実行していたら言われたが、`<<`や`>>`が`-`や`+`よりも優先度が低いというのは結構意外かも。
https://en.cppreference.com/w/cpp/language/operator_precedence.html

1-indexedのままで記述しようとしたら下のコードみたいになりました。結構大変

```cpp
class Solution {
public:
int kthGrammar(int n, int k) {
int result = 0;
while (k > 1) {
if (!(k & 1)) {
result ^= 1;
}
k = (k + 1) >> 1;
}
return result;
}
};
```

https://cpprefjp.github.io/reference/bit/popcount.html
https://learn.microsoft.com/ja-jp/cpp/cpp/data-type-ranges?view=msvc-170

## 最終コード
```cpp
class Solution {
public:
int kthGrammar(int n, int k) {
if (n <= 0 || k <= 0 || k > 1 << (n - 1)) {
throw std::invalid_argument("invalid argument");
}
return std::popcount((unsigned int)k - 1) & 1;
}
};
```