ドミノソフト公式ブログ

合同会社ドミノソフトの公式ブログです。

CPUをNANDゲートからつくるゲームのすゝめ(Turing Complete)

ドミノソフトのqwavです。

Turing Completeの最終ステージまでクリアした記念にブログを書きます。

store.steampowered.com

恥ずかしながら私のCPUに対する理解がブラックボックスになっていて、CPUって実際何してるんだろう?と思ったのがこのゲームを始めたきっかけです。 (細かいことは知らんけど何かしらの命令にもとづいて何かしらの計算してるんでしょぐらいの理解)

ゲームのプレイ時間としては約40時間、WATER WORLDという実績(最終ステージをクリア時に付与)までプレイしました。 (正直いくつか解法がわからないステージもあり、攻略ブログやSTEAMにも解説があがっているので、そこをカンニングしてしまいました。)

ちなみにTUTORIAL COMPLETEという実績(実質CPU作成)の取得率が約5%、先ほどのWATER WORLDの実績の取得率は約2%と結構な人が投げ出しているみたいなので、ちょっとした自慢です。 (ちなみにSEKIROの葦名一心の実績の取得率は約20%でした。)

Turing Completeとは

宇宙人にさらわれた主人公が知能テストとして、NANDゲートを使ってCPUを作り、機械語・アセンブリ言語でのプログラミングを行い、お題をクリアしていくパズルゲームです。(さもなくばお前は喰ってやると言われます。)

宇宙人に攫われた

そんなことをいきなり言われても0からCPUをつくるのは私にはどうやっても不可能です。

しかし、ゲームではNANDゲートから他の論理演算ゲート(OR,AND,NOR,XOR)等をつくったり、加算器をつくったり、レジスタをつくったり、組み合わせて演算装置をつくったり等々のステージがあるので段階を踏んで一個ずつ理解を深めていけました。

またそのあとに、機械語・アセンブリ言語に関してもレベル別にステージがあるので、理解しやすかったです。 (最初は自分で作ったCPUで四則・論理演算をしてみるものから、ハノイの塔や迷路を解くような問題が与えらます。)

論理回路や機械語とは?等の説明はとくにないので、基本情報やらを何も知らないとこのあたりが結構きつそうです。

Turing Completeの良いところ・悪いところ

良いところ

  • ステップ実行しながらレジスタ・RAM・配線等に流れている値を視認可能
  • ほぼすべてのステージにテストケースが付いている(パスしないと次のステージに進めない)
    • パズルゲーム的には当たり前な感じはしますが、見方を変えればテスト駆動開発ができる
    • 実際オペコードを追加したときに意図していない値をレジスタに保存するようにしてしまい、それに気が付いて(場当たり的な)修正をすることができました。
  • ゲームなのでハードウェア的な不調の考慮は不要

悪いところ(あったらうれしい)

  • 最適な回路の組み方については学べない
    • 答えが一致すればOK、回路やプログラミングの中身はなんでもいいよという感じです。ここで学んだことを糧に専門的な教材に移るのがいいんでしょうね。
    • これを逆手に汎用CPUではなくそのステージ専用の回路・CPU作成、プログラミングをすることでスコアアタックが公式に行われています。どうやってそんなスコア叩きだせるの?と頭のいい人たちはすごいです。
  • 後半になっていくほどステージの説明が雑な感じ
    • このステージのインプットとアウトプットはなんなん?と何回かなりましたが、雰囲気でなんとなくわかる感じです。
  • (日本語翻訳について、有志による翻訳もありますがまだ充実してるとはいいにくいです。英語が分からない箇所はGooglePixelに翻訳をしてもらっていました。ありがとうGooglePixel)
    • (宇宙人が設定やジョークを言っているだけ(多分)のところも多いので、無視しても問題ないと思います。)

まとめ

2050円(2025/2現在)のゲームにどこまで求めているんだという話になりそうですが、 デバッガー、テストケース、ステップバイステップの教材、無限の資材を抱き合わせたバンドル商品と思うとかなり破格のお値段なのではないでしょうか。 セールも滅多に来ないみたいなので、欲しいときが買い時です。 (ちなみにこのゲームはアーリーアクセスで今も開発継続しているようなので、今後の進化にも期待です。)

レビューも中々おもしろいです。 steamcommunity.com

