-
Notifications
You must be signed in to change notification settings - Fork 0
Create 6. Zigzag Conversion.md #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| # 6. Zigzag Conversion | ||
| ## STEP1 | ||
| - 何も見ずに解いてみる | ||
| - 言われたことをやる。numRows が 1 の時は先に処理しておくとよさそう。 | ||
| - 最終行をよりよく書く方法があるかわからない。 | ||
| ```python | ||
| class Solution: | ||
| def convert(self, s: str, numRows: int) -> str: | ||
| if numRows == 1: | ||
| return s | ||
|
|
||
| row_to_letters = [[] for _ in range(numRows)] | ||
| direction = 1 # 1: going down, -1: going up | ||
| row_index = 0 | ||
| for letter in s: | ||
| row_to_letters[row_index].append(letter) | ||
| if row_index == 0 and direction == -1: | ||
| direction = 1 | ||
| elif row_index == numRows - 1 and direction == 1: | ||
| direction = -1 | ||
| row_index += direction | ||
| return "".join("".join(row) for row in row_to_letters) | ||
| ``` | ||
| - 行の位置は計算できる。こちらの方がわかりやすいと思う人もいそう。 | ||
| ```python | ||
| class Solution: | ||
| def convert(self, s: str, numRows: int) -> str: | ||
| if numRows == 1: | ||
| return s | ||
|
|
||
| row_to_letters = [[] for _ in range(numRows)] | ||
| num_letters_in_cycle = 2 * numRows - 2 | ||
| for i, letter in enumerate(s): | ||
| position_in_cycle = i % num_letters_in_cycle | ||
| if position_in_cycle < numRows: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私も同感です。 |
||
| row_index = position_in_cycle | ||
| else: | ||
| row_index = num_letters_in_cycle - position_in_cycle | ||
| row_to_letters[row_index].append(letter) | ||
| return "".join("".join(row) for row in row_to_letters) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. join() が 2 重になっているのがやや読みづらく感じました。 2 行に分けると読みやすくなるかもしれません。 rows = ["".join(row) for row in row_to_letters]
return "".join(rows)There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rows = ("".join(row) for row in row_to_letters)とすると、Generator で副作用がある場合は等価ではないですね。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 差異があるケースは以下のようにあると思いますが、想定されているケースと合致していますか? counter = 0
def f(row):
global counter
counter += 1
return "".join(row) + str(counter)
row_to_letters = [["A"], ["B"], ["C"]]
counter = 0
rows = [f(row) for row in row_to_letters]
counter = 100
print("".join(rows)) # A1B2C3
counter = 0
rows = (f(row) for row in row_to_letters)
counter = 100
print("".join(rows)) # A101B102C103There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. そうですね。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。意外と気にすることが多いですね。 import itertools
print("".join(itertools.chain.from_iterable(row_to_letters))) |
||
| ``` | ||
|
|
||
| ## STEP2 | ||
| ### プルリクやドキュメントを参照 | ||
| - https://github.com/olsen-blue/Arai60/pull/61/files | ||
| - 進む方向をフラグで管理する書き方もある。たしかに、STEP1で書いた direction は方向だけと読まれる可能性あり。step はありかも。 | ||
| - https://github.com/olsen-blue/Arai60/pull/61/files#r2040670667 | ||
| - itertools.batched を使った面白解法。 | ||
| - https://docs.python.org/3/library/itertools.html#itertools.batched | ||
| - https://github.com/olsen-blue/Arai60/pull/61/files#r2042314581 | ||
| - 以下の二つは同じ | ||
| `"".join("".join(row_chars) for row_chars in rows)` | ||
| `"".join(c for row_chars in rows for c in row_chars)` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 内包表現を 2 重にすると読みづらく感じます。原則避けたほうが良いと思います。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. あ、これ結果は同じですが、上は文字列を複数回 join していますが、下は Generator を利用して join 一回です。 |
||
| - for の順番にあまり納得がいかない。 | ||
| - https://docs.python.org/3/reference/expressions.html#generator-expressions をみると以下のよう。 | ||
|
|
||
| generator_expression ::= "(" expression comp_for ")" | ||
| comp_for ::= ["async"] "for" target_list "in" or_test [comp_iter] | ||
| comp_iter ::= comp_for | comp_if | ||
|
|
||
| 当てはめると | ||
| (1) c (2) for (3) row_chars (4) in (5) rows (6) for c in row_chars | ||
| (1) expression (2)"for" (3) target_list (4) "in" (5) or_test (6) comp_iter | ||
| のように読まれるので前の for が外側の for になる。全て追えていないがおそらく expression には comp_iter は含まれないため、逆の解釈はできない。 | ||
|
|
||
| - https://github.com/hayashi-ay/leetcode/pull/71/files | ||
| - 4th の方向管理はシンプルでいいですね。 | ||
| - row_index を先に進めてから、方向の反転をすればよい。 | ||
|
|
||
| ## STEP3 | ||
| ### 3回ミスなく書く | ||
| ```python | ||
| class Solution: | ||
| def convert(self, s: str, numRows: int) -> str: | ||
| if numRows == 1: | ||
| return s | ||
|
|
||
| row_to_letters = [[] for _ in range(numRows)] | ||
| row_index = 0 | ||
| direction = 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私は bool の方が読みやすく感じますが好みの範囲だと思います。 |
||
| for letter in s: | ||
| row_to_letters[row_index].append(letter) | ||
| row_index += direction | ||
| if row_index == 0 or row_index == numRows - 1: | ||
| direction *= -1 | ||
| return "".join(c for row in row_to_letters for c in row) | ||
| ``` | ||
| 練習として書いていて思ったが、Generator Comprehension の nest は書きにくいし読みにくい。 | ||
|
|
||
| 3分,2分,2分で3回Accept | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この行は、2倍する意味や-2する意味のコメントがあると親切だと思いました。