0:00 ブラタモリの黒部ダム回再放送とヒーリングタイムを見届けずに寝る。

最初に目が覚めたのは 5:00 前だが 7:40 起床。寝坊しないように午前中に用事を入れてある。 朝飯は納豆とおにぎり。久しぶりに歯茎が一部腫れている。これは嫌な予感。

スッキリなどを観ながら PC で時間つぶし。

9:15 外出。隅田公園経由で区役所へ。雨はまだ降っていない。

9:30 一階のハローワーク出張所で約束の打ち合わせ。 怒られることもなく 10 分で就労活動報告終了。次回の予約でカレンダーを見たら、妙な祝日があることに気づく。 これはオリンピック延期の残滓みたいなものだな。トイレを済ませて辞去。

10:00 向島の部屋に戻る。昨晩のシャンテン数プログラムの続き。 きのうの日記のロジックで正しいが、呼び出される補助関数が未完成だ。 一盃口みたいに同一順子が二個ある場合に正しく動いていないので要修正。 手抜きだが、ループ中の ifwhile に置き換えれば結果は正しくなる。

あと字牌の面子・搭子抜き関数が未実装。これはすぐに書ける。

気分転換に送付状と履歴書の更新をしておく。タイムスタンプがあるのが面倒な。 今日紹介状をもらうのはやめよう。

13:05 服を着て外出。三省堂書店で雑誌チェック。アエラとか週刊プレイボーイとか置いてあるのか。

13:50 ビッグエー墨田業平店。191 円。ペットボトルが古くなったので買い替える。

  • 麦茶 500ml
  • ベーコン&コーンマヨパン
  • メロンパン

柳島児童遊園でおやつ休憩のあとに横川コミュニティー会館図書室に行く。 新聞と統計解析を読む。いしいひさいち先生のマンガが平積みの商品を下から取り出すのはセコいと断罪してくれていてありがたい。 あれはなにか厭な感じがすると不思議だったが、セコいからなのか。

ハローワーク墨田で求人検索。応募のストックが切れたから、これまでに印刷した求人票を吟味したい。

タイトー F ステーションオリナス錦糸町店。 ビートマニア ARENA 最終日につき 2 クレ消費。やはり人と当たらない。 MJ プロ卓東風戦で 3 クレ消費。

【SCORE】
合計SCORE:+34.0

【最終段位】
四人打ち段位:魔神 幻球:16

【7/8の最新8試合の履歴】
1st|----**--
2nd|--------
3rd|---*---*
4th|------*-
old         new

【順位】
1位回数:2(40.00%)
2位回数:0(0.00%)
3位回数:2(40.00%)
4位回数:1(20.00%)
平均順位:2.40

プレイ局数:23局

【打ち筋】
アガリ率:21.74%(5/23)
平均アガリ翻:4.40翻
平均アガリ巡目:14.00巡
振込み率:4.35%(1/23)

【7/8の最高役】
・跳満
・跳満

久々に葛飾区の某上級プレイヤーと対戦。また立石に行きたいものだ。

面に表示されるシャンテン数を私の脳裡で計算した値と比較して検証する。 どうも 0 面子 3 対子を七対子の 3 シャンテンとみなすようだ。

18:10 カスミオリナス錦糸町店。336 円。きくらげと豚肉の炒め丼。

18:35 ビッグエー墨田業平店。280 円。

  • シュークリーム
  • 小粒納豆 (3)
  • ふっくらおむすび昆布
  • 大きなおむすびツナマヨ

18:50 向島の部屋に戻る。いきなり晩飯にする。日が暮れたら電話ボックスに移動する。

19:50 から電話ボックス作業。メールなどに異状なし。20:30 に部屋に戻る。 入浴して白ブリーフ一丁でテレビを観る。

シャンテン数の件、搭子オーバーのときの考慮が抜けている。 人のせいにするわけではないが、きのう見た某ページ言及されていなかった。 5 個以上の搭子は要らないので 4 との最小値を取って調整するのが良さそうだ。 あとは手牌が短いときの調整をして完成。テストケースを増やしたい。

麻雀の練習をして寝る。

Programming Notes

きのうの日記のコードを修正する。これ単体を切り出してコマンドラインツールに仕立て直していろいろと試したい。 もしそうするときは国士・チートイモードも組み込む。

def count_shanten_std(player_hand: Union[Counter, Iterable]) -> int:
    """Count the shanten number of player's hand to 4-melds-1-pair form.

    >>> count_shanten_std(tiles.tiles('3899m3457p88s南白発'))
    4
    >>> count_shanten_std(tiles.tiles('3899m3457p88s南発発'))
    3
    >>> count_shanten_std(tiles.tiles('389m3457p888s南発発'))
    2
    >>> count_shanten_std(tiles.tiles('89m23457p888s南発発'))
    1
    >>> count_shanten_std(tiles.tiles('88m23457p888s南発発'))
    1

    >>> count_shanten_std(tiles.tiles('112233m258p39s西中'))
    4

    >>> count_shanten_std(tiles.tiles('1289m1289p1289s北'))
    4

    >>> count_shanten_std(tiles.tiles('5566m3477p56s'))
    2
    >>> count_shanten_std(tiles.tiles('566m77p56s'))
    1
    """

    if not isinstance(player_hand, Counter):
        player_hand = Counter(player_hand)

    num_tile = sum(player_hand.values())
    if num_tile % 3 != 1:
        raise ValueError('the number of tiles must be 3n + 1.')

    if num_tile == 1:
        # Obvious tempai.
        return 0

    part_m = player_hand & FILTER_CHARACTERS
    part_p = player_hand & FILTER_CIRCLES
    part_s = player_hand & FILTER_BAMBOOS
    part_m, part_p, part_s = (tiles.convert_suit_to_number(suit_part)
                              for suit_part in (part_m, part_p, part_s))

    melds_m, melds_p, melds_s = (
        remove_melds(suit_part, _all_melds_suit) for suit_part in (
            part_m, part_p, part_s))
    pairs_m, pairs_p, pairs_s = (
        remove_pairs(suit_part, _all_pairs_suit) for suit_part in (
            part_m, part_p, part_s))

    hand_h = player_hand & FILTER_HONORS
    melds_h = remove_melds(hand_h, _all_melds_honor)
    pairs_h = remove_pairs(hand_h, _all_pairs_honor)

    # 13, 10, 7, 4, 1 -> 8, 6, 4, 2, 0
    num_shanten = (num_tile - 1) // 3 * 2
    num_shanten -= sum(len(melds) for melds in (
        melds_m, melds_p, melds_s, melds_h)) * 2
    num_shanten -= min(4, sum(len(pairs) for pairs in (
        pairs_m, pairs_p, pairs_s, pairs_h)))

    return num_shanten