最後に

自分の中でブラックボックスだったCPUについてほんの少しだけ理解度が深まりました。 また、機械語・アセンブリ言語でプログラミングしていた・している方々には頭が下がる一方です。 これからは高級言語のありがたみを噛み締めていきたいと思います。

それでは。


↓は公衆の面前に晒すのは恥ずかしいかぎりですが私のゲームクリア時までにつくったCPUもろもろです。 ネタバレになるかもしれないのでこれからゲームをプレイしたい方は見ないほうがいいと思いますが、 画像も鮮明ではないので直接的なネタバレ(ぱっと見では回路を具体的にどう繋ぐみたいのはあんまりわからないはず)にはならないので、 つくる規模感が知りたい方はちらっと見てもいいかもしれません。

CPU図面

趣味で始める機械学習 ニューラルネットワークって何?

はじめに

こんにちは! ドミノソフトのkimi_dominoです。

趣味で機械学習の勉強をしていて、折角なので勉強したことをメモしていきます!初学者なので解釈や理屈の粗があったらスミマセン(TーT)

ニューラルネットワークって何?編です!

ニューラルネットワークとは?

Wikipediaからの引用です。

ニューラルネットワーク(英: neural network; NN、神経網)は、生物の学習メカニズムを模倣した機械学習手法として広く知られているものであり、「ニューロン」と呼ばれる計算ユニットをもち、生物の神経系のメカニズムを模倣しているものである。人間の脳の神経網を模した数理モデル。

何のこっちゃ?という感じですが、図に描くと以下のような感じのものです。

ニューラルネットワークは「入力層」「中間層」「出力層」から成っていて、それぞれ役割があります。次にそれぞれの層の役割について説明します。

入力層

私たちが持っているデータをユニットへ入力します。 例えば画像であるなら、画素数の数だけ入力するためのユニットがあり、そのピクセルの色(CMYK値やRGB値)が入力値だったりします。

中間層

入力ユニットから値を貰い、中間層の各ユニットで結果を解釈しやすいように加工するための役割を持ちます。加工した出力値を、次の出力層への入力値として渡します。

出力層

入力から得られる結果です。この結果は「確率」として得られます。イメージとしては、手書きで書いた数字が「1」である確率、「2」である確率...「9」である確率というイメージです。
もう少し抽象化すると、数字がC_1C_2....C_9という各クラスに属する確率が得られます。

ニューラルネットワークにおける学習とは、この得られる確率を正しいものに近づけるために行われます。この学習を理解するため、以下では理屈について見ていきましょう。

ベイズの定理

私たちはあるデータを持っていて、それをニューラルネットワークへの入力値とします。入力値を「\textbf{x}=(x_1,x_2,\ldots,x_n)^\top」と書きましょう。これがクラス「C_k」に属する確率を知りたいので、「入力\textbf{x}が得られている前提で、これがクラスC_kに属する確率」をP(C_k|\textbf{x})と書きます。これを条件付き確率と言います。

条件付き確率には、以下のベイズの定理が成り立ちます。

\displaystyle{P(C_k|\textbf{x})=\frac{P(\textbf{x}|C_k)P(C_k)}{P(\textbf{x})}}

条件付き確率の前後関係を逆に表せるんだな、という雰囲気で大丈夫です。右辺の分母を、確率の乗法定理を使って変形していきます。

P(\textbf{x})=\displaystyle{\sum_{i}P(\textbf{x}\cap C_i)}=P(\textbf{x}|C_k)P(C_k)+\sum_{i\neq k}P(\textbf{x}|C_i)P(C_i)

分子の形に合わせて、kとそれ以外に分解したいという感じです。よって次のように書けます。

\displaystyle{P(C_k|\textbf{x})=\frac{P(\textbf{x}|C_k)P(C_k)}{P(\textbf{x}|C_k)P(C_k)+\sum_{i\neq k}P(\textbf{x}|C_i)P(C_i)}}=\frac{1}{1+\displaystyle{\frac{\sum_{i\neq k}P(\textbf{x}|C_i)P(C_i)}{P(\textbf{x}|C_k)P(C_k)}}}

ここまで来たらもうひと踏ん張りです。分母に現れる分数部分を変形しましょう。

