OmniAICreator/Qiita-1.07M huggingface dataset:
MyBatis Dynamyc SQL 自動生成手順


# 手順


```
前提として

・DBに接続できる状態にする
・CREATE文が既に実行されてテーブルが作られている
・「generatorConfig.xml」をresourcesフォルダ直下に置く（どこでもOK）
・「generatorConfig.xml」の「targetPackage=」に、生成場所を記載する
・「generatorConfig.xml」に「<table tableName="test_table_name">」というように、生成したいテーブル名を記載する
・「MyBatisGeneratorExecutor.java」のJavaソースを任意の場所に置く（generatorConfig.xmlのパスを読み取りに行く記述があるため注意）
・必要な以下pomを指定してmvn install（mvnインストールが完了しないと初回だけ赤文字でエラーのポップアップが出る）

```

```

<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.2</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.mybatis.dynamic-sql/mybatis-dynamic-sql -->
    <dependency>
        <groupId>org.mybatis.dynamic-sql</groupId>
        <artifactId>mybatis-dynamic-sql</artifactId>
        <version>1.5.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
    <dependency>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-core</artifactId>
        <version>1.4.2</version>
    </dependency>
</dependencies>

```

・「MyBatisGeneratorExecutor.java」を右クリック→実行を押下→生成されます



------------------------------------------------------------------------------------------------------------------------------

# 補足事項

・現在判明している生成不具合として、テーブル名「Users」というような、何かの予約語に相当しそうなテーブル名は、Crudソースの生成が完璧にできません。（UserXxxxというような被らなそうな名前ならOK）

・DDLのカラム定義として、INTではなくBIGINTを利用しないとLong型になりません。

・利用しているJava周りの起動構成によって、import文についてjavaxではなくjakartaが生成されるので注意。

・Mybatis(xmlファイル)の設定によりTimeStamp型がLocalDate型として生成されるので注意

------------------------------------------------------------------------------------------------------------------------------

# 参考記事

MyBatis Generatorの導入方法
引用：「特に設定しなければ、デフォルトでDATE・TIME・TIMESTAMPのデータはjava.util.Date型に変換されるようです。」
https://zenn.dev/peishim/articles/07178eadbcebb6

↑について、Date型ではなくLocalDateTime型として生成する方法
https://tetsufuru.hatenablog.com/entry/2020/06/07/162212

生成されたCRUD操作の実際の利用例（SELECT文）
https://qiita.com/HiroyaEnd/items/7281f7e5db30ef5a6ce6

MySQLの数値系(INT等)カラム定義
https://blog.s-giken.net/367.html
[備忘録] ChatGPT GPT-4oの画像作成機能を使って4コママンガを作成する方法

Qiita記事「ChatGPT GPT-4oの画像生成機能を使って4コママンガを作成する方法」を作成しました。手順、参考情報は参考になるかもしれません・・。皆さんがより良い結果を出せることを願っています。🙏

## はじめに
ChatGPT GPT-4oには画像作成機能が搭載されています。この機能を活用すれば、簡単に4コママンガを作成することができます。本記事では、2025年3月末時点での画像生成機能の使い方と、4コママンガ作成のためのプロンプト例を紹介します。試してみた結果の備忘録です。

## 前提条件

- ChatGPT Plus（有料版）を使用しました
- GPT-4oモデルが利用可能であること

## 画像生成機能へのアクセス方法

1. ChatGPTにログインする
2. 新しいチャットを開始する
3. モデル選択からGPT-4oを選択する
4. 以下のいずれかの方法で画像生成機能にアクセスする：
   - 「...」（その他）メニューから「画像を作成する」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/092ec60f-5eda-46aa-a3a3-2b213208a3f0.png)

「...」から機能を選択できるようです・・・ Canvasのほうも同様


## 4コママンガ作成してみた手順

### ステップ1: 入力画像を貼り付ける

### ステップ2: プロンプトを指定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/439218ca-bdfe-47ba-bf66-42b3ec1d64ce.png)

## 画像作成結果の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/13df94fd-b02c-42eb-8eb0-dbf40468c684.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/277ef627-1f3c-4dbc-bc41-e12af99f0868.png)




## まとめ

ChatGPT GPT-4oの画像生成機能を使えば、プログラミングの知識がなくても手軽に4コママンガを作成できます。プロンプトを工夫して、オリジナルの面白いマンガを生み出してみましょう。この記事が皆さんのクリエイティブな活動の一助となれば幸いです。

## 参考情報

<iframe width="560" height="315" src="https://www.youtube.com/embed/2f3K43FHRKo?si=ErE11-oW2FlcbfG0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


https://x.com/OpenAI/status/1904602859259166778


---

※この記事の内容は2025年3月末時点のものです。UI や機能は更新により変更される可能性がありますのでご了承ください。
Tailwind CSSのwidthなどに使える幅の値を増やす

## はじめに

Tailwind CSS では `default-spacing-scale` に定義された値を `width` や `padding` 等に利用することができます。

https://v3.tailwindcss.com/docs/customizing-spacing#default-spacing-scale

`default-spacing-scale` では 0.5 刻みがあるのは 3.5 まで、整数があるのは 96 までですがもう少し大きい値を使いたい場面があるので、サンプルとして 4.5~300 までの値を 0.5 刻みで追加してみます。

:pushpin: **検証バージョン: Tailwind CSS v3.3.0**

## `spacing` の値を追加する設定

`tailwind.config.ts` に以下の設定を行い、 `spacing` の値を追加します。

```tailwind.config.ts
const maxSpacing = 300; // ここを追加

const config: Config = {
  theme: {
    extend: {
      // ここを追加
      spacing: {
        ...Array.from({ length: maxSpacing * 2 - 8 }, (_, i) => i * 0.5 + 4.5)
          .reduce((acc, curr) => {
            acc[curr] = 0.25 * curr + 'rem';
            return acc;
          }, {} as Record<string, string>)
      },
      // ...
    }
  }
};
export default config;
```


## 変更後の動作

0.5刻みの値が300まで使えるようになりました

```tsx
<div className="whitespace-nowrap [&>div]:bg-red-400">
  <div className="w-4.5">w-4.5</div>
  <div className="w-96.5">w-96.5</div>
  <div className="w-100">w-100</div>
  <div className="w-200">w-200</div>
  <div className="w-300">w-300</div>
</div>
```

![__.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42028/f08b5580-5da4-4655-b7a7-069de77d97c5.png)

## 補足

Tailwind 4.x系では下記のように `calc(var(--spacing) * value)` 形式で計算するようになるので本記事の `spacing` を追加する対応は不要になっています。
```css
.w-300 {
    width: calc(var(--spacing) * 300);
}
```
2025/3/31主にITとかセキュリティの記事

Firefox・Chrome・Tor Browserに重大脆弱性 – サンドボックスエスケープの危険性と迅速な対応(3/29)
https://innovatopia.jp/cyber-security/cyber-security-news/50392/

「疎かにすれば市場を失う」発効まで1年半、日本企業を阻む欧州サイバーレジリエンス法“3つの壁”と対策
既に出後れている国内製造業……まず何から始める？(3/29)
https://enterprisezine.jp/article/detail/21687

Windows 11最新パッチがLenovo製ツールをブロック　一部ThinkPadでBIOS更新が不能に(3/29)
https://reinforz.co.jp/bizmedia/77130/

中国が開発したAIサイバー攻撃ツールが発見される、IoT機器の詳細な位置やIPアドレスを収集して脆弱なデバイスを探し当てる(3/29)
https://gigazine.net/news/20250329-chinese-ai-iot-tool-prototype/

AIクローラーに“復讐”する開発者たち　FOSS界で広がるアヌビス作戦と偽情報の迷宮(3/28)
https://reinforz.co.jp/bizmedia/77063/

Google Threat Intelligence Technical Workshop for Partners 参加レポート(3/28)
https://zenn.dev/cloud_ace/articles/b51235dcb8f006

「本当に必要なエンジニア」とは何か - AIアシスタント時代の新たなエンジニア像(3/28)
https://zenn.dev/aoi_umigishi/articles/496ea407873aee

大阪万博公式サイトの偽サイトを複数確認、紛らわしいドメイン使用…「フィッシングサイト」の恐れ(3/28)
https://www.yomiuri.co.jp/expo2025/20250328-OYT1T50208/

マクニカ、産業界における製品セキュリティとOTセキュリティの現状・課題・対策について解説するメディア勉強会を開催(3/28)
https://www.mylifenews.net/study-work/82768/

欧州委員会 汎用AI実践規範の第3ドラフトを発表 (2025.03.11)(3/29)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2025/03/post-7524e3.html

AIエージェントにできることとは？最新動向と企業での活用事例(3/29)
https://markezine.jp/article/detail/48558

偽造キャッシュカードの被害急増、ネットバンキング注意喚起が必要な状況
https://news.3rd-in.co.jp/article/4c8832d8-0bc8-11f0-999a-9ca3ba083d71#gsc.tab=0

不足する｢セキュリティ人材｣の育成に挑む国立高専、｢サイバー攻撃への技術的対応｣から｢模擬記者会見｣まで実践を重視した教育のリアル(3/29)
https://toyokeizai.net/articles/-/867123

