blog.bouzuya.net

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 軸に平行な直線で対称移動する場合は ST の点の X 座標は一致し Y 座標はどこかを基準に対照なので、 SX の昇順 Y の昇順 TX の昇順 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 は取れないと不便そう
  • seqVec<Event> の最後の EventEventStreamSeq
  • 永続化する際に更新前・更新後の EventStreamSeq が必要になる
  • 更新前・後の履歴管理は複雑になるので避けて aggregate ごと clone する
  • Clonederive に入れておく必要がある
  • eventsVec<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 にしたので pushEventData に譲って push_event とした

今日のコミット。