\displaystyle{\frac{\sum_{i\neq k}P(\textbf{x}|C_i)P(C_i)}{P(\textbf{x}|C_k)P(C_k)}}=\displaystyle{\frac{P(\textbf{x}|\bar{C_k})P(\bar{C_k})}{P(\textbf{x}|C_k)P(C_k)}}=\exp\left(-\log\displaystyle{\frac{P(\textbf{x}|C_k)P(C_k)}{P(\textbf{x}|\bar{C_k})P(\bar{C_k})}}\right)

ここで\expはネイピア数で、指数・対数の性質a=e^{\log_e a}\log a^{-1}=-\log aを使っています。
\expのなかに現れる確率の形は対数オッズと言い、互いに排反な確率の比となっています。これを\theta_kと置いてしまいます。
以上から、ベイズの定理から求めたい確率は次のようになります。

\displaystyle{P(C_k|\textbf{x})=\frac{1}{1+\exp(-\theta_k)}}=\sigma(\theta_k)

これはロジスティックシグモイド関数と呼ばれていて、以下のようなグラフになります(Wikipediaから引用)。

つまり、ニューラルネットワークでは、出力ユニットで対数オッズをシグモイド関数に入力する必要があります。これを式で書くと、出力y_k

y_k=P(C_k|\textbf{x})=\sigma(\theta_k)

ということです。では入力\textbf{x}しか知らない状況で、対数オッズ\theta_kはどうやって得るのでしょうか?

対数オッズの回帰

先に言うと、対数オッズ\theta_kを直線で近似します(これを線形回帰と言います)。

\theta_k(\textbf{z})=\displaystyle{\sum_{j}}w_{kj}z_j

ここで\textbf{z}中間層のユニットの出力=出力ユニットへの入力であり、w_{kj}回帰係数(重みパラメータ)と言います。つまり、ニューラルネットワークにおける学習とは、対数オッズを近似するためのw_{kj}を最適化することを言います。

直線で近似してよいの?という疑問が生まれるかもしれませんが、これは問題ありません。なぜなら、中間層の役割はデータを線形識別できる空間への写像となっているからです。Wikipediaから図を引用します。

左のグラフの白い点、黒い点がの集まりがクラスC_kに相当します。赤い線は識別曲面と言い、この曲面を境界としてクラスが分類されています。左の図は識別曲面が非線形です。
つまり中間層は、データ点をT:\textbf{x}\to\textbf{x}^\primeと写像Tによって、識別曲面が線形となるようにデータ集合を写像する役割を持てば、出力層で対数オッズを線形回帰して問題ないということになり、これもニューラルネットワークにおける学習の役割です。

最後に

入力データを中間層で写像をする、ということは入力データの情報(特徴)を出来るだけ残す必要があります(線形代数的に、写像Tが全単射であればデータの情報は欠落しません)。歴史的にどのような問題があり、試行錯誤があるのかは次回のトピックに残します。 さらに、ここで解説できなかった重みパラメータの最適化法(学習法)なども説明できればと思います。

ではまた~^-^

社会人学生生活1

こんにちは、summer_127です。 今年は社会人学生三年目です。2023年四月から電気通信大学・大学院情報理工学研究科・情報・ネットワーク工学専攻の南・古賀研究室に所属しています。 3年の長期履修コースを入学時に申し込み、現在(2025/1/31)はあと一年で卒業します。 この二年間の社会人学生生活をこの記事で振り返ってみます。

なぜ大学院に入りたいのか

実は、自分が奈良女子大学 生活環境学部 情報衣環境学科の四年生だった頃から、大学院に進学したいと思っていました。理由としては、より専門性のある知識を学びたかったからです。学部の授業は、三年生までは一般教養的な授業が多いのです。 三年生になると、ようやく情報科学科っぽい授業が多くなりました。しかし、この二年間だけでは、なかなか専門的な能力が身に付けません。学部を卒業する時は、プログラミング能力とか、アルゴリズムやコンピューターアーキテクチャの知識とかは、自分にはあまりないと気付きました。 情報科学科卒以外の学生と差はありませんでした。そこから、大学院に進学しないと思い始めました。

大学院に進学することは、どこかの研究室に所属することになります。そして、所属する研究室は、自分で選ばないといけません。まずは、自分の研究したい分野や、興味のある研究テーマなどを、自分で探さなければならなりません。 そのあと、自分のしたい研究を研究している研究室へアプローチします。残念ながら、その時学部四年生だった自分が、研究したい分野も興味のある研究テーマも一個もありませんでした。