走行中の自動運転センサーは長距離から無効化可能　慶應義塾大学などが脆弱性を発見(3/29)
https://univ-journal.jp/252623/

医療情報セキュリティ確保のための新ガイドライン発表と意見募集の結果
https://news.3rd-in.co.jp/article/ea76d7bc-0bfd-11f0-8354-9ca3ba083d71#gsc.tab=0

マレーシア空港ランサムウェア攻撃：首相が1000万ドルの身代金要求を即座に拒否(3/29)
https://innovatopia.jp/cyber-security/cyber-security-news/50386/

eシール認定制度の規程策定に向けた意見募集結果を公開
https://news.3rd-in.co.jp/article/ea7b9694-0bfd-11f0-bdfc-9ca3ba083d71#gsc.tab=0
競プロ日記#25/03/30

# アルゴ式-[ごはんを買う](https://algo-method.com/tasks/491)
- 実装の方法として価格の小さい順にソートして貪欲法的なやり方で求めるのはわかったが[価格,個数]という要素をどう管理すればよいかがわからなかった→解説を見た
- 結果として「pair」というものを用いるらしい。
- <pair<long long, long long>>の二次元vectorに対してfor文で探索していくのも地味に重要ポイントな気がした

# アルゴ式-[階段ののぼり方](https://algo-method.com/tasks/304/submissions/1691000)
- 最後の行動で場合分けするのが重要。割と漸化式っぽい考え方。
- N＝5の場合は今回の問いでは2通りがある。①3段目からくる➁4段目からくる。→3段目への上り方と4段目への上り方の総数がわかれば答えを出せる。→①3段目へは2段目からくるのと1段目からくる...以下略。
- つまりFi = Fi-2 + Fi-1これをfor文で繰り返す
SSE（Server-Sent Events）を実装したけど、なぜかリアルタイム反映されてないときの解決法

# SSE（Server-Sent Events）を実装したけど、なぜかリアルタイム反映されてないときの解決法

過去に自分がはまってしまった、SSE（Server-Sent Events）を実装してしっかりとCORSも考慮したのに、なぜかリアルタイム反映されない罠について解説します。

## はじめに

`Server-Sent Events (SSE)`は、サーバーからクライアントに対してリアルタイムでデータを送信するための技術です。しかし、実装したものの、**リアルタイムで反映されない**という問題に遭遇することがあります。これは、さまざまな原因が考えられます。

この記事では、SSEを実装した際にリアルタイム更新が反映されない原因と、それを解決するための方法を解説します。



## 1. HTTPレスポンスのバッファリング

これが一番の沼りポイントだと思います。
SSEでは、サーバーからクライアントにデータをリアルタイムで送信することが目的ですが、**HTTPレスポンスがバッファリングされる**と、レスポンスがクライアントに即座に送信されず、更新が遅れることがあります。これは、Node.jsのHTTPレスポンスがデフォルトでバッファにデータをため込み、一定のタイミングで一度に送信するためです。

### 解決策

Node.jsのレスポンスはデフォルトでバッファリングされるため、SSEでリアルタイムにデータを送信したい場合、`res.flush()` を使ってバッファを即座に送信することが必要です。これにより、データがブラウザに即時に反映され、リアルタイム更新が実現できます。

### コード例

以下は、MongoDBのChange Streamsを使ってリアルタイムでデータをクライアントに送信するコードの一部です。このコードでは、SSEを使用しての変更をクライアントに通知していまするための`sendData`の作成例です。

```js
  const sendData = (data) => {
    res.write(`data: ${JSON.stringify(data)}\n\n`);
    // 即座にレスポンスを返す
    res.flush();
  };
  
  ChangeStream.on('change', async (change) => {
    const updatedData = change.fullDocument; // 変更後の完全なドキュメント
    sendData(updatedData); // クライアントに送信
    console.log('Change detected in Data:', JSON.stringify(change, null, 2));
  });
```

## 2. CORS設定

異なるオリジンからデータを送信する場合、CORS（クロスオリジンリソースシェアリング）設定が正しく行われていないと、クライアントがSSE接続を拒否することがあります。特に、異なるドメインやポートでサーバーとクライアントが通信している場合は、CORS設定を確認することが重要です。


### 解決策

CORS設定を行い、SSEを許可するようにします。以下のように、Corsミドルウェアを使用して、オリジンを許可します。methodsやoriginを適切に設定することで、セキュリティリスクを軽減し、外部アプリケーションとの連携を可能にすることができる。

## コード例
`mothods`は、許可するHTTPメソッドを指定しています。ここでは、GETとHEADメソッドのみが許可。
`origin`の`*`はワイルドカードで、すべてのオリジンからのアクセスを許可することを意味します。つまり、どのドメインからでもリクエストが許可される設定です。


:::note warn
セキュリティを考慮する場合は、`'*'`を使用するのではなく、特定のオリジン
（例：origin: 'https://example.com'） を指定することが推奨されます。
:::

```js
import Cors from 'cors';

// CORSミドルウェアの初期化
const cors = Cors({
  methods: ['GET', 'HEAD'],
  origin: '*',  // 必要に応じて特定のオリジンを指定
});
```

## 3. ヘッダーの設定

デフォルトでは、HTTPレスポンスが完了した後にサーバーとクライアントの接続は閉じられます。しかし、リアルタイム通信を行うSSE（Server-Sent Events）などでは、接続を維持し、サーバーがクライアントにデータを送り続ける必要があります。

### 解決策

`Connection: keep-alive` ヘッダーを設定して、接続を維持します。
`Connection: keep-alive` を設定することで、クライアントとサーバーの接続を維持するために使います。この設定により、クライアントとサーバーの間でTCP接続が切断されることなく、長時間接続が維持されます。

## コード例
SSEのヘッダー設定の場所に`res.setHeader('Connection', 'keep-alive');`を加えてあげましょう。

```js
  // SSEのヘッダー設定
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
```

## 最後に
リアルタイムのデータ更新を実現するためには、SSEやWebSocketのような技術を活用することが重要ですが、その際に発生するバッファリングの問題には注意が必要です。
自分の場合、プロンプトに問題があったのかChat-GPTもこのバッファリング問題（res.flush()追加）について教えてくれなかったので、プロンプトの重要性を実感しました。
[Terraform] TFコードのリソース関係をグラフで表現する方法

## 前書き 
Terraformコードが長くなると、リソース間の関係が分かりづらくなることもあります。そのため、リソース間の依存関係をグラフで可視化することが非常に有用です。この記事では、Terraformコードをグラフとして可視化する方法について、いくつかの方法を紹介します。

### 方法1.　terraform graph
Terraformには、リソース間の依存関係をグラフとして出力する terraform graph コマンドが組み込まれています。このコマンドを使って、リソース間の依存関係を可視化することができます。

#### 1-1. Terraformの設定ファイルを準備
まず、Terraformで作業しているディレクトリに移動し、適切なTerraformコード（.tfファイル）があることを確認します。

#### 1-2. terraform graph コマンドを実行
以下のコマンドを実行して、依存関係をDOT形式で出力します。
```bash:terraform cli
terraform graph > graph.dot
```
このコマンドにより、graph.dot というファイルが生成されます。DOT形式は、グラフを表現するためのフォーマットです。

#### 1-3. dotファイルを画像に変換
次に、Graphvizツールを使って、graph.dot をPNGなどの画像に変換します。Graphvizは、DOT形式を視覚的なグラフに変換するツールです。

- Graphvizのインストール
```bash:cli
# macOS:
brew install graphviz
# Ubuntu:
sudo apt install graphviz
```
- DOTファイルを画像に変換
以下のコマンドで、graph.dot をPNG形式に変換できます。
```bash:cli
dot -Tpng graph.dot -o graph.png
```
これで、graph.png という画像ファイルが生成されます。この画像には、Terraformリソース間の依存関係が可視化されています。ただし、リソースが多いと見にくいという欠点があります。

### 方法2.　terraform-docs
terraform-docsは、Terraformコードから自動的にドキュメントを生成するツールです。依存関係の詳細な視覚化には直接使えませんが、モジュールやリソースの構成を文書化するために有用です。
#### 2-1. インストール
```bash:cli
brew install terraform-docs
```

#### 2-2. 使用方法
```bash:cli
terraform-docs markdown . > README.md
```

これにより、TerraformのリソースやモジュールのドキュメントをMarkdown形式で生成することができます。

### 方法3.　terrascan
terrascanは、Terraformコードの静的解析を行うツールで、セキュリティやベストプラクティスに基づいたレポートを生成するために使用されます。依存関係の可視化にも役立つことがありますが、主にセキュリティ監査のツールとして使われます。
#### 3-1. インストール
```bash:cli
brew install terrascan
```

#### 3-2. 使用方法：
```bash:cli
terrascan scan -i terraform -p .
```

### 方法4.　terraform graph beautifier
該当リポジトリはこちらです。
[terraform-graph-beautifier](https://github.com/pcasteran/terraform-graph-beautifier
 "terraform-graph-beautifier")
 
