2022-09-22 PAST #10 の I を解いた / twiq 実装メモ (2)
PAST #10 : 第10回 アルゴリズム実技検定 過去問 の I を解いた。
- I - 対称変換
https://atcoder.jp/contests/past202203-open/tasks/past202203_i
- 提出: https://atcoder.jp/contests/past202203-open/submissions/35047419
- 操作が 0 回で一致する場合は
S = T
なのでソートして一致するかを調べれば良い - 操作が 1 回で X 軸に平行な直線で対称移動する場合は
S
とT
の点のX
座標は一致しY
座標はどこかを基準に対照なので、S
をX
の昇順Y
の昇順T
をX
の昇順Y
の降順で並べて、 1 件目で基準位置を求めた後残りがすべて一致することを調べれば良い - Y 軸に平行な直線で対称移動する場合も同様に考えれば解ける
- 二つの点の間を取ると小数になるが、間を取る必要はなくて和をとって一致していれば十分のはず
実装メモ
2022-09-21 の EventStream の続き。
Vec<Event>
となっているがEventStream
にしたほうが良い箇所がありそうEventStream
は単一のEventStreamId
を持ち、単調増加するEventStreamSeq
を持つ- ↑の定義から一部は
Vec<Event>
で残すことになりそう (EventStreamId
を横断する場合がある)- 「単一の
EventStreamId
を持つ」という部分を削る選択肢もあるだろうけど、現状はEventStream
のグループごとに取り得る event type が分類されているので、EventStreamId
ごとに区切るほうが良さそうEventStream
は aggregate の実装の共通部分を削減する上で効果がありそうEventStream
への追加のためにEventStreamSeq
の増加など定形処理が多いので削れそう- 現在の目標から外れているので保留する
- 空の
Vec<Event>
はあり得るか (空を許容するか) - 空を許容しない場合は
EventStore::find_event_stream
の戻り値はEventStream
ではなくOption<EventStream>
になる - 空を許容する場合は
EventStreamId
を保持すべきか - 空を許容かつ
EventStreamId
を保持しない場合はEventStream::id
の戻り値はEventStreamId
ではなくOption<EventStreamId>
になる EventStream
から aggregate を復元する場合にEventStream
が空で得られているとOption<A>
を返すべきところでResult::Err
になりそう (判断が面倒になりそう)- 取り得る状態をより簡素にするため、今回は空を許容しない形で進める
EventStream
の属性。
id
,seq
,events
を追加したid
はすべてのVec<Event>
に共通のEventStreamId
id
は取れないと不便そうseq
はVec<Event>
の最後のEvent
のEventStreamSeq
- 永続化する際に更新前・更新後の
EventStreamSeq
が必要になる - 更新前・後の履歴管理は複雑になるので避けて aggregate ごと clone する
Clone
をderive
に入れておく必要があるevents
はVec<Event>
- 永続化する際に 1 件ずつ
Event
を取り出したいため - 順序は
EventStreamSeq
の昇順で問題ないはず - aggregate では
Event
の追加がある EventStream::push(Event)
として単純にEvent
を追加するのは欲しいEventId
の生成やEventStreamId
の指定やEventStreamSeq
のインクリメントを自動でやってほしい- 名前に迷う
- もう
Event
の生成はほとんど隠蔽してしまっても良い気もする - 基本的なユースケースとしては
EventData
を渡して残りの情報は保管してもらうで良さそう EventStream
自体の生成はどうなる……?Vec<Event>
から生成する想定だけど最初のEvent
の生成を隠蔽してしまうと困るEventStream::empty(EventStreamId)
のような形で生成できると良いけど空は許容されていないEventStream::generate(EventData)
EventStream::push(EventData)
EventStream::push_event(Event)
Event
を push することのほうが少なそうなのとgenerate
側をEventData
にしたのでpush
をEventData
に譲ってpush_event
とした
今日のコミット。