「もしかして、社会人になってから、研究したい分野を見つけることができるかも。」と思い、就職しました。

社会人大学院生への道

2022年6月、ChatGPTが誕生する5ヶ月前、社会人三年目の私は、ようやくあるテーマに思いつき、勇気を出して電気通信大学の古賀久志准教授にあるメールを送りました。このメールを保存していませんので、記憶で再現してみます。

「近年では、LowCode開発やNoCode開発が注目されています。さらに、人工知能も進化しており、いつか私よりスピードが速くて綺麗なコードを書けるAIが現れるかもしれません。私はもう危機感を感じています。AIに代替されないために、もしくは、AIをよりよく活用するために、 AIを知ることがエンジニアである私にとても重要だと思います。先生の研究分野は、人工知能のコアと言えるアルゴリズムとビッグデータで、さらに機械学習やオンラインクラスタリングに関する論文も発表しており、自分がより深く勉強したい分野と合致しています。もしよろしければ、 一回研究室見学をお願い致します。」

詳しいことは覚えていませんが、こんな感じでメールを送りました。そのあと、無事に返信が来て一回研究室を見学しました。そして、研究室見学の時は、先生に研究計画書を書いてと言われました。

大学院社会人特別入試

電通大へ出願するために、色んな書類を集めないといけないですが、その中で一番大変なのは研究計画書です。先生は、この研究計画書を見て、志望する学生が修士論文を書ける学力と文書力があるかどうかを判断します。私は二週間もかけて研究計画書を書きました。大学院に在学中の友人にも 添削してもらいました。出願する一か月前、メールで先生に自分の研究計画書を送りました。

この後、二週間を経っても先生の返事が来ませんでした。「もう落ちたかな」と思いながら先生の返信を待っていました。幸い、研究計画書を送ってから三週間目の時に先生からOKの返信が来て、無事に認めてもらいました。あとは、電通大へ正式的に出願し、入学試験に合格することです。 実は、社会人入試と一般入試とは違い、研究計画書が先生に認めてもらえば、入学試験は99%合格するらしいです。

電通大の社会人特別入試は、口頭質問と面接でした。面接官は、自分の志望する先生を含めて4人でした。口頭質問は、4人の先生の前で、ホワイトボードでC言語のプログラミング問題を解いていけません。エンジニア三年目の私にとっては、割と簡単な質問だったが、超緊張で普段より十倍ぐらい汚い コードを書いた気がします。。。面接は穏やかで、変な質問はなかったです。

めっちゃくちゃ緊張していましたが、無事に合格しました。

次回は社会人大学院生一年目の生活について紹介したいと思います。

ワイヤレスイヤホン探索

はじめに

こんにちは。ドミノソフトのnct-dsです。

みんな大好きワイヤレスイヤホン。ええ。私も大好きです。 いくつも所持しているのに、セールになっているとついつい「こっちの方がいいかな?試してみようかな?」と買ってしまうんですよね。

しかし、どれを買ってもなんか違う。長時間つけていても不快感が少ないイヤホンが欲しいのですが、どれも2時間くらいで限界を迎え「ウゎァー」となって外してしまいます。 長い年月、そんな気持ちで理想のイヤホンを探し求め浪費を続けておりました。しかし最近ついに「これがゴールだ!」と思える商品に巡り会えたのです。

というわけで、これまでの探索の過程とともに私のゴールを簡単にご紹介いたします。(レビューではありません) なお、音質はあまり気にしませんので5,000YEN~10,000YEN程度のコスパモデルで選んでいます。 さすがに2,000YEN~3,000YEN程度のやつは音が変なのでナシです。

先鋒 カナル型

最初に購入したのは定番のカナル型でした。以下のモデルです。

  • Anker Soundcore Liberty Neo 2
  • Anker Soundcore Life P2 Mini

どちらも音質に不満はありませんでしたが長時間つけていると耳の中が蒸れます。カユイ。 蒸れないものを求めて・・・次へ。

次鋒 インナーイヤー型

次はインナーイヤー型を試しました。

  • JVCケンウッド JVC HA-F15BT-RB ワイヤレスイヤホン