#### 4-1. インストール
```bash:cli
go install github.com/pcasteran/terraform-graph-beautifier@v0.2.0
```
#### 4-2. 使用方法：
```bash:cli
terraform graph | terraform-graph-beautifier \
    --exclude="module.root.provider" \
    --output-type=cyto-html \
    > config_sample.html
```
 **Collapse all**, **Expand all**, **Run layout** それぞれボタンを押すとリソースを縮小、拡大、異動させることができます。

 ### 方法5.　Inframap
 該当リポジトリはこちらです。
 [inframap](https://github.com/cycloidio/inframap
 "inframap")

 #### 5-1. インストール
 ```bash:cli
 go install github.com/cycloidio/inframap@v0.6.7
  ```
#### 5-2. 使用方法
 ```bash:cli
 inframap generate terraform.tfstate --raw | dot -Tpng > inframapraw.png
  ```

場合によって画像が表示されなかった時、以下のコマンドを使用します。
 ```bash:cli
 inframap generate \
> terraform.tfstate --raw | \
> dot -Tpng > inframap_sample.png
```
## 最後に
Terraformのコードをグラフとして可視化する方法はいくつかあります。最も基本的な方法は terraform graph コマンドを使用することですが、目的に応じて紹介した上記のツールを使うこともできます。よかったら、試してみてください。
【AWS】 Elastic Beanstalkのデプロイメントポリシーについて調べてみた

# はじめに
Elastic Benstalkでは、アプリケーションのデプロイ時に**デプロイメントポリシー**なるものを指定できるらしい。
Beanstalk自体は使ったことはないが、現在勉強中のAWS SOAで問われたのと、また将来受験しようかなと考えているAWS DVAの勉強も兼ねてまとめてみることにした。

# デプロイメントポリシー
大きく分けると以下の４つ。

- All at Once
- Rolling
- Rolling with additional batch
- Immutable

### All at Once
同時にすべてのインスタンスにデプロイするポリシー。
すべてのインスタンスに一気にデプロイするのでダウンタイムは発生するが、デプロイメントポリシーの中では一番簡単かつ早い。

### Rolling
**バッチサイズ**を指定してデプロイするポリシー。
バッチサイズというのは、「**デプロイを進める割合もしくはインスタンスの個数**」のことである。

たとえば、「4つのインスタンスを稼働させていて、デプロイ時に半分は稼働させた状態にしておきたい…」といったときに、バッチサイズで「50%」と指定してあげることで、半分の数のインスタンスに対してデプロイを行い、終わったら残りのインスタンスにデプロイする、といったことができる。

### Rolling with additional batch
**バッチサイズを指定しつつ、インスタンスを追加**してデプロイするポリシー

同じくインスタンス数は4、バッチサイズは50%とした場合…

①バッチサイズ分のインスタンスを新規で追加し、新規のインスタンスに対してデプロイを実施する。
↓
②新規インスタンスへのデプロイが完了したら、既存のインスタンスのうち50%のインスタンスに対してデプロイを実施する
↓
③既存のうち50%のインスタンスにデプロイが完了したら、残った二つのインスタンスは削除する。

キャパシティを維持したままデプロイ可能なので、本番環境などで採用されやすい。

### Immutable

**既存のインスタンスは利用せず**、新規インスタンスを作成してデプロイするポリシー。

４つのインスタンスが稼働しているのであれば、新規でさらに４つインスタンスを作成し、そこにデプロイする。
その後、古い方のインスタンスをすべて終了する。

全てにおいて一切のダウンタイムが発生しないことが特徴。
その分時間もかかる。

# おわりに
SOAの問題として問われたときに「こんなのほかで聞いた事ねーし覚えられねーよー」と思ってたけど、蓋を開けてみればなんてことない内容だった。
VBAでコラッツ逆計算を二次元配列として書き出し、Excelの表にするコード

#### コラッツ予想の計算において、1から逆にとらえた計算の奇数の遷移に着目
コラッツ予想の計算を逆にとり、その奇数のみの数列をを二次元配列として書き出します。
計算式は、コラッツ計算の漸化式から一般項を求めました。
6で割ったときに1余るか5余るかで、2で割る回数が、偶数か奇数かが変わるので、一般項は2つ存在します。【1*】【2*】

```vb:excelマクロ
Sub コラッツ奇数配列()
    Dim s As Integer, t As Integer, n As Integer, m As Integer  's,t,n,mの宣言
    Dim 奇数_e(100, 100) As Variant '奇数_eの二次元配列の宣言
    Dim 奇数_o(100, 100) As Variant '奇数_oの二次元配列の宣言
    
    n = 20  '表示したい列数
    m = 20  '表示したい行数
    
    Range(Cells(1, 1), Cells(2, n)).Font.Color = RGB(255, 0, 0)  '参照奇数の二行の文字色設定
    Range(Cells(1, 1), Cells(1, n)).Interior.Color = RGB(226, 226, 226)  '参照奇数_eの行の背景色設定
    
    For t = 1 To n  '列を指定
    
        奇数_e(0, t) = 6 * t - 5  '参照奇数_eを求める式(一行目)
        奇数_o(0, t) = 6 * t - 1  '参照奇数_oを求める式(二行目)
        Cells(1, t).Value = 奇数_e(0, t)  '参照奇数_eをセルに入力(一行目)
        Cells(2, t).Value = 奇数_o(0, t)  '参照奇数_oをセルに入力(二行目)
    
        For s = 1 To m / 2 '行を指定
            
            奇数_e(s, t) = (4 * 4 ^ (s - 1) - 1) / 3 + (t - 1) * 8 * 4 ^ (s - 1)  '奇数_eを求める式【1*】
            奇数_o(s, t) = (10 * 4 ^ (s - 1) - 1) / 3 + (t - 1) * 4 * 4 ^ (s - 1)  '奇数_oを求める式【2*】
            Cells(s * 2 + 1, t).Value = 奇数_e(s, t)  '奇数_eをセルに入力
            Cells(2 * s + 2, t).Value = 奇数_o(s, t)  '奇数_oをセルに入力
            Range(Cells(s * 2 + 1, t), Cells(s * 2 + 1, t)).Interior.Color = RGB(226, 226, 226)  '奇数_eの行の背景色設定(一行ごとに着色)
            
        Next s
    Next t
     
End Sub
```
このコードを実行すると、以下のように書き出せます。

![excel_draw_e_table.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4048186/2538e003-a198-4157-b228-d30d6e17e43d.jpeg)

奇数のみを考えると、
1　→　{1, 5, 21, 85, 341,…}
5　→　{3, 13, 53, 213, 853,…}
7　→　{9, 37, 149, 597, 2389,…}
11　→　{7, 29, 117, 469, 1877,…}
13　→　{17, 69, 277, 1109, 4437,…}
17　→　{11, 45, 181, 725, 2901,…}
のように遷移するわけですが、この{}の奇数の並びが、書き出したExcelでは縦の行のひとつ飛ばしになります。

このコードでは20×20（n=20,m=20）しか表してないですが、【1*】【2*】この二つの式で正の奇数が重複なくもれなく表わせます。
Excelでマクロに貼り付けて、実行させるだけ…数学的な証明など抜きにして、コラッツ予想が真であることを体感していただけるかと思います。

ご覧いただき、ありがとうございました！
大量のデータを扱う際にロードを早くするための対策の種類

ついに重いという現象がこの前発生した。

あるデータを5万件ほど入れたのだ。
セレクトボックスで選択できるようにしていた。

今までは10種類程だったが、それを5万にしたのだ。
もちろん検索も可能だ。

選択するとブラウザの応答が止まる。

おそらくまだロードしているのであろう。
chromeは「応答しませんが待ちますか？」

と返答してくる。

今回の対応は全部検索にして、ワードに含むデータを取得することで解決した。

他の方法もないか探してみた。

# 1. ページネーションを導入する
大量のデータを一度に取得しないで、ページネーションを使い小分けにデータを取得する方法。
Laravel では paginate() や simplePaginate() を使うと簡単。

```php
$users = User::paginate(50);
return view('users.index', compact('users'));

```




# 2. インクリメンタルサーチやオートコンプリートを導入する

大量のデータをselectタグの中にすべて表示するとブラウザがフリーズする。

対応として検索キーワード入力ごとに必要なデータのみ取得する仕組み。
JavaScript のイベントを利用して Ajax 通信をして、サーバーから対象データを返却。
プルダウンに表示する方法。


# 3. キャッシュを利用する

一度取得した結果をキャッシュに保存することで再取得の時間を短縮する。
Laravel にはキャッシュ機構がビルトインで存在する。

```php
$users = Cache::remember('user:list', 3600, function () {
    return User::all();
});
```

## 注意点
データが頻繁に更新される場合はキャッシュの有効期限管理が必要になる。

# 4. インデックスを貼る
DB のカラムにインデックスを貼ることで検索パフォーマンスを向上させる手法。



```php
CREATE TABLE users (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

検索を
```php
SELECT *
FROM users
WHERE email = 'example@example.com';
```

インデックスを貼る。
```php
CREATE INDEX idx_users_email ON users (email);
```
対象カラムの種類や検索条件に応じてMySQLやPostgreSQLなどのインデックス特性を理解して正しく設計するとクエリ速度が上がる。
大きなテーブルで実行速度を大幅に改善できるらしい。

ただ、データをINSERT、UPDATE、DELETEするたびにインデックスの再構築が必要になるとのこと。

# 5. 適切なクエリ・N+1問題の回避
with() や load() などを用いることで関連テーブルを一括取得してクエリの発行回数を減らすことができる。

```php
// N+1問題の例
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->user->name; // ここで都度DBアクセスが走る可能性あり
}

