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
97 changes: 97 additions & 0 deletions 779. K-th Symbol in Grammar/779. K-th Symbol in Grammar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# 779. K-th Symbol in Grammar
## STEP1
- 何も見ずに解いてみる
- 行数を一つずつ減らしていく。ある行において、文字列の前半にいたら index をそのままに行数を -1 して良い。文字列の後半にいたら、index から文字列の半分の長さを引き、0と1を反転させた回数を +1 し行数を -1 する。
- 他の問題より不正な入力が入りやすいと思ったので、チェックしたい。
- 書いている段階では明確に整理できていなかったので、読み返すとコードが読みにくい。

```python
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
n -= 1
k -= 1

if n == 0:
if k != 0:
raise ValueError("invalid input")
return 0

num_symbols = 2 ** n
count = 0
while num_symbols >= 2:
if not 0 <= k < num_symbols:
raise ValueError("invalid input")
num_symbols //= 2
if k >= num_symbols:
count += 1
k -= num_symbols
if count % 2 == 0:
Copy link

Choose a reason for hiding this comment

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

return count % 2 で良いと思います。

return 0
else:
return 1
```

## STEP2
### プルリクやドキュメントを参照
- https://github.com/olsen-blue/Arai60/pull/47/files#diff-da439603310f08640b8dab0ec6cfc15251b5669e04e4effc5795dbe1f506a8daR43
- k の偶奇での場合分けは気が付かなかった。局所的な関係性で考えるパターン。
- k % 2 で場合分けするならば、(k+1) // 2 について k // 2 で良い場合は使い分けたい気がする。下記のように if 文の外に置くのであれば当然 (k+1) // 2 でないといけない。

```python
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
if n == 0:
return 0

previous_symbol = self.kthGrammar(n - 1, (k + 1) // 2)
if k % 2 == 0:
return 1 - previous_symbol
else:
return previous_symbol
```
- https://github.com/olsen-blue/Arai60/pull/47/files#diff-da439603310f08640b8dab0ec6cfc15251b5669e04e4effc5795dbe1f506a8daR65
- よくみると n ではなく k に注目しても良いことがわかる
- https://github.com/fuga-98/arai60/pull/46/files
- k のビットを考える方法。これは綺麗だけど思いつきにくい。
- https://docs.python.org/3/library/stdtypes.html#int.bit_count
```python
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
return (k - 1).bit_count() % 2
```

- 色々な実装パターンがあるが以下が一番理解しやすいと感じた。
```python
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
if n < 0:
raise ValueError("n must be positive.")
if not 1 <= k <= 2 ** (n - 1):
raise ValueError("k is out of range")

result = 0
while k > 1:
if k % 2 == 0:
result = 1 - result
k = (k + 1) // 2
return result
```
## STEP3
### 3回ミスなく書く
```python
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
if n < 0:
raise ValueError("n must be positive")
if not 1<= k <= 2 ** (n - 1):
raise ValueError("k is out of range")

result = 0
while k > 1:
if k % 2 == 0:

Choose a reason for hiding this comment

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

これ簡潔でいいですね。

result = 1 - result
k = (k + 1) // 2
return result
```

3分,2分,2分で3回Accept