形状が耳に合っていないみたいですぐ外れます。蒸れないのは良かったのですが・・・次。

中堅 オープンイヤー型(耳かけ)

今度はオープンイヤー型の耳かけタイプを試しました。

  • SOUNDPEATS(サウンドピーツ) GoFree2

こちらも蒸れは回避できましたが、長時間つけていると耳の上が痛くなります。 また、音質がスカスカで音漏れががが。まあこのタイプなら仕方ないか・・・。 うーん。次。

副将 ヘッドホン

ダメ元でヘッドホンを試してみました。

  • SOUNDPEATS(サウンドピーツ) Space ワイヤレス ヘッドホン

まあ当然蒸れますよね。カナル型のように耳の穴がピンポイントで蒸れるのではなく耳全体が熱くなります。(冬でも)

ただ、アクティブノイズキャンセリングは初体験だったのでなかなか新鮮でした。 また、バッテリーの持ちが良すぎて驚きました。でも次。

大将 オープンイヤー型(イヤーカフ)

最後にたどり着いたのはイヤーカフ型でした。

CCイヤーカフ – SOUNDPEATS JAPAN

これが素晴らしい。当然蒸れないですし、長時間つけていてもストレスがかなり小さい。 しかも音質が案外悪くないのです。音漏れも耳かけタイプより少ないですし非の打ち所がありません。 唯一の弱点はバッテリーの持ちが少し頼りないところでしょうか。とは言え、6時間程度は持つので許容範囲内です。

そんなわけでようやくゴールを迎えました。めちゃお勧めですよ。 なお、SOUNDPEATSが続きましたが案件(提灯記事)ではありません。全部自腹ですのでご安心ください。

以上です。皆様良い物欲ライフを。ではまた。

MarkItDownでGitHubのExcel差分が見やすくなった話

CEOの@uen0yamaです。

MarkItDownを使って、Excelファイルのコミット時にはMarkdownもセットで登録するよう構成したら、Pull RequestのExcelレビューがとてもスムーズになりました。

背景

みなさんはGitHubに*.xlsxとか*.docxとか突っ込んでますか?
*.docxの方は、わりとMarkdown形式に置き換わっているケースが多いのですが、*.xlsxはまだまだ現役なんですよね。
何らかの規則に基づいた表などは、まだまだMarkdownのテーブルでは機能不足なので、Excelに頼るケースが多いです。

Excelの変更についてのPull Requestレビューでは、どこを修正したの? が、依頼者の自己申告だったりしています。
(WinMergeとかで差分抽出もできますが、手順が必要でめんどくさい)

この運用方法、なーんか危なっかしいなー、と思っていたところに現れたのがMarkItDownでした!

設定方法

1. PythonとMarkItDownをインストールする

公式サイトとか参考に、PCにインストールしておきます。

2. quotepathを無効にする

Excelファイルを使っているあなたは、きっとファイル名に日本語を使う人ですよね。
私もそうです。
後述するpre-commitでは、quotepathが有効な状態(デフォルトは有効)だと、ファイル名に日本語があると失敗してしまうので無効にしておきます。

git config --local core.quotepath false
3. pre-commitを設定する

プロジェクトフォルダーの、.git/hooks以下にpre-commitファイルを作成し、下記の内容を貼り付けます。

#!/bin/sh

# 変更されたファイルのリストを取得
changed_files=$(git diff --cached --name-only | tr -d '"')