// withを使って回避
$posts = Post::with('user')->get();
```


# 6. Lazy Loading / チャンク処理
Eloquent には**chunk()やcursor()**メソッドが用意されている。
大量のレコードを分割して取得することが可能。
メモリを圧迫せずに処理したい場合などに有効。


```php
// 100件ずつ取得する例
User::chunk(100, function ($users) {
    foreach ($users as $user) {
        // ...
    }
});
```

バッチ処理に向いているらしい。

# 7. フロントエンドの非同期読み込み（Ajax / タブ区切りなどのUI）

タブを設けて必要なタイミングでデータ取得する。
ページにアクセスした際に Ajax でバックグラウンドで読み込み、完了したら表示する。


データが重くなるのがどういうことかローカル環境だとデータ量がすくなく分かりづらかった。
本番の環境に寄せることで、実際に問題が起こることを知った3月末日。
関数電卓(2行機)徹底比較

## F-715SAとfx-290Aを比較する
[電卓の日企画：関数電卓(1行機)あれこれ(おまけあり)](https://qiita.com/harycurl/items/96e3dc12e5d49473fd2e)に続いて、今回は2行機について徹底比較をしてみる。

現行の機種はキヤノンF-715SA/F-715SG（色違いで機能は同一、以下F-715SAで記述）とカシオfx-290Aの2つのみである。そして面白いくらい両者の特徴が異なる。その特徴を踏まえて一方を選び購入されたい。

実売価格はそれほど変わらない（今回通販ストア経由で購入したが、20円だけF-715SAの方が高かった）が、fx-290Aの方が多く流通し、入手しやすいと思われる。アマゾンではF-715SA/F-715SGがしばらく品切となっている。

### 表示部
まずはF-715SAとfx-290Aの外観を確認しよう。同じ大きさに見えるようサイズを調整しているが、実際はfx-290Aの方がわずかに小さい。

![715sa_290a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/cc6cc939-e5a3-4c35-9171-68d74f7f44c9.png)

1行目に注目。fx-290Aが縦6ドットに対してF-715SAは縦7ドット。1ドットの違いだが、自然な文字の形となるため見やすく感じる人もいるだろう。2行目の数字もF-715SAの方が大きい。
一方、F-715SAはコントラスト調整の機能が無い。前機種のF-715Sにはあったようだが本機では削除され、周辺の環境によってはデメリットと言える。fx-290Aはコントラストが調整できる上はっきりとした黒色で表示されるため、コントラスト面の見やすさはfx-290Aの方がよい。

文字の大きさで選ぶか、コントラストの良さで選ぶか。これが第一の選択である。

### 機能
概ね同程度の機能が備わっているが、F-715SAのキーが2つ多いことからわかるように、若干であるがF-715SAの機能が多くなっている。

- F-715SAのみの機能：最小公倍数、最大公約数、log<sub>a</sub>b、商および剰余、0～9キーのメモリ機能（計17メモリ）、アンドゥ、式のコピー
- fx-290Aのみの機能：単位換算

F-715SAで特筆すべきはlog<sub>a</sub>bだろう。fx-82MSに準じる機能数の関数電卓はlog<sub>a</sub>bがついておらず､底がeや10以外の対数計算は複数に分ける必要が出てくる。本機はlog<sub>a</sub>bが加わっていることで任意の底の対数計算を容易に行える。この点だけでF-715SAを選択しても良い位だ。
最小公倍数や最大公約数は、カシオ（主に上位機種に搭載）が2数までに対してキヤノンは3数まで可能となっている。使用機会のある人は少ないかもしれないが、必要な人にとってはキヤノン機の方が便利だろう。
商および剰余機能は剰余表示が2キーとなる点が惜しい（[Shift][Q↔r]もしくは[RCL][D]）。なお実行時に商はメモリC、剰余はメモリDに自動保存される。

一方のfx-290Aの機能はほぼfx-82MSと同じである。追加されたのは単位換算。108種類（54対）の単位換算が可能であり、ケース裏面の番号表に従って指定する。もちろんほとんどの複数行機にも単位換算機能はあるが、手軽な2行機に付いているからこそ重宝する人もいるだろう。

**（追記）**：[エイプリルフール企画：関数電卓の精度を比較する](https://qiita.com/harycurl/items/3b10eeb3174ecaee4c1e)の記事で、F-715SAの内部計算桁数が16桁、fx-290Aの内部計算桁数が15桁と、F-715SAの精度がよいことを示したが、この内部計算桁数が結果に現れる事例を海外の掲示板で見つけたので紹介する。
[[sharp]EL-509X 小数点6桁目にある結果 標準偏差を求める](https://allcalc-org.translate.goog/24268?_x_tr_sl=ko&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=wapp)
小数点以下6桁の数で標準偏差を求めたところシャープ機で0になってしまうという問題提起だが、fx-290Aで求めてもやはり標準偏差は0になってしまう。一方、F-715SAで求めると記事のコメント通りに xσn = 2.059126028×10^<sup>-6</sup>， xσn-1 = 2.170509413×10^<sup>-6</sup> と求められる（韓国ダイソーで売られている関数電卓で正しい値が出たと書かれているのにびっくり。注文したので到着次第確かめることにする）。
もちろん、カシオES機やClassWizでも同様に求めることができるが、fx-290Aの精度はこの程度であることを踏まえた方がよいかもしれない（とはいえ、シャープの複数行機でも0になってしまうのだけれど）。

### まとめ
結論として、単位換算・表示画面のコントラスト・入手のしやすさで選ぶならfx-290A、log<sub>a</sub>bなどの機能面で選ぶならF-715SA/F-715SGということになる。
キヤノン機の存在のありがたみを感じる2行機比較であった。

なお、シャープの2行機は独特の操作体系で、国内販売が継続されていたらまさに三者三様であった。[PCで動くエミュレータが海外サイトにある](https://www.sharp-calculators.com/teacher-school/learning-materials/)（Wのつかない500番台のものが2行機）ので、気になる人は試してみてほしい。米アマゾン等から購入も可能（送料もかかるので値が張る）。

最後にカシオ2行機のクローンに触れる。fx-82MS初代にそっくりの形状のもの（激安）もあれば、991MSの機能を複数行機の筐体に載せこんだもの（そこそこの値段）、右側に電子メモ帳が付いたもの（高い）まである。
2番目の商品の例として、アマゾンではNEWYESのものが2色販売されている。なぜかメーカー公式に製品が載ってない機種。991MSベースなので上記2機種より断然機能が多いが、簡単な演算でも結果表示に一瞬間がある仕様で、キータッチも安っぽい。通常はfx-290Aより値段が高いものの、現在（2025/3/31時点）スマイルSaleでfx-290Aより若干安くなっている。筐体色の好みや、表示部がF-715SAよりさらに巨大で見やすく感じる人もいるであろうから取り上げた（お勧めはしがたいので自身でレビューを見て判断を）。
【React Native（Expo）】expo-image-manipulatorを使って画像サイズの適正化を行う

### ◆やりたいこと
- Firebaseやsupabaseなどに画像をアップロードする際にファイルサイズを適正化してアップロードしたい
- 背景としてスマホ撮影の画像サイズが数M単位となりアップロード先のストレージを圧迫させるため

### ◆記事にしようと思ったきっかけ
- Expo公式ドキュメントでは「ImageManipulator.manipulateAsync」が
現在非推奨となっており、代替として
「mageManipulator.manipulate」か
「useImageManipulator」を使用を促してます。
![スクリーンショット 2025-03-30 23.45.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3983478/821fa5d5-87eb-49db-b3de-ec92a40db6c8.png)

- Qiitaでもexpo-image-manipulatorに関する記事はあるのですが、「ImageManipulator.manipulateAsync」を使っての実装だったので、非推奨でない方法での適正化を行う方法で記事を作成したいと思いました。

https://qiita.com/0ba/items/791dda1434788783622a

https://zenn.dev/kamabokochan/articles/085c9fe1b7910a

- 今回は代替の1つであるmageManipulator.manipulate」を使って画像サイズ適正化

### 環境（本記事のライブラリのバージョン）
`Expo：52.0.36`
`react-native：0.76.7`
`expo-image-manipulator：3.0.6`

### ◆実装例
```react:image.ts
import { SaveFormat, ImageManipulator } from "expo-image-manipulator"

const uri = "アップロードしたい画像のURI" 

const processImage = async (uri: string) => {
    // manipulateメソッドに画像のURIを渡すことで、画像操作コンテキストを作成します
    const manipulator = ImageManipulator.manipulate(uri)

    // 画像のサイズを調整して品質を最適化
    // 今回の例では画像の幅を1080ピクセルに設定
    manipulator.resize({
        width: 1080
    })

    // 画像を描画
    // リサイズ処理を実際に適用し、結果を取得します。
    const resizeImage = await manipulator.renderAsync()

    // 今回の例ではBase64形式で保存処理を実施。
    // format: 保存形式（JPEG/PNG/WEBP）
    // compress: 圧縮率（0.8は80%の品質（20%の圧縮））
    // base64: Base64エンコーディングを有効にする（trueに設定）
    const result = await resizeImage.saveAsync({
        format: SaveFormat.JPEG,
        compress: 0.8,
        base64: true
    })
}

```
こちらのやり方を適用して、ファイルサイズの適正化を行うことに成功したので、
備忘録としてこちらに記事を書かせていただきました。

当方、初の記事となるため、
もし不備な点などありましたらご指摘ください。
今後も、実装したところで、記事にしたほうが良いと思ったものは
逐次OUTPUTとして記事に上げようと思います。

### 参考情報
https://docs.expo.dev/versions/latest/sdk/imagemanipulator/
Virtual WANのAzure Firewallでは強制トンネリング不可

Virtual WANのAzure Firewall（セキュリティ保護付きハブ）について調べていたところ、Azure Firewallのドキュメントにひっそりと以下の注釈が記載されているのを見つけました。

> Virtual WAN ハブ (セキュリティ保護付き仮想ハブ) 内に Azure Firewall をデプロイする場合、Express Route または VPN Gateway 経由で既定ルートをアドバタイズすることは現在サポートされていません。 解決策を調査中です。

引用元：[Azure Firewall の強制トンネリング](https://learn.microsoft.com/ja-jp/azure/firewall/forced-tunneling)

現時点ではVirtual WANでAzure Firewallを利用する場合は0.0.0.0/0をアドバタイズできない（＝強制トンネリングができない）ということです。サポートにも確認して裏どりしました。実際に構成してから発覚すると手戻りの影響が大きいので注意が必要です。

なお、「解決策を調査中です」とあるので、改善予定があるのかも確認してみましたが、現状ではオープンにできる情報はないとのこと…。

:::note info
サポートへ確認したのは2025年3月時点です。
:::
機能仕様書を書く際に個人的に気を付けた方がいいなと思ったことメモ

# 目次
[気を付けること](#気を付けること)
[表記揺れ](#表記揺れ)
[その他気を付けた方がいい点](#その他気を付けた方がいい点)


# 気を付けること
:::note warn
既に存在する資料に、記載を追加したり、書き直しをする場合は、既存の記載に合わせてよしなに変えてネ★
:::


## 表記揺れ
表記揺れが起きやすそうなところは、以下で揃える
- タップ
    - ↑AndroidやiOSなどは、これで揃える
    - **「押す」** は、物理ボタンの場合に使うようにする
- （特別なルールが無ければ）単語の最後の伸ばし棒は付けないようにする
    - 数字に付けるマイナス記号（-）と間違えるのを防ぐため
    - 例）インジケータ
- ユーザ目線で、事象が主体的なのか、受け身なのかを揃える
    - 特に機能仕様書の場合、「機能仕様書を読む人」=「そのシステムを使う人（ユーザ）」となるため、ユーザ主体（使う人の目線）で書く
    - 例1）ユーザが選択肢の中から選択する（ユーザが主体的に動く）
→ **「選択する」** で揃える
    - 例2）システムが選択肢の中から選択する（ユーザから見るとシステムがやってくれる）
→ **「選択される」** で揃える

# その他気を付けた方がいい点
https://qiita.com/pe-pe-desu/items/3835751487a56fddd6e4
ubuntu トラブル（内部エラー発生ダイアログが出る）

::: note warn
本記事の後日談はこちら。
　[[後日談] ミニPCでUbuntu環境を構築](https://qiita.com/b-wind/items/6518901e51d032d52862)
:::

xrdp でログイン後に必ず内部エラーが表示される事象に見舞われました。
とりあえず解決（？）したので、これもメモとして投稿しておきます。

## 現象
xrdp ログイン後、デスクトップ画面のまましばらく放置していたら、下図のような「内部エラーダイアログ」が表示されるようになってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90456/412672f7-c97d-4af0-a631-10957e4164d2.png)

認証ダイアログ表示の問題を調査する中で、何かを壊してしまった可能性が大です。
　[Ubuntu トラブル（認証ダイアログが頻繁に出る）](https://qiita.com/b-wind/items/648a815c5d0bf5dc105c)


|項目|値|
|:-|:-|
|ExecutablePath|/usr/bin/Xwayland|
|Package|xwayland 2:23.2.6-1ubuntu0.4|
|Title|Xwayland crashed with SIGABORT in __libc_start_call_main()|

システムエラーの詳細を表示してみると、どうやら「Xwayland」に起因して発生している模様です。

## 対処方法
結局、調査中に実施した内容を元に戻しても解消されることはありませんでした。
ただ xwayland 関連の何かで不整合が発生していると思われるため、xwayland だけ再インストールすることにしました。

### ① システムのアップデート
```bash
sudo apt update
sudo apt upgrade
```

### ② Xwayland の再インストール

```bash
sudo apt install --reinstall xwayland
```

## 結果
xrdpログイン後、放置しても内部エラーが勝手に表示されることはなくなりました。
モジュール自体を壊したとは考えにくいので、何らかの設定を消したか上書きしたのでしょう。

これでようやく本当の作業に取り掛かれます。
まずは、Docker + Dify のインストールから始めることにしましょう。
iOS14+で使えるTextのリンク付与

# Textに対するリンク付与について
SwiftUI Text関数で表示する内容について一部分だけリンク化したい、そういった経験はありませんか？
例えば、表示文章内に"ログイン"という部分文字列があり、当該部分のみ押下時ログイン画面へ遷移などしたい場合です。

本アプローチはそういった場合に適用が可能です。

# 手順
```Swift
Text("既にアカウントがありますか？その場合は[ログイン](navigateToLogin)しましょう！")
    .environment(\.openURL, OpenURLAction { specifiedParam in
        switch specifiedParam.description {
        case "navigateToLogin":
            // ログイン画面へ遷移
        default:
            Void()
        }
        return .handled
    })
```

このようにリンク化したい部分をmd形式のように表すことができます。
更に優れているのはリンク毎に付与した引数を受け取ってハンドリングすることができる点です。
この特性を利用して、URLを開く以外にも様々な用途に応用することが出来ます。(想定された使い方かどうかは別だけど...)

# ソース
[Apple Developerサイト](https://developer.apple.com/documentation/swiftui/openurlaction)に記載されていました。
こちらは単純にURLを開く方法の紹介がされていますね。
：ブロック要素／インライン要素／インラインブロック要素と、CSSグリッドの基本をおさらい

# はじめに

HTMLとCSSを学ぶ上で避けて通れないのが、要素の「表示形式」や「レイアウトの仕組み」についての理解です。

特に、

- **ブロック要素 / インライン要素 / インラインブロック要素**
- **CSSのグリッドレイアウト**

は、Web制作やフロントエンド開発において非常に頻出します。

この記事では、それぞれの違いや使いどころを**自分の備忘録も兼ねて**まとめます。

---

# HTML：表示形式の違いを理解しよう

## ① ブロック要素（`display: block`）

- **1行全体を占有**する要素
- 常に**改行**される
- 幅・高さの指定が可能
- 他の要素とは**上下に並ぶ**

### 代表的なブロック要素

| タグ | 用途 |
|------|------|
| `<div>` | 汎用のコンテナ |
| `<p>` | 段落 |
| `<h1>`〜`<h6>` | 見出し |
| `<ul>`, `<ol>`, `<li>` | リスト |
| `<form>` | 入力フォームの囲い |

---

## ② インライン要素（`display: inline`）

- **テキストと同じ行に並ぶ**
- 幅や高さの指定が基本的にできない
- 主に「**部分的な装飾やリンク**」に使われる

### 代表的なインライン要素

| タグ | 用途 |
|------|------|
| `<span>` | 汎用のインライン要素 |
| `<a>` | リンク |
| `<strong>`, `<em>` | 強調 |
| `<img>` | 画像（※例外的にサイズ指定可能） |

---

## ③ インラインブロック要素（`display: inline-block`）

- **横に並びつつ、幅や高さも指定可能**
- ボタンやカードレイアウトなどに便利

### 使用例：

```html
<style>
  .box {
    display: inline-block;
    width: 100px;
    height: 100px;
    background-color: lightblue;
  }
</style>