# 変更されたファイルの中に拡張子がxlsxのものがあるか確認
for file in $changed_files; do
  if [[ ${file##*.} == "xlsx" ]]; then
    # 同じファイル名で拡張子がmdのファイル名を作成
    md_file="${file%.xlsx}.md"
    # コマンドを実行
    markitdown "$file" > "$md_file"
    # Shift-JISからUTF-8(BOMなし)に変換
    iconv -f sjis -c "$md_file" > "$md_file.utf8"
    mv "$md_file.utf8" "$md_file"
    # .mdファイルをステージングに追加
    git add "$md_file"
  fi
done

これで設定は完了です!

使い方

とくに何も気にせず、Excelファイルを更新してコミットするだけで、対となるMarkdownファイルも登録されます。
Pull Requestのレビュー時は、最初にMarkdownの差分を見て、変化のあった箇所をExcelで確認する流れになり、レビュー漏れが無くなってイイ感じです!

注意点

あくまでも差分をMarkdownで抽出しているので、当然ながらExcelで列の追加/削除を行うと、全体に変更が発生したことになります。
そういうのは、列を追加/削除するだけのコミット/Pull Requestを分けるようにして使いましょう。

MarkItDownは、他にも様々な活用方法がありそうなので、引き続き遊んでいきます!

ISUCON14初出場🎉

CEOの@uen0yamaです。
ISUCON14に初出場/初優勝を狙いに行ったら0点でした!
忘れぬうちに備忘録書いときます!

メンバー構成

メンバー 担当
@tzm bashスクリプト作成、アルゴリズム改善
@qwav DBチューニング関連、N+1対策
@uen0yama インフラ/デプロイ、SSE実装

当日のタイムライン

🕒9:30~10:00 早起きはつらかった

  • オフィスに集合(写真撮っておけばよかった)
  • ライブ配信で出題動画見る。おもしろ。

🕒10:00~11:00 マニュアル把握/初期デプロイ

  • 【全員】マニュアル読む。
  • 【@uenoyama】AWSに環境デプロイ。
  • 【全員】SSH接続確認。
  • 【@tzm】デプロイ用のbashスクリプト用意、GitHubのprivateリポジトリにソース登録。
  • 【@uenoyama】1発目のベンチマーカー。1000点ぐらい。
  • 【@tzm, @qwav】ソースコードからボトルネックを調査。
  • 【@uenoyama】nginxでalpログ取り環境、slow-queryログ取り環境の構築。
  • 【全員】alpログ、ソースコード調査から対策の方針を以下のとおり固める。
    • サーバー構成の変更。(@uenoyama)
      • 1台目がNginxのフロントとAPIサーバーの/api/chair/api/matching以外。
      • 2台目がAPIサーバーの/api/chair
      • 3台目がMySQLとAPIサーバーの/api/matching
    • /app/chair/notificationをSSE化。(@uenoyama)
    • /nearby-chairのN+1対策。(@qwav)
    • /api/matchingのアルゴリズム改善。(@tzm)
    • データベースのテーブル構造見直し、最新値とSUM値を新しいカラムとして持つ方針に変更(@uenoyama/@qwav)

🕒11:00~14:30 ベンチマーカー0点時代

  • 【@uenoyama】サーバー構成の変更、ついでにnginx.confを見直してパフォーマンス最適化(これが裏目)
  • 【@uenoyama/@qwav】データベースのカラム追加、インデックスの追加。
  • 【@tzm】後述の事件対応のため、テスト環境をdockerで動作するための準備。マッチング改善のポイントをコード調査。
🔥事件勃発🔥
  • いつの間にかベンチマーカーが0点になってる。
  • エラーログから、何かパフォーマンスの問題じゃないかと安直な判断をして各自調査。(これまた裏目)

🕒14:30~14:45 スタートラインにもどる

  • 【@uenoyama】ソースコードとSQL構成を元にもどしてもエラーが発生してベンチマーカーが0点。
    • ってことはnginx.confしか考えられへん。
    • gzipまわりの設定を元に戻したら、ベンチマーカー完走。ようやく初期設定の1000点に戻る。なんてこった。

🕒14:45~16:30 SQLコピーミスに気付く

  • 【@uenoyama】SSEの実装を進める。
  • 【@qwav】/nearby-chairのN+1問題対応
  • 【@tzm】「docker環境で走らせたら、init.shが失敗するぞ」との報告。全員で調査。
    • カラムを追加したせいで、初期登録データが合わないことでエラーになっていた。
    • ん? じゃあなんでベンチマーカーが完走してるん? 初期化失敗してんのに。
    • 😱😱😱、デプロイ用のスクリプトをミスってた! 結果、修正したSQLコードがアップできてなかったことが判明(つまり初期構成で動いていた)
    • /webapp/sql以下にコピーするスクリプトが、/webapp/sql/sqlにコピーしているなんて……1年生のミスや……
  • SQLを正しくコピーしたら、スコアが4000点を突破🎉 ようやくスタートラインに立った気がする!

🕒16:30-17:00 chairのSSE化完成、そして再び0点時代へ

  • 【@uenoyama】/chair/notificationのSSE化の実装完了。
    • デプロイしてシミュレーターで確認すると、相も変わらずポーリング動作してる。
    • はて? 通常のエンドポイントは削除したはずなのに? エラーならわかるけど、なんでレスポンスが返ってきてるん?
  • 😱😱😱、デプロイ用のスクリプトミス発見アゲイン!
    • 我々は言語にNodeを選択してたのに、デプロイの際、TSコードをアップして終わりの気持ちになっていた!
    • いつトランスパイルしてんだっけ、って調べたらサービス起動時にnpm run startを叩いていて、ここでトランスパイルしてた。今頃気付くなんて! ぐは!
    • ってことは、4000点はサーバーの分散とSQLのインデックスだけの効果だと判明。ソースコードを更新したら(けっこう実装してたので)何点まで伸びるのかワクワク✨しだす。
  • サービス再起動してシミュレーターで確認したら、/chair/notificationが正しくSSEで動作している! これはベンチマーカーも期待できる!
  • ベンチマーカーを走らせたら、まさかの0点! どこだ、どこで壊れた!

🕒17:00-18:00 appもSSE化完成、マッチングアルゴリズム改善、0点フィニッシュ😞

  • ベンチマーカーの問題対応は@qwavにまかせて、勝つためには完全SSE化とマッチングアルゴリズム改善が必須と判断。
  • 【@uenoyama】SSE化を17:30に完成!
  • 【@tzm】マッチングアルゴリズム改善も17:30に完成!
  • 【@qwav+全員】ベンチマーカーのエラー対応! なおらない! chairownerかどっちかが壊れる!
  • 17:59、最後の奇跡を信じ、ログ出力をすべて切って最後のベンチマーカー開始! 0点! おつかれさまでした!

🕒18:00-20:30 ライブ配信鑑賞しつつ🍕ピザと🍺ビールで打ち上げ

  • 全員、完全に燃え尽きた感がありつつも、「今日帰って寝たらタイムリープしてて、9:30からやり直せたら勝てるね」という負け惜しみを吐きながら解散!

ふりかえり

😰悪かったこと

  • 序盤を焦り過ぎた。デプロイのスクリプト検証ぐらい、ちゃんとサボらずやれば良かった。
    • アップロードしたファイルのタイムスタンプが更新されてるよね。
    • NodeのトランスパイルされたJSコードのタイムスタンプも更新されてるよね。
  • 1コミット-1デプロイ-1ベンチマーカーを徹底しとけばよかった。
    • 今回、途中でトランスパイルしてなかったことに気付き、トランスパイルしたらエラーとなった。
    • その時点で多数のコミットを重ねていたので、エラーメッセージから「これかな?」という、いきあたりばったりな修正方法を重ねた。
      • 結果、たぶん修正したせいで壊れた、みたいなのもあったと思う。
      • 1年生みたいなデグレードや。
    • 最後に完走したコミットまで戻して、そっから1個ずつ入れていく、という地道な対応をしておけば良かった。

😃良かったこと

  • 序盤にalpの結果解析と、全体的なソースコードのボトルネック調査を行った結果、改善ポイント自体はいいところを狙えたと思う。
    • 作問解説を聞きながら、「それそれ、そこやってたよー!」と負け惜しみが盛り上がった。
  • 狙い所を定めたあと、担当を決める時にちょうどメンバーの技術領域がマッチングしていた。
    • アルゴリズムはAtCoder担当の@tzmが適任。
    • N+1問題は数学的バックボーンで@qwavが適任。
    • SSEは散々実装してきた@uenoyamaが適任。
  • 😆とにもかくにも楽しかった😆。8時間は長いかなーと思ってたけど、始まったら一瞬だった。
    • とくに17:30-18:00の最後の修正時間は、結果は失敗だったが、「これ動いたら上位行けるんじゃない?」というワクワク感もあっても、濃密な時間だった。
    • ISURIDE、すごく良くできてる問題だなーと思った。マッチング処理がsystemdからの呼び出しなので、これだと並列処理ではなくてアルゴリズムの問題になって、言語間の優劣が出にくいだろうなー、と思った。すばらしいな。

運営の方は大変だと思いますが、また来年参加させていただこうと思います!
ありがとうございました!!

減量生活

はじめに

こんにちは。ドミノソフトのnct-dsです。 2024年5月頭の健康診断で超ハイスコアを叩き出し、GW明けの病院出頭にてめでたく糖尿病と診断されました。 この記事では糖尿病と診断されるまでの経緯と、診断された後の食生活改善、数値(HbA1cと体重)の変化をご紹介いたします。

過食

実は私、2023年の夏頃からフードデリバリーサービスにハマってしまいまして・・・。 いや、それまでも週に1回か2回程度は利用していたのですが、その時期から頻度を激増(会員ランク:スーパーゴッド)させてしまいました。 しかも量も多め(弁当大盛り/Mピザ等)で揚げ物と炭水化物のラッシュだったわけです。

で、その頃から太り始めたのですが、冬あたりに運動もしていないのになんか痩せた気がしたんですよね。 それと体がダルい・喉が渇く・視力が落ちた感じがしていました。 しかし「まだええやろ。次の健康診断で悪い数字が出たらやめよう」と思いつつ出前フードデリバリーサービスを利用し続けておりました。

健康診断

そんなこんなで今年5月頭の健康診断を迎えました。

まず衝撃を受けたのが体重測定でした。なんと前年から3kg減少して67kgだったのです。顔面蒼白です。 「絶対に太ってるはず。75kgくらい行ってるかも」と思っていたのに・・・。不安が一気に押し寄せます。

そして、ひととおり検査を受けてから医師の面談に臨みました。 血液検査の結果HbA1cが驚異の11%Overでした。NGライン(6%)の約2倍。入院を勧めるレベルだそうです。やばすぎて草。 先生の気の毒そうな面持ちが忘れられません。

その日からフードデリバリーサービスをやめ、すぐに食制限を始めてGW明けに自宅近所の病院に出頭しました。 そこで再検査するとHbA1cは9%台まで落ちてはいましたが、めでたく糖尿病と診断されました。オワタ。

まあ入院やインシュリン注射は回避できたので、そこは救いでしたね。 いやはや、こんなに不安な気持ちは竜神バンジーのジャンプ前以来でした。

食生活改善

食事を以下に制限しました。もう宅配ピザなんてとんでもない話です。

  • 朝食:ゆで卵、低糖ヨーグルト、野菜ジュース(食塩/砂糖不使用) 👉225kcal、糖質18g
  • 昼食:サラダ、豆腐バー 👉365kcal、糖質23.5g
  • 夕食:納豆1パック、他3品くらい適当に 👉700kcal、糖質55g
  • 間食:コーヒー、チーズ 👉150kcal、糖質7.5g
  • 1日合計:1440kcal、糖質104g

上記、夕食の「他3品くらい適当」は、米・パン・麺類・点心・揚げ物をNGとしましたがそれ以外は特に制限しませんでした。 また、私は自炊出来ない人間なのでコンビニやスーパーのお惣菜でやりくりしていました。

数値の変化

HbA1cと体重の変化は以下の通りでした。

  • 5月(健康診断):HbA1c=11.6%、体重66.8kg
  • 5月(病院出頭):HbA1c=9.9%、体重67kg
  • 6月:HbA1c=7.8%、体重64.4kg
  • 7月:HbA1c=6.5%、体重は記録消失
  • 8月:HbA1c=5.7%、体重60.9kg
  • 9月:HbA1c=5.6%、体重59.5kg
  • 10月:HbA1c=5.7%、体重59.2kg

HbA1cは約3ヶ月で6.0%を切り、体重は4ヶ月で7.5kg減といったところでしょうか。 病院に行くと毎回先生に「大変よく頑張っていらっしゃいますね!」と褒められます。フフン。頑張ったさ。 糖尿病患者界のエリート(模範囚)を自負しております。

まとめ

なんとかHbA1cを正常範囲内(糖尿予備軍)まで戻すことができました。 スーパーゴッド時代より食事の量はかなり少なくなったのに体調はすこぶるヨロシイです。

そして現在は少し食事を戻して様子を見ております。 週に2回程度は普通の昼食をとり、NGとしていた品目を「少量ならOK」にしました。

しかし「糖尿病の人」というレッテルは一生外れません。 糖尿病は一生付き合い続けるパートナーです。本当にありがとうございます(クソデカため息)

皆様、食生活には気をつけましょうね。 なお、食事制限のメニューは真似しない方がよろしいかと思います。あくまでもご参考程度に。