<div class="box">A</div>
<div class="box">B</div>
```

# ④CSS：グリッドレイアウトの基本
**1.グリッドとは？**
- **縦・横の2軸（行と列）で要素を整列できるCSSレイアウト手法**
- 従来の float や flex に比べて、**複雑なレイアウトが簡単に組める**

**2.基本の書き方**

```CSS
.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}
```

```html
<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>
```

→この場合、要素が **3列×2行** に並びます。

**3.よく使うグリッドプロパティ**
![IMG_3961.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/1e3906a0-87c3-4b31-a372-5e2a29d3a65c.jpeg)

# ⑤比較まとめ: どれがどう違う？

**HTML要素の表示形式まとめ**
![IMG_3962.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/41bd3890-153c-460c-ba99-466aa6f74957.jpeg)

**グリッドとフレックスの違い**
![IMG_3963.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/149a60b0-18c8-46c6-affa-f510f7908e07.jpeg)

# ⑥：CSSフレームワークとの関連（Tailwind CSSなど）
最近は Tailwind CSS などのユーティリティファーストなCSSが主流になっていますが、**Tailwind も内部的には display: grid や display: inline-block を使っているため、** 基本概念を理解しておくことがとても大切です！

# ⑦まとめ
![IMG_3964.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/51275ff4-567b-4eda-a3fe-fa410f841519.jpeg)

- HTMLとCSSの基本に立ち返ることで、後々の Vue / React、Tailwind / Bootstrap、Laravel Blade でのビュー設計にも活きてきます！
インストールされている Power Automate Desktop のインストーラーのバージョンを取得する方法

# 前提
以下のリリースノートにおいて、インストールされている Power Automate Desktop がどれなのかを判別したい。そのために、Power Automate Desktop か Windows のレジストリから「Installer version」を取得したい。

https://learn.microsoft.com/ja-jp/power-platform/released-versions/power-automate-desktop

# 「Installer version」が記載されている場所
### トラブルシューティング
![スクリーンショット 2025-03-30 235937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629955/92cc4b33-33bb-40e9-b6dc-beef9f4fd71d.png)

### コンピューターランタイム
![スクリーンショット 2025-03-31 000621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629955/9d1b7228-111a-4020-af3b-93b848c670e5.png)

### レジストリ

- Path:
    - HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ {GUID}
- DisplayName:
    - Power Automate for desktop
- DeisplayVersion または BundleVersion:
    - ここにインストーラーのバージョン

![スクリーンショット 2025-03-30 235232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629955/6b2122b3-4243-4036-9aee-75ac4c04094b.png)

### インストーラーのバージョンを取得する PowrerShell コマンド
```PowerShell:PowerShell
Get-ItemProperty 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' |
Where-Object { $_.DisplayName -like "*Power Automate for desktop*" } |
Select-Object PSChildName, DisplayName, DisplayVersion, BundleVersion
```

上記コマンドで情報を取得してみたところ、「DisplayVersion」に 2.54.188.25066 と 2.54.00188.25066 の2種類があったが、この違いは謎。BundleVersion をインストーラーのバージョンとして考えれば良いのかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629955/e2863e76-5013-47d0-ba37-51de7ea7cfd0.png)

なおレジストリの GUID はインストーラーによって決められる
TouchGFXを使おう5～Lチカ編～

TouchGFXを使おう4～アニメーション～の続きです。

https://qiita.com/usashirou/items/d21e53005f2229f3fa35

今回は、TouchGFXでLEDを光らせてみましょう。
# 画面製作
新規プロジェクトを作成し、ボタンを2個作成します。
# インタラクションの設定
Interactionを以下のように設定します。

||Interaction1|
|---|:-:|
|Trigger|Button is clicked|
|Choose clicked source|On_switch|
|Action|Call new virtual function|
|Function Name|function1|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/fc50c75d-f8b3-e17f-c3c5-55da075af9d4.png)

# ピン設定
STM32CubeIDEを立ち上げた状態でSTM32CubeIDEフォルダのprojectファイルをダブルクリックし
__.project__ ファイルを __ダブルクリック__ プロジェクトをインポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ab877328-3311-bb34-4c51-94d50bb95e7b.png)
__Iperatin completed__ ⇒ __OK__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6ab4893b-f252-8581-521c-31249f2d0467.png)
立ち上げ後、iocファイルからLEDにつながる __PC2__ ピンを __GPIO Output__ にし __Generation__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/34f87b02-d39a-85fa-14e5-eaac34a73e2b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/a1c451ba-be7b-c31b-690e-5bf4e4f36c0d.png)
Warningが出ますが __Yes__ で進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6162f98f-ff2b-06ba-7d32-60c3b2fc860e.png)
TouchGFXでも変更されたことが表示されますので __Yes__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/924e233a-27bd-d7b5-bd99-7552871c9f1c.png)
# プログラム作成
今回、__Screen1View.hpp__ に追加する関数を宣言します。
### Screen1View.hpp

    virtual void function1();

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/1e8b2ecb-60f0-38ed-37c9-cb6a7d99a5dd.png)

__Screen1View.cpp__ に以下ププログラムを追加します。

ヘッダに
```
#ifndef SIMULATOR
#include "stm32h7xx_hal.h"
#endif
```
プログラム内に以下を追加します。
```
void Screen1View::function1()
{
	#ifndef SIMULATOR
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
	#endif
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/51a9cd82-18db-aec2-2fae-609cdfaf20dd.png)

# シミュレータエラー対策
そのままプログラムを記述するとTouchGFXにおけるシミュレータでエラーとなります。
シミュレータでは読まない設定にするために __#ifndef SIMULATOR__ を宣言しプログラムを記述していきます。

	#ifndef SIMULATOR
	#endif

コンパイルするとボタン操作に応じてLEDの切り替えが出来るようになります。
# TouchGFX内でのプログラム作成の例
ピン設定を行えば、プログラムをTouchGFX内で完結する手法があります。
__Action__ を __Execute C++ Code__ にし以下プログラムを入力します。

Code
```
#ifndef SIMULATOR
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
#endif
```
Includes
```
#ifndef SIMULATOR
#include "stm32h7xx_hal.h"
#endif
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e0040f6c-49f4-8858-cc94-4cce2046b974.png)
# 書込み
Program and Run Targetをすることで書き込み後、ボタン操作に応じてLEDが点滅すれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ef02abdb-6f94-5868-7a24-b4a79b5f59ba.png)
TouchGFXを使おう6～Lチカ編２～に続きます。
AZ-104の更新に挑む

ある日こんなメールが届きました。

> Microsoft Certified: Azure Administrator Associate 認定資格が更新の対象になりました。2025年9月23日 (UTC) までに更新評価に合格する必要があります。

むむむ。この間AZ-305に合格して安心していたところ、次はAZ-104の更新ですか、、、。
でもAZ-305の知識が頭に残ってるうちがチャンスかも、と思いメールが届いた次の日にチャレンジしました。

## 更新試験の概要
更新試験で問われる内容は以下です
- Azure App Service で Web アプリケーションをホストする
- Docker でコンテナ化された Web アプリケーションを構築する
- Azure ストレージ アカウントを保護する
- ネットワーク セキュリティ グループとサービス エンドポイントを使用して Azure リソースへのアクセスをセキュリティで保護して分離する
- Azure Backup を使用して仮想マシンを保護する
- 仮想マシンの可用性を構成する
- Microsoft Entra ID でユーザーとグループを管理する

試験は無料で試験時間は45分です。有効期限の180日前から受験することができます。通常の試験とは異なり、試験センターなどで受験する必要はなく自宅で気軽に受験できます。

## とりあえず受けてみる
資格の有効期限内であれば、何度でも繰り返し受験できるとのことだったので事前に勉強せず、とりあえず受けてみることにしました。

結果は正答率50%。はい、普通に不合格です。

試験方法はAZ-104のプラクティス評価ほぼ同じ形式でした（回答は表示されません）。次の問題に進むと前の問題には戻れなかったです。

https://learn.microsoft.com/ja-jp/credentials/certifications/azure-administrator/practice/assessment?assessment-type=practice&assessmentId=21&practice-assessment-type=certification

問題数は私の場合は26問でした。結果が表示されるページで57％以上正解で合格と書いてありました。受験前には合格ラインは書いていなかったのでここで初めて知りました。ちなみに、結果が表示されるページでは分野ごとの正答率のみが表示され、問題を振り返ることはできません。
また、試験時間は45分と書いてたのですが、試験中に残り時間は表示されていなかったので開始時間は事前にチェックしておいた方が良さそうでした（もしかしたら時間計られてないかも？）。

## 2回目の挑戦
1回目でどんな感じか掴めたので、少しだけ1回目の復習をしてすぐに2回目にチャレンジすることにしました。ちなみに、2回目が不合格だと以降の試験は24時間経過しないと受験できなくなります。

結果は、76％で合格でした！

1回目と同じ問題が半分くらいだったと思います。問題数も1回目と同じで26問でした。
合格すると、資格が更新されたというメールがすぐに届きました。更新した日から1年間延長されるのかと思っていたのですが、有効期限から1年間延長されたので次の有効期限は1年半後になりました。

## 受験してみて
とりあえず受験してみて感触を掴むことをお勧めします。1回目の結果から足りてなさそうなところを中心に復習すれば合格に近づけるのではないかと思いました。

最初からがっつり勉強して1回目で合格したい！という方は更新評価の準備というのが、更新試験のページにあるのでこちらで勉強すれば良いかと思います。Udemyの問題集を解き直したりとかまでは必要ないかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955838/eeacb3af-d83f-41cf-963d-22e2d3c3b8cd.png)

次はAZ-305の更新が半年後にあるので、サクッと合格したいです！
条件付き確率とベイズの定理を統計学の視点から徹底比較

# 条件付き確率とベイズの定理を統計学の視点から徹底比較 〜具体例で学ぶ基本と応用〜

統計学において「条件付き確率」と「ベイズの定理」は、基礎でありながら実務にも直結する重要な概念です。この記事では、統計検定の学習を兼ねて、この2つの違いや関係性を、具体的なデータを用いてわかりやすく解説します。

---

## 条件付き確率とは何か？

まず、**条件付き確率（Conditional Probability）**とは、ある事象 $B$ が起きたときに、別の事象 $A$ が起こる確率のことです。記号で表すと以下のようになります。

$$
P(A|B) = \frac{P(A \cap B)}{P(B)} \quad \text{（ただし } P(B) > 0\text{）}
$$

ここで、$P(A \cap B)$ は $A$ かつ $B$ が同時に起こる確率、$P(B)$ は事象 $B$ が起こる確率です。

---

## ベイズの定理とは何か？

**ベイズの定理（Bayes' Theorem）**は、条件付き確率を逆に求める公式です。

$$
P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)}
$$

これは、既知の情報（$B$ の観測）に基づいて、原因（$A$ の確率）を推定するもので、機械学習、医療診断、信頼性工学など幅広い分野で応用されています。

---

## 具体例：医療診断における条件付き確率とベイズの定理

### 例題：ある病気の検査

- ある病気の**有病率**（実際に病気を持っている人の割合）：1%（$P(\text{病気}) = 0.01$）
- 検査の**感度**（病気の人が陽性と出る確率）：99%（$P(\text{陽性}|\text{病気}) = 0.99$）
- 検査の**特異度**（健康な人が陰性と出る確率）：95%（$P(\text{陰性}|\text{非病気}) = 0.95$）

---

### Q1. 「検査が陽性だった場合、その人が実際に病気である確率」は？

ここで求めたいのは $P(\text{病気}|\text{陽性})$ です。これは**ベイズの定理**で計算します。

---

### ステップ1：確率の整理

- $P(\text{病気}) = 0.01$
- $P(\text{非病気}) = 0.99$
- $P(\text{陽性}|\text{病気}) = 0.99$
- $P(\text{陽性}|\text{非病気}) = 1 - 0.95 = 0.05$

---

### ステップ2：ベイズの定理を適用

$$
P(\text{病気}|\text{陽性}) = \frac{P(\text{陽性}|\text{病気}) \cdot P(\text{病気})}{P(\text{陽性})}
$$

分母の $P(\text{陽性})$ は全体で陽性となる確率で、以下のように計算されます：

$$
P(\text{陽性}) = P(\text{陽性}|\text{病気}) \cdot P(\text{病気}) + P(\text{陽性}|\text{非病気}) \cdot P(\text{非病気})
$$

$$
= 0.99 \cdot 0.01 + 0.05 \cdot 0.99 = 0.0099 + 0.0495 = 0.0594
$$

したがって：

$$
P(\text{病気}|\text{陽性}) = \frac{0.99 \cdot 0.01}{0.0594} = \frac{0.0099}{0.0594} \approx 0.1667
$$

---

### 結果の解釈

**陽性と診断されても、実際に病気である確率は約16.7%しかありません。**

この結果は直感に反するかもしれませんが、「母集団に対する病気の発生率（有病率）」が低いため、**偽陽性**の影響が大きいのです。

---

## 条件付き確率とベイズの定理の比較

| 観点 | 条件付き確率 | ベイズの定理 |
|------|----------------|---------------|
| 定義 | ある条件下での確率を求める | 条件付き確率の逆を求める |
| 主な用途 | 統計的推論、基本的な確率計算 | 逆推論（診断や推定） |
| 実用例 | 「雨の日に傘を持っている確率」 | 「傘を持っている人が雨に遭っている確率」 |

---

## 統計学における位置づけと重要性

- **条件付き確率**はあらゆる確率モデリングの基盤。
- **ベイズの定理**は**事後確率**の導出に不可欠で、特に**ベイズ統計学**ではコア概念となります。

---

## 結論

条件付き確率とベイズの定理は、密接に関連しながらも役割が異なる概念です。統計解析や意思決定において、「観測からどのように原因を推測するか」を考える際、ベイズの視点は非常に重要になります。

---
【備忘録】Windows環境において、vcpkg（クラシックモード）とCMakeを用いてライブラリを管理する

vcpkgとCMakeを用いてライブラリを管理する方法について述べる。
私は普段VSCodeとGCCのコンパイラを用いてプログラミングを行っている。その環境でvcpkgを用いてライブラリ管理を行う際の方法について記す。

# 丸投げ

https://learn.microsoft.com/ja-jp/vcpkg/get_started/get-started?pivots=shell-powershell

大体は上の記事の通りだ。ただ、上の記事はマニュフェストモードでの動作であり、ハマったポイントもあったので、忘れないうちにメモしておきたい。

# ハマったポイント：CMakePresetsにおけるTripletの指定漏れ
マニュフェストモード、クラシックモード双方に言えることだが、自分の環境に対応した適切なTripletが指定されていないと、以下のようなエラーが出る。
```
undefined reference to \`__imp__ZN3fmt3v116vprintENS0_17basic_string_viewIcEENS0_17basic_format_argsINS0_7contextEEE'
```
これを解決するのには、以下の内容が役に立った。

https://github.com/microsoft/vcpkg-docs/issues/439

この記事の内容を踏まえて、実行する環境に合わせて`CMakePresets.json`を以下のように変更した。
```
{
  "version": 2,
  "configurePresets": [
    {
      "name": "vcpkg",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
        "VCPKG_TARGET_TRIPLET": "x64-mingw-dynamic"
      }
    }
  ]
}
```

# ハマったポイント：マニュフェストモードとクラシックモードの差異
クラシックモードでは、あらかじめvcpkgを用いてライブラリをインストールしておく必要がある。また、パッケージのインストールの際にも正しいTripletを指定する必要がある。自分の環境の場合は、コマンドラインに以下のように入力すればよかった。
```
vcpkg install fmt:x64-mingw-dynamic
```

正しいTripletを指定することでこの問題を解決できるようだ。
type-challenges解いてみた 初級 189 easy-awaited編


# 問題

````md

Promise ライクな型が内包する型をどのように取得すればよいでしょうか。

例えば：`Promise<ExampleType>`という型がある場合、どのようにして ExampleType を取得すればよいでしょうか。

```ts
type ExampleType = Promise<string>

type Result = MyAwaited<ExampleType> // string
```
````


























## 回答

```ts
type MyAwaited<T> = T extends PromiseLike<infer U> ? MyAwaited<U> : T;
```

### ちょっと解説

- `T extends PromiseLike<infer U>`
もし T が PromiseLike であるなら、その中身の型を U として推論するという意味です。

- `MyAwaited<U>`
ネストしている場合に対応するため、再帰させています。

- `PromiseLike`
その名前の通り、擬似的なPromise型です。
これは自分もよくわかっていないので深く掘りたい...
【GitHub】リポジトリのディレクトリ構造を簡単に把握する方法

GitHubTreeを使用するとリポジトリのディレクトリ構造を簡単に把握できます。

https://githubtree.mgks.dev/?repo=mgks%2FGitHubTree&branch=main

![screen-shot-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/da514117-2b73-47b6-8a14-28b8bca665f7.png)

## 使い方

以下にリポジトリとブランチを入力し、「Fetch」ボタンを押下するとリポジトリのツリーが表示されます。

![screen-shot-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/f31731e4-e54e-4520-8ac3-24ce663ab081.png)

ツリーは以下のようにソートできます。

![screen-recording-9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ea044bea-529e-428b-8bd4-d89a03f6d43c.gif)

「Copy Complete Tree」を押下すると表示されているツリーをクリップボードにコピーできます。

![screen-shot-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ab5bb1a6-1b68-44f5-8fef-b15611f2da67.png)
PostgreSQLの機能を自分なりにまとめてみる

# PostgreSQLのSQL機能 
PostgreSQLの機能をわかりやすい言葉でまとめてみる。


### 1. SELECT（データを取得する）
```sql
SELECT * FROM sample;
```
→ `sample` テーブルからすべてのデータを取得する。

### 2. INSERT（データを追加する）
```sql
INSERT INTO sample (name, age) VALUES ('Yamada', 23);
```
→ `sample` テーブル内の新しい行を追加する。「name」列に「Yamada」
「age」列に「23」を追加する。

### 3. UPDATE（データを変更する）
```sql
UPDATE sample SET age = 26 WHERE name = 'Yamada';
```
→`name`列が`Yamada`の全ての行で、`age`列を`26`に変更する。

### 4. DELETE（データを削除する）
```sql
DELETE FROM sample WHERE name = 'Yamada';
```
→ `name`列が`Yamada` のデータを全て削除する。

## データの絞り込み・並び替え

### 5. WHERE（特定の条件に合うデータだけ取得する）
```sql
SELECT * FROM sample WHERE age = 20;
```
→ `age` が 20の行だけを取得する。

```sql
SELECT * FROM sample WHERE age > 20;
```
→ `age` が 20 より大きい行だけを取得する。

### 6. ORDER BY（データを並び替える）
```sql
SELECT * FROM sample ORDER BY age DESC;
```
→ `age` が大きい順に並べる。

### 7. LIMIT（取得するデータの数を制限する）
```sql
SELECT * FROM sample LIMIT 5;
```
→ 最初の 5 件だけ取得する。

### 8. OFFSET（取得するデータをスキップする）
```sql
SELECT * FROM sample LIMIT 5 OFFSET 10;
```
→ 10 件目から 5 件取得する（10件目までは取得しない）。

## データのグループ化・集計

### 9. GROUP BY（同じ値ごとにまとめる）
```sql
SELECT age, COUNT(*) FROM sample GROUP BY age;
```
→ 年齢ごとに何人いるかを集計する。

### 10. HAVING（グループの条件を指定する）
```sql
SELECT age, COUNT(*) FROM sample GROUP BY age HAVING COUNT(*) > 2;
```
→ 2 人以上いる年齢グループだけ表示する。

### 11. DISTINCT（重複を省く）
```sql
SELECT DISTINCT age FROM sample;
```
→ `age` の重複を省いて取得する。

## データの結合

### 12. INNER JOIN（共通するデータを結合する）
```sql
SELECT sample.name, orders.score 
FROM sample 
INNER JOIN orders ON sample.id = orders.user_id;
```
→ `sample` と `orders` を、`id` をキーにして共通データを取得する。

### 13. LEFT JOIN（左のテーブルのデータは必ず残す）
```sql
SELECT sample.name, orders.score 
FROM sample 
LEFT JOIN orders ON sample.id = orders.user_id;
```
→ `sample` に対応するデータのある `orders` の行だけ結合。対応する行が存在しない場合、`orders` テーブルの列は `NULL` になる。

### 14. RIGHT JOIN（右のテーブルのデータは必ず残す）
```sql
SELECT sample.name, orders.score 
FROM sample 
RIGHT JOIN orders ON sample.id = orders.user_id;
```
→ `orders` に対応するデータのある `sample` の行だけ結合。対応する行が存在しない場合、`sample` テーブルの列は `NULL` になる。

### 15. FULL JOIN（両方のデータを全部出す）
```sql
SELECT sample.name, orders.score 
FROM sample 
FULL JOIN orders ON sample.id = orders.user_id;
```
→ `sample` も `orders` も全部出し、関連がない部分は `NULL`。

## データベースの管理

### 16. CREATE TABLE（テーブルを作る）
```sql
CREATE TABLE sample (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    age INTEGER
);
```
→ `sample` というテーブルを作る。

### 17. DROP TABLE（テーブルを削除する）
```sql
DROP TABLE sample;
```
→ `sample` テーブルを削除する。

### 18. ALTER TABLE（テーブルの構造を変更する）
```sql
ALTER TABLE sample ADD COLUMN hobby VARCHAR(100);
```
→ `sample` テーブルに `hobby` という列を追加する。

## データベースの操作

### 19. SHOW（設定を確認する）
```sql
SHOW timezone;
```
→ 現在のタイムゾーンを確認する。

### 20. SET（設定を変更する）
```sql
SET timezone = 'Asia/Tokyo';
```
→ タイムゾーンを `東京` に変更する。

## データのバックアップと復元

### 21. COPY（データをファイルに書き出す）
```sql
COPY sample TO 'data/sample.csv' CSV HEADER;
```
→ `sample` テーブルのデータをCSVファイルに保存する。

### 22. COPY FROM（ファイルからデータを取り込む）
```sql
COPY sample FROM 'data/sample.csv' CSV HEADER;
```
→ `sample.csv` のデータを `sample` テーブルに取り込む。

## データベースの削除

### 23. DROP DATABASE（データベースを削除する）
```sql
DROP DATABASE my_database;
```
→ `my_database` を削除する。
Android開発で出てくるmapまとめ（自分用メモ）


Android開発でKotlinやJavaを触っていると至る所で`map`が出てきてややこしかったのでまとめてみます。

### コレクション型としてのMap
https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-map/

キーと値のペアを保持するコレクション型の一種。
mapOf()で値を生成する。
キーは一意である必要がある。
```test.kt
    val test: Map<String, String> = mapOf("key1" to "value1", "key2" to "value2")
    println(test["key1"]) // value1
```

### コレクションの拡張関数の.map
https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/map.html

すでに存在するコレクションを元に新たなコレクションを生成する。
```test.kt
    val integers = listOf(1, 2, 3)

    val twiceIntegers = integers.map {
        it * 2 // <- 各要素は"it"で取得できる
    }

    println(integers) // [1, 2, 3]
    println(twiceIntegers) // [2, 4, 6]
```


### LiveDataのTransformations.map
https://developer.android.com/reference/androidx/lifecycle/Transformations#map(androidx.lifecycle.LiveData%3CX%3E,%20androidx.arch.core.util.Function%3CX,%20Y%3E)

あるLiveDataの値が変わった時に他のLiveDataの値も変えたいという時に使う。
```TestViewModel1.kt
val useId = MutableLiveData<Int>()
val userName: LiveData<String> = Transformations.map(userId) {  id -> 
    "userName: ${id} "
}
```

```TestViewModel2.kt
val userLD : LiveData<User> = ...;
val userFullNameLD: LiveData<String> = userLD.map { user -> user.firstName + user.lastName }
```

### Coroutine flowの.map
Flowの各イベントを元に新しいFlowを生成する。

```test.kt
runBlocking {
    val numbers = (1..5).asFlow()
    val doubledNumbers = numbers.map { it * 2 }
    doubledNumbers.collect {
        println(it) // 246810が順に出力される
    }

```

### RxJavaのmap
流れてきたデータを変換する。
```test.kt
Observable.range(1, 5)
        .map(i -> i * 2)
        .subscribe(System.out::print); // 246810
```

型としてのMap以外はどれも「元の値に何か操作を加えて新しい値を生成する」という時に使われるようです。
Educational Codeforces Round #172 B を考えたメモ

# 題意

箱の中にビー玉が $n$ 個あり、それぞれ色が付いています。
このビー玉を使ってアリスとボブの2人がゲームをします。

2人は「好きなビー玉を1個選んで取る」という操作を交互に繰り返します。（アリスが先攻です）
ビー玉が全て取りつくされて箱が空っぽになったらゲーム終了で、下記に従ってアリスの得点が決まります。

- アリスが取った色の種類数を $a$ とする
- その $a$ 種類の色のうち、アリスが独占した色、つまりボブが取っていない色の種類数を $b$ とする
- アリスの得点は $a+b$ となる

アリスは、得点をなるべく大きくしようと行動します。
ボブは、アリスの得点をなるべく小さくしようと行動します。

**アリスは何点獲得できるでしょうか？**

ビー玉の個数と色が与えられたとき、アリスの得点を求めるプログラムを作成してください。

# サンプル

下図のように、12個のビー玉があるとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600213/53be773f-3db0-4536-bc0d-da2e0073fd4d.png)

2人が最適に行動すると、下図のような結果になるでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600213/a49264b9-96ed-45ce-8b9a-bf4c2acc5e2c.png)

- アリスが取った色は5種類
- その5種類の色のうち、アリスが独占した色、つまりボブが取っていない色は2種類（黄、青）

となっているため、5 + 2 = 7 より、アリスの得点は7点となります。

# 考えたこと

上図のサンプルでは、例えば青いビー玉は1個しかないため、アリスはこれを取るだけで独占となります。すると $a$ と $b$ が1ずつ増加することになり、2点獲得です。
このように「1個しかない色」がまだ残っているゲーム前半では、アリスはそれを狙うべきでしょう。また、ボブも積極的にそれを取り、アリスの独占回数を減らすべきでしょう。

そして「1個しかない色」がなくなったゲーム後半では、アリスの独占回数を増やしたくないボブは、アリスが取ったビー玉と同じ色のビー玉をすぐ取るという行動に出るべきでしょう。

すなわち、下記のようなゲームの流れになりそうだと考えました。

- 1個しかない色の種類数を $p$ とする
- 2個以上ある色の種類数を $q$ とする
- ゲーム前半は、アリスとボブが $p$ を半分ずつ奪い合う（独占なので1色取るたびに2点）
  - $p$ が奇数なら、アリスは $p+1$ 点獲得することになる
  - $p$ が偶数なら、アリスは $p$ 点獲得することになる
- ゲーム後半は、アリスは $q$ 種類の色のビー玉を順番に取る（独占ではないので1色取るたびに1点）
  - アリスは $q$ 点獲得することになる

まとめると、この問題の答え、つまりアリスの得点は下記のようになります。

- **$p$ が奇数なら、答えは $p+1+q$**
- **$p$ が偶数なら、答えは $p+q$**

さきほどのサンプルに当てはめると、$p=3$ および $q=3$ より、アリスの得点は $3+1+3=7$ と計算できます。

# Codeforces に提出！

このビー玉取りゲームの問題は、Codeforcesというサイトで開催されたプログラミングコンテスト「Educational Codeforces Round 172」の B 問題で出題されたものです。
問題のタイトルは「Game with Colored Marbles」です。

https://codeforces.com/contest/2042/problem/B

実際に、

- ビー玉が1個しかない色の種類数を $p$ とする
- ビー玉が2個以上ある色の種類数を $q$ とする
- $p$ が奇数なら、答えは $p+1+q$
- $p$ が偶数なら、答えは $p+q$

という計算を行うプログラムを実装して提出してみたところ、無事に正解と判定されました。良かったです。

```Java:提出コードの一部
int score = p + ((p % 2 == 1) ? 1 : 0) + q;
```

はじめに問題文を読んだときは「へんてこな得点計算をするゲームだなぁ」と思いましたが、意外とシンプルな計算式でアリスの得点を求めることができました。

以上、私が考えたメモでした。