OmniAICreator/Qiita-1.07M huggingface dataset:
Kokkosのチュートリアルをやってみた #1

Kokkos[^1]の勉強をしています。本記事は"The Kokkos Lectures - module 2"[^2]を参考にしています。

### Tutorial Exercise 01
Kokkos Tutorials[^3]のExercise01をやってみました。
これはBegin配下のプログラムをKokkos対応させるという練習問題になっています。

まず、事前準備としてSerialとOpenMPを有効にしたKokkosを構築しました。

```bash: Kokkosのビルド・インストール
$ cmake -B <build directory> -S </path/to/kokkos> \
  -DCMAKE_INSTALL_PREFIX=<install prefix> \
  -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++ \
  -DKokkos_ENABLE_SERIAL=ON -DKokkos_ENABLE_OPENMP=ON
$ cmake --build <build directory>
$ cmake --install <build directory>
```

configureのログでKokkos::OpenMPが有効になっていることが確認できました。

```console
:
-- Built-in Execution Spaces:
--     Device Parallel: NoTypeDefined
--     Host Parallel: Kokkos::OpenMP
--       Host Serial: SERIAL
:
-- Kokkos Backends: OPENMP;SERIAL
:
```

また、kokkos-tutorial[^3]のソースコードを取得しました。

```console
$ git clone https://github.com/kokkos/kokkos-tutorials.git
```

#### 01/Biginのビルド・実行

Exercise01について、まずはBeginのコードをビルド・実行してみます。

```console
$ cd kokkos-tutorials/Exercises/01/Begin
```

Makefileは各環境で書き換える必要があります。
`KOKKOS_PATH`に`Kokkos`のソースコードのディレクトリを指定します。
この配下の、ビルドした`bin`と`Makefile.kokkos`を参照しています。

```
KOKKOS_PATH=</path/to/kokkos>
```

ソースコード`exercise_1_begin.cpp`をビルドし実行してみました。

```console
$ make
:
$ ./01_Exercise.host 
  Total size S = 4194304 N = 4096 M = 1024
  Computed result for 4096 x 1024 is 4194304.000000
  N( 4096 ) M( 1024 ) nrepeat ( 100 ) problem( 33.5954 MB ) time( 0.421103 s ) bandwidth( 7.97795 GB/s )
```

#### 01/Solutionのビルド・実行

Beginを修正してkokkos対応されたソースコードにしてください、というのがこのTutorialですが、答えはSolutionの方にあります。
同様にMakefileを修正しビルド・実行してみました。

```console
$ make
:
$ OMP_PROC_BIND=spread OMP_PLACES=threads ./01_Exercise.host 
  Total size S = 4194304 N = 4096 M = 1024
  Computed result for 4096 x 1024 is 4194304.000000
  N( 4096 ) M( 1024 ) nrepeat ( 100 ) problem( 33.5954 MB ) time( 0.0957646 s ) bandwidth( 35.0812 GB/s )
```

実行時間が1/4ほどになりました。OpenMPの効果のようです。
`OMP_PROC_BIND`と`OPM_PLACES`は付けなくても実行できましたが、以下のように言われたので付けました。
> In general, for best performance with OpenMP 4.0 or better set OMP_PROC_BIND=spread and OMP_PLACES=threads


#### BeginとSolutionのコード比較

このチュートリアルではコードを変更する練習でした。
コードの対応として下記が必要ということでした。

- `Kokkos_Core.hpp`のインクルードを追加
- `Kokkos::initialize()`の追加
- `for`を`Kokkos::parallel_for`, `Kokkos::parallel_reduce`に書き換え
- `Kokkos::finalize()`の追加

詳しくは以下の記事に記載しました。

https://qiita.com/joule/items/9b097b9b8e2f3e40b07f

[^1]: https://github.com/kokkos/kokkos
[^2]: https://www.youtube.com/watch?v=O-asHTtO7O4&t=134s
[^3]: https://github.com/kokkos/kokkos-tutorials
Effect.gen みたいな関数を作ってみよう

## `Result` 型を便利に使いたい!

最近 Domain Model Made Functional を読みました

これを TypeScript で表現してみたいけど、`Railway Oriented` はやりすぎじゃ...
って思った矢先に、`Effect.gen` で Rust みたく Result を使えるっぽい!?

純関数型的に表現するのを、ちょっと妥協したいなと思っていたので
`Railway Oriented` じゃない `Result` をどうやるのか見てみたいと思いました

## そもそも `Effect.gen` って魔法みたいじゃないですか?

そもそも、型定義を見てもよくわからない...

僕が気になったのは以下の点です

* なぜ `yeild` ではなくて `yield*` なのか?
* なぜ `Generator` なのに個々の `yield*` に対して型を推論できるのか?

では、実際に `Effect.gen` っぽい関数群を作ってみて、なぜなのか確かめてみましょう

## 実際に作ってみよう!

### 基本的な `Result` の定義

`error: boolean` で場合分けする `Result` の定義は、こんな感じになります

```typescript
type Success<T,> = T & { error: false };
type Failure<F,> = F & { error: true };
type Result<T, F> = Success<T> | Failure<F>;

const toSuccess = <T,>(success: T) => ({ ... success, error: false }) as Result<T, never>;
const toFailure = <F,>(failure: F) => ({ ... failure, error: true }) as Result<never, F>;
const extractSuccess = <T,>(success: Success<T>) => { const { error, ... rest } = success; return rest; };
const extractFailure = <F,>(failure: Failure<F>) => { const { error, ... rest } = failure; return rest; };
```

### `gen` の定義

上記の `Result` を利用する `gen` の定義は、このような感じになります
ここの型はそんなに重要ではないので `unknown` で逃げています

```typescript
function gen<T, F>(definision: () => Generator<Result<unknown, NoInfer<F>>, Success<NoInfer<T>>, unknown>) {
  const generator = definision();
  let result = generator.next();
  if (result.done) { return result.value; }
  if (result.value.error) { return result.value; }

  while (true) {
    result = generator.next(extractSuccess(result.value));
    if (result.done) { return result.value; }
    if (result.value.error) { return result.value; }
  }
}
// definition: () => Generator<Result<unknown, NoInfer<F>>, Success<T>, unknown>) として Success<T> は推論してもいいです
```

### ユーティリティ関数の定義

ユーティリティとして `Result<T, F>` を受け取って `T` を受け取り
`T` をそのまま `return` する `Generator` を定義します

この関数がかなりのキモなポイントです

```typescript
function* unwrap<T, F>(a: Result<T, F>): Generator<Result<T, F>, T, T> {
  return yield a;
}
```

### 実際の利用例

使う側はこうやって `Effect.gen` と (ある程度) 同じメンタリティで使えます

キモは `unrwap` 側の `generator` に `yield*` で処理を委譲しているという点にあり、
これにより `yeild*` 毎に `unwrap` の結果を参照するため、型がその都度決まります
```typescript
const result = gen((function* () {
  const a = yield* unwrap(toSuccess({ hello: 'world', num: 5 } as const));
  let z = a.num < Math.random() * 10 ? toSuccess({ y: 'test' }) : toFailure({ x: 'fail' });
  const b = yield* unwrap(z);
  return toSuccess(b);
});

// この result をよしなにと...
```

## Pros/Cons

### Pros

#### 命令的に `Result` の Implicit な Early Return が表現できる

元々やりたいと思っていた、命令的な Early Return ができます
`Result` を剥がす操作で `Result` が `Failure` なら、ついでに `Return` してしまえます

これは便利だなと思いました

### Cons

#### Result の型を事前に決める必要がある

今回は `gen` で `NoInfer` で明示的に型の推論をしないようにしています
これは `Generator` が `yield` や `next` が毎回同じ型であることを期待するためです

このため、事前に共通の型の情報を与えなければならず、
実際に起こりえるエラー型の直和型をコードから直接推論することができません...

ここら辺をうまくできる方法があったら知りたいです...

### まとめ

`Effect.gen` がどうやって個々の型を推論しているのか謎でしたが
ステップバイステップで追っていくと、中心的な理屈がわかりました

ここで紹介した例は `Generator` でしたが、`AsyncGenerator` とすれば
非同期処理もまとめて扱えてお得になります
基本的には `AsyncGenerator` をラップすることになると思います

でも `yield*` を使う理由が型推論だけという理由なので、
あまりプロダクションコードに入れる気は (まだ) していないです...
GitHub CLIをつかう

個人的「質はともかく継続する」39日目です。
## githubのissueを一括操作
 
GitHub CLI を利用して、issueをエクスポートしたりインポートしたり出来ます。
 
## GitHub CLI のインストール
 
公式を参考にインストール。
https://github.com/cli/cli#installation
 
## ログイン

CLIでログインします。
私はブラウザで認証してますが、お好みで。
 
```sh
gh auth login
``` 

## リポジトリクローン
 
リポジトリをクローンして移動します。すでにクローン済みのリポジトリがあれば、そこに移動しましょう。
 
```sh
gh repo clone https://github.com/XXXXX.git
```
 
## エクスポート
 
出力したい項目を指定すると、指定した項目が出力されます。ステータスの状態等で絞り込むことも可能です。
https://cli.github.com/manual/gh_issue_list  
 
基本的な情報  
```sh
gh issue list
```
 
オープン中のみ  
```sh
gh issue list --state open
```
 
create issue で使える項目  
```sh
gh issue list --state all --json 'assignees,body,labels,milestone,title' > issue.json
```
 
すべて出力  
```sh
gh issue list --state all --json 'assignees,author,body,closed,closedAt,comments,createdAt,id,labels,,number,projectCards,reactionGroups,state,stateReason,title,updatedAt,url'
```
 
## インポート
 
現状はインポートする手段がないようです。
エクスポートしたjsonファイルをcsv等に変換して、クリエイト文を作成する等で代替はできそう。
 
作成出来る項目は以下参照。  
https://cli.github.com/manual/gh_issue_create
flutterのremote開発は簡単

flutterのremote開発は(ターゲットデバイスがwebブラウザなら)簡単です。

## やり方

Visual Studio Codeで開発している場合、SSHでリモートアクセスした先のターミナルで例えば以下のコマンドを打ちます。

```bash
flutter create --template=app my_remote_example
cd ./my_remote_example/
flutter run -d web-server --web-port 9999
```

`--web-port`を指定しない場合には、自動でポートが割り当てられます。

```bash
Launching lib/main.dart on Web Server in debug mode...
Waiting for connection from debug service on Web Server...         15.8s
lib/main.dart is being served at http://localhost:42457
The web-server device requires the Dart Debug Chrome extension for debugging. Consider using the Chrome or Edge devices for an
improved development workflow.

🔥  To hot restart changes while running, press "r" or "R".
For a more detailed help message, press "h". To quit, press "q".
```

この場合、`http://localhost:42457`でserveされていると書かれているので、VS Codeの[Local Port Forwarding](https://code.visualstudio.com/docs/editor/port-forwarding)機能を使って、SSHホスト側のポートを、SSHクライアント側にport forwardします。

そうすれば、SSHクライアント側で`http://localhost:42457`にアクセスした時、flutterでrunしている画面が見られるはずです。

## その他

(flutterを触りはじめでよくわかっていないが、androidのエミュレータもリモート開発する方法があるんだろうか)
サーバーにshellをカスタマイズして運用している。運用スタイルと見えてきた「なぜアンチパターンなのか」

私はfishが大変好きで、これをちょこちょこカスタマイズして使っている。
のみならず、自分が個人で運用しているサーバーでもfishを使っているし、ちょっとカスタマイズしている。
ここで大半の読者は嫌な予感がしたはずである「サーバーのshellにカスタマイズだって……？！」

これは、どうしてサーバーのshellのカスタマイズが禁忌とされてきたのかその理由を想像したりして、その上で「でも自分の環境なら大丈夫」と言えるなら便利に整理しておくのはいいんじゃないかというポエム記事だ。

なお、この記事で非常に重要なポイントとして、筆者は「個人開発者」であり、「基本的にメンテナンスを行うのは自分ひとり」「VPS（EC2みたいなやつ）ポッ建ての立ちっぱなしで作業している」という前提で作業している。この記事について批判する前にこの立場について理解したうえで議論してもらいたい。

## 素の状態のサーバーが好まれる2つ理由

１つ目の理由は、新任が入ってきたときに誰かが設定したエイリアスなんてしらないよ！ってなることだ。
２つ目の理由は、雨後の筍のごとく増えていくサーバーの中に普段のエイリアスがなかったら不便だからだ


### 疑問：本当に人が増えることを想定すべきなのか？
あなたが事業に所属しているなら、人が増える可能性はかなり高い。……スタートアップすぎて、明日の人員計画すらままならない状況でなければ。
しかし、個人開発なら当面は一人の作業ではないか

### 疑問：接続するサーバーは雨後の筍のごとく増えたり、そのサーバーは頻繁に削除されたり復活するのか？
Dockerの普及により、サーバーをお手軽に消滅させたり大量に並べたりするテクニックが世の中に溢れたと思う。
とはいえ、それが本当に必要かというと筆者はかなり疑問視していて、適度にVPSに直接ぶっこんでおいたほうが小回りが効くので良いと信じている。
そうであるならば、サーバーの中は永続的なので、ショートカットをバシバシ設定しても特に問題ないのではないか

## 「カスタマイズしない」信仰の源流に思いを馳せる

想像するに、色々なサーバー、それも客先のサーバーにsshして作業を終わらせて返ってくるみたいな歴戦の傭兵の知恵が源流なのではなかろうか。
そこからクラウド全盛になったことにより、より一層半端なファイルを置いても抹消される環境が当たり前になったのだと思う。

で、あなたの環境はどうですか？
私はfishいれるしなんか色々やりたいと思います。


## 色々なサーバーで同期とるのめんどいやん
つ chezmoi


この記事はコメント歓迎です。賛否あると思いますがどうぞ。
「satisfies」とTypeScriptの基本


## はじめに
この記事では、「satisfies」演算子の簡単な使い方と、いつ使うべきかを説明します。

## 「satisfies」演算子って何？
「satisfies」演算子は、ある型が特定の条件やインターフェースを満たすかどうかをチェックするものです。これにより、変数が指定された型やインターフェースの定義に沿っているかどうかを確認できます。

## なぜ便利なの？
例えば、2つの異なる値を持つ型を定義した場合、そのどちらが実際に使われているか分からないことがあります。「satisfies」演算子を使うと、特定の値の実際の型をより正確に把握できます。

### 例
```typescript
type allMyInfo = personalInfo | workInfo;
```
`allMyInfo`は、`personalInfo`か`workInfo`のどちらかになります。
```typescript
type personalInfo = "田中" | "佐藤" | "小林";
type workInfo = {
  id: number;
  bossAge: number;
};
```
次に、`allMyInfo`を使う`Person`型を定義します。これには2つの値があり、それぞれが`allMyInfo`を持っています。
```typescript
type Person = {
  myInfo: allMyInfo;
  myOtherInfo: allMyInfo;
};

const applicant: Person = {
  myInfo: "田中",
  myOtherInfo: { id: 123, bossAge: 28 },
};
```
この状態で、`toUpperCase`メソッドを呼び出そうとすると、次のようなエラーが表示されます。
```typescript
applicant.myInfo.toUpperCase();
// Error: プロパティ toUpperCase は型 allMyInfo に存在しません
```
これは、TypeScriptが`myInfo`や`myOtherInfo`の値の型を確定できないために発生します。

このエラーを修正するために、`if`文を使って`myInfo`が文字列型かどうかを確認し、その中で`toUpperCase`メソッドを使うことができます。
でも、ここで「satisfies」演算子が登場します。
```typescript
const applicant = {
  myInfo: "田中",
  myOtherInfo: { id: 123, age: 22 },
} satisfies Person;
```
`Person`型の後に`satisfies`を追加することで、TypeScriptはどの値を選ぶべきかを推論し、`toUpperCase`メソッドを使えるようにしてくれます。
Misskey（開発環境）を構築する

Misskeyの開発環境構築について、なんか手順があやふやなのでメモ
普通のローカル環境構築でもいいといえばいいんだけど、HotReloadが効かなかったりするのが嫌だと思ったらこのドキュメントを参考にしてほしい。

ローカルでとりあえず立ててみたいだけなんだ！コントリビュートとかはそこまで考えてないよって人はもっと簡単な記事があるのでそちらをどうぞ
Misskey（ローカルお試し環境・連合なし）を構築する #misskey - Qiita
https://qiita.com/fruitriin/items/04672855f0d69892ed72

この記事のレギュレーションは以下の通り
- Dockerがインストールされている
- Node 20.10くらいがインストールされている（*結構新しいNodeじゃないとインストールに蹴られる)
- npm i -g pnpm で pnpmがインストールされている



## 兎にも角にもDockerの中でNodeの開発をしたくない筆者

（恨みつらみが延々と続く）みたいなこともあるし、Dockerが間に挟まるとかオーバーヘッドでしかないんだから素でシュっとアプリは動いてほしい


ローカル環境との建て方の違いはここ
```
 mv compose.local-db.yml docker-compose.yml
```

compose.local-db.yml を採用している。

さて、 以下のように準備用のコマンドを叩いていこう
（buildが必要なのは本体がバブルゲームやmisskey-jsのビルド済みのファイルを要求するからだ）

```
pnpm i 
pnpm build
pnpm migrate
```

最後に以下のコマンドを実行すると、完全にモダンWeb開発なViteがゴリゴリ動く開発版Misskeyが立ち上がると思う。
```
pnpm dev
```

立ち上がったMisskeyにアクセスするには、ブラウザのアドレスバーに`http://localhost:5173`と入力して飛べばOK。

この記事は加筆・修正、コメントを求めます
Scannerから入力を受け付けたあと、エラー処理が無限に繰り返される（Java超初心）

## 前提
最初の頃に躓いたので、記録も兼ねて記載します。
Scannerで入力を受け付けたあと、仕様外の入力（例：数字の入力を求めているのに文字を入力）などが起こった場合、エラー時の処理が無限に繰り返されてしまう対処法です。
なお、ターミナルやコマンドプロンプトが無限ループを起こしてしまったときは、
Windows：ctrl　+　C
Mac：Control + C
で終了できますので、「初めて知った」という方は是非ご参考ください^^

## コンテンツ
下記のように年齢の入力をユーザーに求め、入力された数字に応じて
「成人です」
「未成年です」
と表示されるjavaのコードを書きます。

```
import java.util.Scanner;

public class ScannerBug {
  public static void main(String[] args) {
    // 入力受取のためのインスタンス生成
    Scanner scanner = new Scanner(System.in);

    while (true) {
      int ageInput = 0;
      System.out.println("年齢を入力してください");
      try {
        ageInput = scanner.nextInt();
        if (ageInput >= 20 && ageInput < 130) {
          System.out.println("成人です");
          break;
        } else if (ageInput < 20 && ageInput >= 0) {
          System.out.println("未成年です");
          break;
        } else {
          System.out.println("不正な値です");
        }
      } catch (Exception ex) {
        // 数以外が入力されたときは再入力を求める
        System.out.println("不正な値です");
      }
    }

    scanner.close();
    System.out.println("プログラムを終了します");
  }
}
```

動作は以下のようになります。

「5」が入力されたときは「else if」に入り、「未成年です」と表示
「20」が入力されたときは「if」に入り、「成人です」と表示
「150」が入力されたときは「else」に入り、「不正な値です」と表示されたあと、「年齢を入力してください」と表示。負の値のときも同様。
つまり、想定内の数字「0～129」を入力されたときだけ、結果が表示されてプログラムが終了するようになっています。

## しかし!
「a」などが入力されると画像のようにエラー時の処理がループしてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834469/36696eb3-bdb2-d998-4156-6bfca47c9522.png)

## 原因
catchブロックに入ったあと、Scanner型の変数scannerに「a」が残っており、エラー時の処理がループしている。

### 詳細説明
まずはプログラムの流れを追います。
```
 Scanner scanner = new Scanner(System.in);
```
Scanner型の変数scannerのインスタンスを生成。scannerにはユーザーの入力したものが入る。
ユーザーが「a」と入力。scannerには「a」が入る。
```
ageInput = scanner.nextInt();
```
int型の変数ageInputにint型の要素を入れようとするが、「a」は数字ではないため、エラーが発生。処理がcatchブロックへ進む。
```
System.out.println("不正な値です");
```
こちらは問題なく実行される。他の処理がないため、while(true)まで戻る。

:::note warn
このとき、scannerには「a」が入った状態のままとなっている！
:::
```
ageInput = scanner.nextInt();
```
int型の変数に文字「a」を入れようとしているため、エラーが発生。catchブロックの処理が実行される。
以下ループ……
という流れになっていたんですね。
デバックモードで動かしてみると、変数にどのような値が入っているのか、コードのどの部分まで正常に動いているのか、確認できるので積極的に使っていきたいところです。

## 解決法
scannerをリセットすればいい、となります。方法はいくつかありますが、catchブロック内に
``` 
scanner.next();
```
を追記することで解消されます。

### 詳細説明
「.next();」は空白までの文字列の入力を受け取るメソッドです。似たものに「.nextLine();」がありますが、こちらは改行を判別する、という点で少し違います。
ユーザーが「a」を入力したとき、scannerには「a」が入ります。
その後、catchブロック内でscanner.next();を実行したとき、「a」を入力したときの入力内容が参照されており、「a」以外何も入力されていなければ、scannerにはnull（※ざっくり言うと”何もない”というもの）が入ります。
※catchブロック内にscanner.nextLine();と記載した場合は、ユーザーが「a」を入力した後に実行したエンターキーの入力が読み込まれ、改行コードの「\n」がscannerに入ります。
こうすることによって、変数のsannerが空になる、というわけです。
そのため、while(true)に処理が戻っても、scannerは空なので1からコードが実行されていきます。

## 最後に
Scannerを呼び出す度に変数名を変えてインスタンスを再生成したりしていたのですが、それはエレガントなコードとは言えないそうです。
そのため変数のscannerを使い回していたのですが、今度は上記の無限ループが発生してしまいました。
複数入力を求めるプログラムの場合、色々な箇所で「.next();」や「.nextLine();」を追記する必要があり、「見にくいのでは？」と疑問に思ったりもするのですが、現状の記録として、初心者の方のご参考になれば嬉しいです！

※勉強中の身ゆえ、記載内容に不適切な箇所などありましたら、諸先輩方からご指摘いただけますと幸いです。
Misskey（ローカルお試し環境・連合なし）を構築する

意外とハマるという噂なのできちんと整理したいと思います。

今回のターゲットはローカルお試し環境で構築します。連合しない予定です。
開発環境の作成と本番環境の構築はそれぞれ別の記事で解説します。

Misskey（開発環境）を構築する #misskey - Qiita
https://qiita.com/fruitriin/items/533f04f8e5c1e7f28297


この記事で必要な能力はDockerをインストールすることです。
以下主にMacで進みますがWindowsではハマりポイントがあるかもしれません。

Misskeyローカルお試し環境についてレギュレーションを整理します。
- Misskeyに関連するものはすべてDockerで起動する
- 4GB以上の空きメモリを確保すること

それではいきましょう。

```shell
 git clone https://github.com/misskey-dev/misskey.git
 ```

 これで misskey というディレクトリに misskey-dev/misskey がインストールされます。
 
 ```sh
cd .config
 ```

 .configというディレクトリに移動します。

 ```.sh
mv docker_example.env docker.env
mv docker_exanoke.yml default.yml
 ```
mvコマンドでファイル名を変えています。
docker.envは Docker用の設定ファイルです。環境変数を設定している模様。
今回は動けば大変満足なのでこのままでよいでしょう。

default.ymlについてはMisskeyのWeb上から編集できない設定が書かれています。

さて cd ../ でconfigディレクトリを抜け、misskey本体のディレクトリに戻ってきます。

```.sh
mv compose_example.yml docker-compose.yml
```

compose_example.ymlがワンショットで関連するサービスすべてが入ったdocker composeなので、こちらを使って起動していきます。

```sh
# お使いのdockerのバージョンによっては docker-compose up じゃないと動かないかも
docker compose up
```

```
web-1    | > misskey@2024.5.0 start /misskey
web-1    | > pnpm check:connect && cd packages/backend && node ./built/boot/entry.js
web-1    | 
web-1    | 
web-1    | > misskey@2024.5.0 check:connect /misskey
web-1    | > cd packages/backend && pnpm check:connect
web-1    | 
web-1    | 
web-1    | > backend@ check:connect /misskey/packages/backend
web-1    | > node ./scripts/check_connect.js
web-1    | 
web-1    |   _____ _         _           
web-1    |  |     |_|___ ___| |_ ___ _ _ 
web-1    |  | | | | |_ -|_ -| '_| -_| | |
web-1    |  |_|_|_|_|___|___|_,_|___|_  |
web-1    |  v2024.5.0               |___|
web-1    | 
web-1    |  Misskey is an open-source decentralized microblogging platform.
web-1    |  If you like Misskey, please donate to support development. https://www.patreon.com/syuilo
web-1    | 
web-1    | --- ed4c7cfcf3de (PID: 127) ---
web-1    | INFO *	[core boot]	Welcome to Misskey!
web-1    | INFO *	[core boot]	Misskey v2024.5.0
web-1    | INFO *	[core boot env]	NODE_ENV: production
web-1    | INFO *	[core boot nodejs]	Version v20.12.2 detected.
web-1    | DONE *	[core boot config]	Loaded
web-1    | DONE *	[core boot]	Misskey initialized
```

起動しましためでたい。

前段にnginxなど何も用意してないので、localhost:3000でアクセスすればアクセスすることができます。
![スクリーンショット 2024-07-16 0.15.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/b69c4159-652f-eb96-5741-b145854ef7d0.png)

ちょっとうれしいですね！
ちなみにドメイン名がシッチャカメッチャカなのでこのまま本番運営に移行すると大変なことになります。
あくまでお試しがよいかなと思います。


この文章は加筆修正リクエスト、コメントを募集しています。
Disk, disk, sleuth! II のWriteup

### [Disk, disk, sleuth! II](https://play.picoctf.org/practice/challenge/137) の Writeup

問題に記載のディスクイメージのdown-at-the-bottom.txtというファイルにフラグがあるらしいのでイメージを分析する

問題の「sleuth」とは「探偵」という意味らしい。

同名のフォレンジックツール「**Sleuth kit**」を使ってディスクイメージを分析していく

まずmmlsコマンドでディスクイメージのパーティションテーブルをダンプする

```bash
mmls dds2-alpine.flag.img 
```

実行結果

```bash
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000262143   0000260096   Linux (0x83)
```

Linuxと説明のある2つめのパーティションがメインのパーティションのようなのでここを掘っていく

flsコマンドで2つ目のパーティションのStart値をoffsetに指定してパーティションの中身をみてみる

```bash
fls -o  2048 dds2-alpine.flag.img 
```

実行結果（d/dはディレクトリ、r/rはファイルを示している）

```bash
d/d 26417:      home
d/d 11: lost+found
r/r 12: .dockerenv
d/d 20321:      bin
d/d 4065:       boot
d/d 6097:       dev
d/d 2033:       etc
d/d 8129:       lib
d/d 14225:      media
d/d 16257:      mnt
d/d 18289:      opt
d/d 16258:      proc
d/d 18290:      root
d/d 16259:      run
d/d 18292:      sbin
d/d 12222:      srv
d/d 16260:      sys
d/d 18369:      tmp
d/d 12223:      usr
d/d 14229:      var
V/V 32513:      $OrphanFiles
```

順番にflsで見ていくと、tmpフォルダ内にdown-at-the-bottom.txtがあることが分かる

```bash
fls -o 2048 dds2-alpine.flag.img 18290
```

実行結果
```bash
r/r 18291:      down-at-the-bottom.txt
```


icatコマンドでファイルの中身を見てみる

```bash
icat -o 2048 dds2-alpine.flag.img 18291
```

フラグ文字列が表示される
Bash で function 定義

Bash スクリプトで関数( function ) を定義する方法についてメモ。  
Bash における関数の基本的な定義方法と、関数間で引数を伝搬させる方法について書いていく。  

## Bashにおける関数の記述方法

Bashにおいて関数を定義するには、主に2つの方法がある。  
1つはfunctionキーワードを使用する方法、もう1つはキーワードを使用せずに関数名の後に`()`を付ける方法。  


### 関数の定義方法

`function` キーワードを使用する方法

```bash
function my_function1() {
    echo "This is a function1"
}
```

`function` キーワードを使用しない方法

```bash
my_function2() {
    echo "This is a function2"
}
```

`function` キーワードは任意のため、どちらも同じように機能する。 

 ### 関数の呼び出し方法

定義された関数を呼び出すには、関数名をそのままコマンドのように使用する。  

例:

```bash
my_function  # my_functionを呼び出す
```

引数を関数に渡す場合は、関数名の後にスペースを空けて引数を記述する。  

```bash
my_function "arg1" "arg2"  # 2つの引数を持つmy_functionを呼び出す
```

### 実際にやってみる

`func_test.sh` を作成して実行してみる。  

```bash
# func_test.sh の中身確認
$ cat func_test.sh
#! /bin/bash

function my_function1 {
    echo "This is a function1"
}

my_function2() {
    echo "This is a function2"
}

my_function1
my_function2

# func_test.sh 実行
$ bash func_test.sh
This is a function1
This is a function2
```

## Bashスクリプトファイル内の関数をターミナルで使用する

Bash スクリプトファイルで定義した関数をターミナルのコマンドとして使いたい場合、関数を含むスクリプトファイルをソース化してしまうのが早い。  
そのためには `source` コマンドまたは `.`(ドット)コマンドを使用する(`source .bashrc` とかやったことがある人も多いと思う)。  
例として、上記の `func_test.sh` をソース化してみる。  

```bash
$ source func_test.sh
# または
$ . func_test.sh

# コマンドとして実行
$ my_function1
This is a function1
```

## おまけ: 関数間で引数を伝搬させる


以下では、2つの引数を `first_function` から `second_function` に伝搬させるコード (`function2function_test.sh`)

```bash
#!/bin/bash

# 最初の関数を定義
function first_function {
    msg1=$1  # 最初の引数
    msg2=$2  # 二番目の引数
    echo "First function: ${msg1}, ${msg2}"
    # 第二の関数に引数を伝搬
    second_function "${msg1}" "${msg2}"
}

# 第二の関数を定義
function second_function {
    msg1=$1  # 最初の引数
    msg2=$2  # 二番目の引数
    echo "Second function: ${msg1}, ${msg2}"
}

# 最初の関数を引数とともに実行
first_function "Hello" "Bash"
```

実行してみる

```
$ bash function2function_test.sh
First function: Hello, Bash
Second function: Hello, Bash
```

めでたし！
【GitHubActions】プルリクエストがマージされた時にワークフローを実行する方法

`.github/workflows/xxx.yml`に以下のように記述するとプルリクエストがマージされた時にワークフローが実行されます。

```yml
on:
  pull_request:
    types:
      - closed

jobs:
  if_merged:
    if: github.event.pull_request.merged == true
```

## 参考

https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-pull_request-workflow-when-a-pull-request-merges
LeetCode挑戦日記：Day40

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 1161. Maximum Level Sum of a Binary Tree

二分木の根が与えられたとき、その根のレベルを1、その子ノードのレベルを2とします。
レベル`x`におけるノードの値の合計が最大になるような最小のレベル`x`を返します。

## 素直に解いてみる

### 考え方

1. 各レベル毎の合計値を計算し、配列にまとめる
1. 最大値となる配列のインデックスを求める

### コーディング

```typescript
function maxLevelSum(root: TreeNode | null): number {
    const layerSum: number[] = [];
    const func = (root: TreeNode | null, layer: number): void => {
        if (!root) { return; }
        if (layerSum[layer] === undefined) {
            layerSum.push(root.val);
        } else {
            layerSum[layer] += root.val;
        }

        func(root.left, layer + 1);
        func(root.right, layer + 1);
    }
    func(root, 0);

    let max = layerSum[0];
    let maxIndex = 0;
    for (let i = 1; i < layerSum.length; i++) {
        if (max < layerSum[i]) {
            max = layerSum[i];
            maxIndex = i;
        }
    }

    return maxIndex + 1;
};
```

### 結果

Runtime：130ms
Beats 93.75%

Memory：68.34MB
Beats 96.59%
LeetCode挑戦日記：Day39

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 199. Binary Tree Right Side View

二分木の根が与えられたとき、自分がその右側に立っていると想像して、上から下に向かって見えるノードの値を返します。

## 素直に解いてみる

### 考え方

1. 各階層毎のノードを値を左から確認していき、`Map`に入れる
1. レスポンス用の配列を作成する

### コーディング

```typescript
function rightSideView(root: TreeNode | null): number[] {
    const map = new Map<number, number>();

    const func = (root: TreeNode | null, layer: number): void => {
        if (!root) { return; }

        map.set(layer, root.val);
        func(root.left, layer + 1)
        func(root.right, layer + 1)
    }
    func(root, 0);

    const response: number[] = []
    for (let i = 0; i < map.size; i++) {
        const num = map.get(i)
        if (num !== undefined) {
            response.push(num)
        }
    }

    return response;
};
```

### 結果

Runtime：59ms
Beats 80.08%

Memory：51.69MB
Beats 94.05%

## `Map`を使わないように改修する

### 考え方

1. 各階層毎のノードを値を右から確認していき、レスポンス用の配列に入れていく

### コーディング

```typescript
function rightSideView(root: TreeNode | null): number[] {
    const response: number[] = [];
    const func = (root: TreeNode | null, layer: number): void => {
        if (root === null) { return; }
        if (response[layer] === undefined) { response.push(root.val); }

        func(root.right, layer + 1)
        func(root.left, layer + 1)
    }
    func(root, 0);

    return response;
};
```

### 結果

Runtime：53ms
Beats 93.27%

Memory：51.81MB
Beats 81.24%
LeetCode挑戦日記：Day38

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 236. Lowest Common Ancestor of a Binary Tree

二分木が与えられたとき、木の中の2つの指定されたノードの最小共通祖先（LCA）を見つけます。
WikipediaのLCAの定義によると、「最小共通祖先は、木Tにおいて、ノード`p`とノード`q`の両方を子孫に持つ最も低いノードとして定義されます（ノード自体をその子孫と見なすことができます）」。

## 素直に解いてみる

### 考え方

1. 指定されたノードを見つけたらそのノードを返す再帰関数を作成する
1. 各ノードの子ノードの両方からノードが返されたら、そのノードをLCAとする

### コーディング

```typescript
function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: TreeNode | null): TreeNode | null {
    const func = (root: TreeNode | null, values: number[]): TreeNode | null => {
        if (!root) { return null; }

        if (values.includes(root.val)) {
            return root;
        }
        
        const l = func(root.left, values);
        const r = func(root.right, values);

        if (l && r) {
            return root;
        } else if (l) {
            return l;
        } else if (r) {
            return r;
        }
        return null;
    }
    return func(root, [p.val, q.val]);
};
```

### 結果

Runtime：66ms
Beats 83.03%

Memory：59.89MB
Beats 39.35%
プログラムの特許戦略についてのメモ書き

端的にプログラムの特許って取ったほうがいいのか？
それとも取らないほうがいいのか？
について
中小企業の観点からメモ書きです。

---
# 観点1. 外から見えるか？見えないか？

外から見えるUI、UXに関する特許相当の技術がある場合
これは模倣が容易ですので、
知財で保護したほうが良さそうです。

あんまりないかもしれないですけど、javascriptで実装されてたりしたら、
ソースコード見えちゃいますので、これも特許化したほうが良い属性のものです。


一方でアルゴリズムを知財で保護する場合、
・外から見たらブラックボックスであるために、他社の類似ソフトが、本当にまるっとぱくってるか主張が難しい
・特許せずブラックボックスとして通すことで、他社からパクられるのを防ぐ効果がある
という観点があるため、
やや特許にしない方が有利に働く場合が多そうです


クローズドな工場内施設で使われる機械とプログラムのセット
（工場でも決められた一定の人しか入れない秘密のエリアにある機械）
なんかは、逆に特許にしちゃいけないたぐいですね。

---
# 観点2. ビジネス化に有利に働くか？

以下の効果が有ります
* toC向けの宣伝文句になる
* toB向けにも宣伝文句になる。特にアカデミックに近いところに売りに行く場合、エビデンス、論文、特許のいずれかを求められやすい印象です（数少ない経験上の感想です）
* 大企業と協業や技術売っぱらいのタイミングで、パクられるのを防ぐ
  -> 特に大企業には知財部だったり、専任弁理士、弁護士団が控えているので
  　　裁判沙汰になったとしても、言い負かされる可能性が高いです。

このへんのメリットやデメリットを重く見るなら特許取得しておいたほうが無難です。

---
# 観点3. コスト面

特許自体の申請費用はまあまあで、出願だけなら１０万円見とけば良いですが、
請求項や明細書を弁理士に頼むと、作文代金でトータル５０万円〜クラスの出費になります。

中小の体力だと、あんまりバカスカ数打つ作成なんてとれませんし、
そもそも１個すら通らないかもしれません。

---

# まとめ

特許はビジネスとして使うものですので
やはり、コストに見合っただけのビジネス効果が得られるか、
それに#1で述べた、外側から見える（パクられる）性質のあるプログラムであるかどうかという観点をくわえて
特許にするかどうか判断する戦略が良いかもしれません。

以上、知財専門家ではない一般社員のポエムでした。
Elixir をWindows11のwsl2にセットアップする手順（覚え書き）

Elixir をWindows11のwsl2にセットアップす手順の覚え書きです。

Elixirのセットアップ手順は、先駆者の方々がこれまで投稿された記事が多数あり、それらを参考とさせていただきました。

この記事では、2024/7/15時点のErlang & Elixirの最新バージョンをasdfを使用してセットアップする手順を記載しています。



## 1 インストール先の環境

　Windows11 HOME
　wsl2
　Ubuntu 24.04 LTS　（注）Microsoft Storeで検索＆インストール

## 2 インストールの参考情報

　書籍：　Elixir 実践入門ーー基本文法、Web開発、機械学習、IoT https://amzn.asia/d/08N2qTy3
　書籍：　Elixir 実践ガイド https://amzn.asia/d/06cluAlR

　Elixir公式サイト： https://elixir-lang.org/install.html
　apdf公式サイト： https://asdf-vm.com/guide/getting-started.html
　YouTube daimon_ex チャンネル： https://www.youtube.com/watch?v=hMN6YlqNls8

　Phoenix公式サイト： https://www.phoenixframework.org/
　PostgreSQL公式サイト： https://www.postgresql.org/
　日本PostgreSQLユーザ会： https://www.postgresql.jp/



## 3 asdfのインストール

前提条件

ユーザのhomeフォルダ（Ubuntuターミナル起動直後のフォルダ）で、インストールを実行する。
aptコマンドは、sudoコマンドを使いスーパーユーザ権限で実行する。
asdfコマンドは、sudoは不要です。（sudoを付けずに）そのままasdfコマンドを実行する。

インストール手順：asdf公式サイトに記載の手順に沿って実行する。

### 3.1 依存モジュールのインストール

sudo apt install curl git

### 3.2 asdfのダウンロード

git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0

### 3.3 asdfのインストール（~/.bashrcに環境変数を追加する）

エディタで .bashrc を開き、最後に以下の２行を追加して保存&クローズする。


. "$HOME/.asdf/asdf.sh"
. "$HOME/.asdf/completions/asdf.bash"

その後、以下を実行する。

source ~/.bashrc

動作確認

asdf


version: v0.14.0-ccdd47d
以下usage

が表示されれば動作は正常です。

### 3.4 unzipのインストール

sudo apt install unzip -y

## 4 Erlang ＆Elixirのインストール

### 4.1 Erlang 依存モジュールの確認

https://github.com/asdf-vm/asdf-erlang

で、
Before asdf install
Ubuntu 24.04 LTS
のところを確認

sudo apt -y install build-essential autoconf m4 libncurses5-dev libwxgtk3.2-dev libwxgtk-webview3.2-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev unixodbc-dev xsltproc fop libxml2-utils libncurses-dev openjdk-11-jdk


### 4.2 asdf erlang plugin のインストール

（注）インストール方法は、asdf erlang plugin で検索。

asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git

### 4.3 asdf elixir plugin のインストール

（注）インストール方法は、asdf elixir plugin で検索。

asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git 


### 4.4 インストールできるerlangのバージョンを確認する。

asdf list-all erlang

（2024/7/15時点の最新バージョンは、27.0.1）

### 4.5 インストールできるelixirのバージョンを確認する。

asdf list-all elixir

（2024/7/15時点の最新バージョンは、1.17.2-otp-27）　（注）インストールするElixirのバージョンとErlangのバージョンを合わせる必要がある。otp-27の部分）

### 4.6 erlangのインストール

asdf install erlang 27.0.1

### 4.7 elixirのインストール

asdf install elixir 1.17.2-otp-27

### 4.8 使用するerlangのバージョンを指定する

asdf global erlang 27.0.1

### 4.9 使用するelixirのバージョンを指定する

asdf global elixir 1.17.2-otp-27

### 4.10 elixirの動作を確認する

elixir -v

iex



### 2024/7/15 はここまで（erlangとelixirのインストールまで）

Phoeninx と PostgreSQLのセットアップの記事を投稿しました。

[Elixir に続いて、PostgreSQL と Phoenix をWindows11のwsl2にセットアップする手順（覚え書き）
](https://qiita.com/hattun_geh01713/items/8e05c905a0a74a177164)
【備忘録】AWS構成図をサクッと作る「draw.io」

記事ではなく、学んだことを書き留めておく備忘録シリーズです。

↓ こんな感じの、AWSを触っているとよく見る構成図。
![aws-sekigime2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676797/89832a7a-dcdc-41c2-0935-a09dd70685f2.png)

それをサクッと作れてしまう描画ツールが「draw.io」、ER図と同じような感覚で作成できます！

https://www.drawio.com/

使い方は以下の記事を参考にしました！

https://aws.taf-jp.com/blog/61489

https://aws.amazon.com/jp/builders-flash/202204/way-to-draw-architecture/
Pythonで極座標のヤコビ行列を作る

## なぜ今ヤコビ行列なのか
先日、久しぶりにお会いした研究室の先輩がヤコビアンについて熱く語っていたから

## 極座標のヤコビ行列
直交座標`(x,y)`から極座標`(r,θ)`の変換式は次の通り
```math
\displaylines{
 x = r\cos\theta \\
 y = r\sin\theta
}
```
これのヤコビ行列は次の通りとなる
```math
\displaylines{
    \begin{pmatrix}
        \frac{\partial x}{\partial r} & \frac{\partial x}{\partial \theta} \\
        \frac{\partial y}{\partial r} & \frac{\partial y}{\partial \theta}
    \end{pmatrix}
    =
    \begin{pmatrix}
        \cos\theta & -r\sin\theta \\
        \sin\theta & r\cos\theta
    \end{pmatrix}
}
```

## pythonで実現
```jacobian.py
import numpy as np

def jacob_array(r, theta):
    return np.array([[np.cos(theta), -r*np.sin(theta)],[np.sin(theta), r*np.cos(theta)]])

# r=1, theta=0の場合
j = jacob_array(1,0)

print(j)
```

## 実行結果
```
python jacobian.py
[[ 1. -0.]
 [ 0.  1.]]
```
urqlのキャッシュ理解が足りなくて

## はじめに
urqlとは：React向けの軽量で柔軟なGraphQLクライアントライブラリ
その中でも`cache-updates`についてのアウトプットです

https://commerce.nearform.com/open-source/urql/docs/graphcache/cache-updates/

## 大事なのは__typename

ミューテーションで更新があった場合、`__typename`を理解して
勝手にキャッシュを更新してくれます。

ですので、更新などのコマンドが操作された時に
BFFからIDのみを返すのではなくて`__typename`が入ったスキーマの形を返してあげると、
データ更新後の取得をフロントが気にする必要がなくなります。

BFF内で更新＋取得を行い該当の`__typename`の型で返してあげることを意識するということです。
これができるとフロントで無駄なstate管理をする機会が減り、
謎のコンポーネント間のバケツリレーをする必要がなくなります。

### 失敗の思い出
BFFのservice内でコマンドのAPIを作成しているときに、
> コマンドのAPIはコマンドしか呼ばずにIDだけを返そう。
> 画面更新するまでに即時反映しないデータはその時だけ`useState`でバケツリレーして
> `useEffect`で更新してあげよう。

という取り決めをしたことがありました。

そしたらどうでしょう。
遠くから更新の処理でやってきたstateが下から上まで通って渡らなくてはいけなくなったり
一番上のtemplateで多くのstateを持たなくてはいけなくなるなど
保守がとんでもなく大変なことになりました。
これはなぜスキーマが`__typename`を持っているのかなどキャッシュについて理解が足りていなかったことが問題だったなと今では思います。
~~今でもその保守に追われております~~

## さいごに
せっかく`GraphQL`で`urql`を採用しているのにキャッシュの機構を理解しないのは勿体無いなと思い
改めてドキュメントを読んでいるところです。
ここら辺は相手に説明できるくらいである必要があると感じているのでしっかり知識として取り入れたいです。
CostExplorerにアクセスすると「この操作を実行する権限がありません」と言われてしまう

## 起きたこと
AdministrotorAccessを付与したSwitchRoleを用いているのに、「この操作を実行する権限がありません。」というエラーでCostExplorerを確認できなかった...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045261/3879ca10-1f0c-895a-b6ab-8c44a04c1024.png)


## 原因
Billing and Cost Management console(請求情報とコスト管理コンソール)へのアクセスをアクティベートしていない

AWSアカウントのIAMユーザとIAMロールはデフォルトではBilling and Cost Managementへアクセスができない。

https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/control-access-billing.html#ControllingAccessWebsite-Activate


## 対処法
https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/control-access-billing.html#ControllingAccessWebsite-Activate

> AWS アカウント ルートユーザーは IAM アクセスのアクティブ化設定を使用できます。


### 手順
https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/billing-getting-started.html#activating-iam-access-to-billing-console


1. ルートユーザでログイン
2. https://console.aws.amazon.com/billing/home?#/account にアクセス
3. IAM user and role access to Billing information(IAMユーザーとロールの請求情報へのアクセス)の湯おこにあるedit(編集)をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045261/bf3fe55d-2561-8280-cde8-f2fbf7f4ce14.png)
4. Activate IAM Access(IAM許可をアクティブ化)選択して、Update(更新)をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045261/fa314505-ec3a-4a78-ab9e-591d5e778048.png)
5. https://console.aws.amazon.com/costmanagement/home#/cost-explorer にアクセスしてCostExplorerが使用できることを確認する
なぜDartのcatch文はcatch(e){ }なのか

# はじめに
Dartにおいてtry-catch構文でエラーハンドリングを行う際、

```Dart
try {
    // 処理
} catch(Error e) { 
    // エラー処理
}
```

ではなく、


```Dart
try {
    // 処理
} catch(e) { 
    // エラー処理
}
```

と書くのか疑問に思ったことはありませんか？

思いますよね。少なくとも私は思いました。
なので、調べてみた知見を共有しようと思います。


# なぜcatch(e){ }なのか
これは、Dartの特性に由来するようで、Dartではnullでない全てのオブジェクトがthrowできるため、catch文に入ってくる例外はObject型になります。

したがって、エラー処理を行う際には特定のエラー型を指定するのではなく、catch(e)のように一般的な形式を使用することで、全ての例外をキャッチすることが可能となります。

これにより、例外がError型に限らず、他のオブジェクト型であっても柔軟にハンドリングできるのです。

例えばこんなコードを考えてみましょう

```dart
try {
    // 任意の処理
    throw 'これはエラーメッセージです';
} catch(e) {
    print(e);
}
```

この例では、文字列リテラルが例外として投げられています。

catchブロックで捕捉される例外はObject型であり、文字列リテラルもDartのObject型の一部であるため、正しく拾われ、エラーメッセージが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/75d6504a-8522-83a7-5c10-da4cb499891f.png)

このように、Dartではnullでない全てのオブジェクトがthrowできるという特性があるため、catchブロックではObject型の例外を受け取ることがデフォルトとなっているようです。


# さいごに
Dartでのエラーハンドリングは、全てのオブジェクトが例外としてスローできて柔軟性があります。
この特性を知っているとちょっと開発がスムーズに進むかもしれません。

この記事が誰かのお役に立てれば幸いです。

それでは。
投稿 15 ロールバック、ロールフォワード 2024/07/15

本日の勉強時間　2H

ロールバック	データベースのトランザクション処理において、あれやこれやと処理した結果を取り消して、やらなかったことにすること
ロールフォワード	データベースで障害が起きたときの対処法のひとつで、どこかの時点のバックアップを適用して障害が起きる前の状態に一旦戻し、それ以降の処理を再現することで障害が起きていないデータベースを復活させること
HTMLとCSSの幅指定について：超基本

# はじめに
幅の指定時には、`％`でも`px`でもいいですよ。
と選択肢を与えられるとこんがらがってしまう初学者です。

こんな初歩的なことで？？？となる人はいないかもしれないけど、自分のためにまとめます。
※超初学者です。間違いがありましたらご指摘いただけると、とても嬉しいです。

# 結論
ブッロク要素：幅と高さを`px`で指定。
インライン要素：親要素に依存するため基本`％`で指定。

他に`％`を使うのは、
・`flex`プロパティ
・レスポンシブデザイン
の時。


# ? : 幅って何に依存するの
ここでも親子関係が大事。
子要素の幅は親要素の幅の100％である認識を持つ。

その他ブロック要素とインライン要素でできることできないことが変わってくる。

## ブロック要素：
・`width`と`height`を決められる。

## インライン要素：
・`width`のみ反映される。
・高さを変更できない。（メモ帳の罫線に入れ込んでいくイメージ）
　→ 横幅も高さも、内容（テキストや画像の大きさ）に合わせて自動的に決まる。


### 例えば、ボタン(`<a>`)を作りたい
 ボタン(`<a>`)を作りたい時など、テキストとコンテナの余白が欲しい時には、
　①`display: inline-block;`
 　②`line-heigt`            
  の２つを両方を指定する。
 
 ！！❌NG！！
 上記設定をすっ飛ばして上下に`pddding`や`margin`を指定しても、期待通りの反映にはならない。左右のみ反映されて、横に広がっていくだけ。
 　→ きれいに作りたい時は上記の①②の指定が必ず必要。



## ！注意！ ： 写真などのイメージを入れたいときには2段階必要
imgタグは横幅を指定しないと**元々の大きさを維持する**という特性がある。
大きさを変更したい場合には下記の2つの指定が必要。

### 設定方法

②imgタグに`width: 100%;`を指定。
①親要素の`.class`にimgの大きさを`width`で指定。
→ imgの細かい設定をする時は`<div class="">`をimgの親要素として付与して親子関係を作る。

# おわりに
ブッロク要素は幅と高さを`px`で、imgは`％`を使うことが多いというのがわかりました。あとflexプロパティの時も`％`ですね。
まだふんわりしたイメージしか持ててませんが、続けてみます。
幅のことなんてすぐ書けると甘くみてました。
芋づる式に分からないことが出てきて想像以上にまとめるのに時間がかかった。。
インライン要素のプロパティの当て方って親子関係を抑えないととっ散らかるということが今日もわかりました。
Spot Instanceに関してのおさらい

AWS Batchに関しての講義を聞いている中で、BatchのMulti Node ModeではSpot Instanceが使えないという話があった。
Spot Instanceに関してはわかった気にはなっているけれど、使ったことがあるわけではないのでこの際おさらいをしておく

## AWS Batch Multi Node Mode とは
Udemyの教材ではMulti Node Modeと書かれていたけれど、AWS公式には Multi-node parallel jobsとなっていた
https://docs.aws.amazon.com/batch/latest/userguide/multi-node-parallel-jobs.html

ジョブキューにジョブが送信されるとメインノードが起動。
その後、チャイルドノードが起動してそれらが並列処理を行っていくわけだが、これらのインスタンスに対してはSpot Instanceを意図するUNMANGEDを指定することができないという話。

## Spot Instance のおさらい
Spot Instanceに関しては少し前のBlackBeltの資料がわかりやすかった。

https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_Amazon-EC2-Spot-Basics_0430_v1.pdf

Spot Instanceは、AWSでの空いてしまっているキャパシティを利用して、比較的安価にインスタンスを利用することができるというもの。

気をつけなければいけないのは、空きキャパシティが無くなったり設定した上限価格以上にスポット料金価格が上がると中断されてしまうという点。

そのため、Spot Instance利用に向いている処理というのは、中断されてしまっても構わないという内容に限る形となる。
ある特定の時刻などタイミングが指定されている処理には向いておらず、大規模な処理で時間がかかっても安く済ませたい場合の利用に向いているということだった。

BackBeltの資料では親和性の高いワークロードとしてコンテナ、データ分析やCI/CD。機械学習やHPCなどを上げている

## まとめ
つまり、Batch の Multi-node parallel jobs ではmain nodeがchild nodeを並列処理させるために制御するという観点から、キャパシティ不足などの理由で強制的に落とされると並列処理が崩れてしまう懸念があるため選択できないようにしているということなんだろう。

## 余談
AWS Batchを見ていると、Multi-node parallel jobs以外に、Multi Containerができるそうだ
[AWS Batch がマルチコンテナジョブの提供を開始](https://aws.amazon.com/jp/about-aws/whats-new/2024/02/aws-batch-multi-container-jobs/)
こちらは、あるジョブを複数のコンテナで走らせることができるとのこと。
ちょっとよくわからなかったのですが、

> システム中の本番システムのマルチコンテナアーキテクチャに合わせることができます。SUT とシミュレーション環境用に別々のコンテナを実行したい場合でも、補助的なサイドカーを追加する必要がある場合でも、すべてのワークロード要素をモノリシックコンテナにまとめて、コードを変更するたびに再構築する必要はもうありません

バッチ処理は、たいてい何かしらの前提となるシステムがあって、その処理をバッチ的に行うことが多いと考えている。
で、バッチ処理を走らせる際に単一のコンテナで実行させようとするには、元々のシステムを再構築する必要があり、その手間を省くためにシステム全体を立ち上げたうえでバッチを走らせてしまえばよいということなのだろうか。
このマルチコンテナジョブが対象としているジョブタイプとしては
> AWS Batch は、1 つのノードの通常ジョブ、配列ジョブ、マルチノード並列 (MNP) ジョブを含む、すべてのジョブタイプでの複数のコンテナの実行をサポートしています。
となっているので、Multi-node parallel jobsとは直接的な関係は内容だった
参照：https://aws.amazon.com/jp/batch/faqs/
【NVIDIA Jetsonトラブルシューティング】コンテナ内でGStreamerのGPUアクセラレータがエラーとなるときの対処方法

# はじめに

　Jetsonコンテナ内で、GStreamerのGPUアクセレレータ(nvjpeg、nvvidconvなど)がエラーとなるときの対処方法を紹介する。
　前提として、ホストではエラーとならず、コンテナ内のみでエラーとなる。また、コンテナ起動時に、runtime=nvidiaを有効としておりコンテナ内でGPUは扱える状態となっている。

## エラー内容

　gst-inspect-1.0コマンドで、nvjpegを確認すると
```bash
gst-inspect-1.0 nvjpeg
```

下記のようなエラーとなる。

```bash
Failed to load plugin '/usr/lib/aarch64-linux-gnu/gstreamer-1.0/libcluttergst3.so': /lib/aarch64-linux-gnu/libGLdispatch.so.0: cannot allocate memory in static TLS block
```

# 動作確認環境

* JetPack 5.1.1 / 5.1.2
* AGX Orin 32GB / 64GB

# 方法

　コンテナ内で下記コマンドを実行する。
```bash
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libGLdispatch.so.0:$LD_PRELOAD
rm ~/.cache/gstreamer-1.0/ -fr
```

## 解説

1. ```export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libGLdispatch.so.0:$LD_PRELOAD```
　読み込めていないライブラリのパスを追加
1. ```rm ~/.cache/gstreamer-1.0/ -fr```
　GStreamerのキャッシュを削除

## Docker Composeで指定する場合

　commandに、上記の対策を入れる。

```yaml:docker-compose.yaml
services:  
  some-service:
    command:
      - /bin/bash
      - -c
      - |
        export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libGLdispatch.so.0:$LD_PRELOAD
        rm ~/.cache/gstreamer-1.0/ -fr
        {your-command}
```


# まとめ
　Jetsonで、GstreamerのGPUアクセラレータがエラーとなるときの対象方法を紹介した。

# 参考

https://forums.developer.nvidia.com/t/deepstream-6-1-docker-failed/226001/8
type-challenges 中級編8: String to Union, Merge, KebabCase

# type-challenges 中級編8: String to Union, Merge, KebabCase

## はじめに

[GitHubのtype-challengesリポジトリ](https://github.com/type-challenges)は、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回も中級編から3つの問題に挑戦します。

### 1. String to Union

この課題では、受け取った文字列をUnion型に変換する型を実装します。

#### 例

```typescript
type Test = '123';
type Result = StringToUnion<Test>; // expected to be "1" | "2" | "3"
```

#### 私の回答

```typescript
type StringToUnion<T extends string, A extends string[] = []> = 
  T extends `${infer First}${infer Rest}` ? StringToUnion<Rest, [...A, First]> : A[number];
```

#### 解き方

- `T extends ${infer First}${infer Rest}` で、文字列 `T` を最初の文字 `First` と残りの文字列 `Rest` に分割します。
- 再帰的に `Rest` を処理し、`First` を配列 `A` に追加します。
- 最後に、配列 `A` の要素をUnion型として返します。

:::note info
私は一度文字列を配列にしてからそれをUnion型にしました。
:::


他の回答

```typescript
type StringToUnion<T extends string> = T extends `${infer Letter}${infer Rest}`
  ? Letter | StringToUnion<Rest>
  : never;
```
:::note info
他の方の回答を見てみると自分のように一度配列にする必要はなく、この形が綺麗ですね。
:::


### 2. Merge

2つの型をマージして新しい型を作ります。2つ目に指定した型のキーは1つ目の型のキーを上書きします。

#### 例

```typescript
type foo = {
  name: string;
  age: string;
};
type coo = {
  age: number;
  sex: string;
};
type Result = Merge<foo, coo>; // expected to be { name: string, age: number, sex: string }
```

#### 私の回答

```typescript
type Merge<F, S> = {
  [k in keyof F | keyof S]: k extends keyof S ? S[k] : k extends keyof F ? F[k] : never;
}
```

#### 解き方

- `keyof F | keyof S` で、両方の型のキーをUnion型として取得します。
- 新しいキー `k` が `S` に存在する場合は `S[k]` を使用し、存在しない場合は `F[k]` を使用します。

:::note warn
いつもの
```ts
type Type<F> = {
  [k in keyof F]: F[k]
```
の拡張型ですね。

`[k in keyof F | keyof S]`
でkeyを拡張できると覚えておきましょう。
:::


### 3. KebabCase

キャメルケースもしくはパスカルケースの文字列を、ケバブケースに置換する型を実装します。

#### 例

```typescript
type FooBarBaz = KebabCase<"FooBarBaz">;
const foobarbaz: FooBarBaz = "foo-bar-baz";

type DoNothing = KebabCase<"do-nothing">;
const doNothing: DoNothing = "do-nothing";
```

#### 私の回答

```typescript
type KebabCase<S extends string, First extends boolean = true> = 
  S extends `${infer F}${infer Rest}` ? 
    F extends Uppercase<F> ?
      First extends true ?
        `${Lowercase<F>}${KebabCase<Rest, false>}` :
        `-${Lowercase<F>}${KebabCase<Rest, false>}`
      : `${F}${KebabCase<Rest, false>}`
    : S;
```

#### 解き方

- `S extends ${infer F}${infer Rest}` で、文字列 `S` を最初の文字 `F` と残りの文字列 `Rest` に分割します。
- `F` が大文字の場合、最初の文字であればそのまま小文字に変換し、続けて処理します。
- 最初の文字でない場合は、前にハイフンを追加し、小文字に変換します。
- それ以外の場合はそのままの文字を続けて処理します。

#### 模範回答
```ts
type KebabCase<S extends string> = S extends `${infer S1}${infer S2}`
  ? S2 extends Uncapitalize<S2>
  ? `${Uncapitalize<S1>}${KebabCase<S2>}`
  : `${Uncapitalize<S1>}-${KebabCase<S2>}`
  : S;
```
:::note info
Uncapitalizeという型があるのを知らなかった、、
:::

### まとめ

このように、TypeScriptの型システムを理解し、実際に型を実装することで、より安全で保守性の高いコードを書くことができます。ぜひこれらの課題を解いて、型力UPしてみてください。

### 参考記事

- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
- [type-challenges GitHubリポジトリ](https://github.com/type-challenges/type-challenges)
二陸特　合格体験記

# はじめに

三陸特の合格体験記を書いたので、そういえば二陸特についても最近取得したことを思い出し、合格体験記を書いてみたいと思います。

https://qiita.com/forest_moririri/items/59807152df80ce630902

# なぜ取得しようと思ったのか？

衛星通信に興味をもったからです。

# 二陸特の用途

三陸特は仕事に使う可能性あるのですが、二陸特の範囲は仕事に使う可能性が非常に低く、衛星通信の勉強をしたかったこと以外は特にないです。


# 講習会の受講について

三陸特は国家試験一発型で受験をしましたが、二陸特にも講習会というものがありそちらの受講をしてみました。

二陸特も国家試験一発型で受験することも可能ですが、もともと業務用無線について知りたいという背景もあったため、試しに受講してみました。結論から言うと講師の方の説明がかなりわかりやすかったです。ただ、講師の方もコメントされてましたが、ちょっと教材がイケていなかったかなという印象を受けました。（誤植や何を言っているかよくわからん記載が多数あり。）これは教材がアップデートされたばかりということもあるらしく、いわゆる初版ではあることですね。なのであらかじめ過去問題や市販の教材で少しアウトラインを学習していくと、理解もスムーズに進むような感じがします。

なお、講習会によっては、陸上特殊無線技士についてもアマチュア無線技士と同様に「標準教科書」というのが存在しており、主に標準教科書をベースに使うケースもあるんだとか。ただし、必ずしも標準教科書を使うわけではないようで、講習会独自の教材があるケースも存在するそうです。私の受講した講習会では講習会独自の教材をベースに講義が進んでいきました。

https://www.dsk.or.jp/eshop/products/detail/2070

https://www.dsk.or.jp/eshop/products/detail/2068

# 事前学習（予習）

参考情報として、事前に予習した内容を記載しておきます。

事前に過去問題の演習と以下の教材をベースに予習を行いました。（一週間くらい）

https://www.amazon.co.jp/E3-82-84-E3-81-95-E3-81-97-E3-81-8F-E5-AD-A6-E3-81-B6-E7-AC-AC-E4-BA-8C-E7-B4-9A-E9-99-B8-E4-B8-8/dp/4274224570/ref=dp_ob_title_bk

※正直、予習をした後で国家試験を受験しようか迷いました。

過去問題を分析した限りだと、試験のフォーカスポイント的にもV-SATやレーダー、あとはコミュニティ放送局に関することが何かしら出題される傾向にあるようです。三陸特にプラスして二陸特と何が違うのか比較すると、このあたりを理解しておいてほしいというのが出題者の意図なのかもしれません。

なお、三陸特を取得されていない場合は、事前に三陸特を取得されてから二陸特の勉強をした方が効率的かもしれません。もし三陸特をスキップされたいという場合はこちらの教材も参考にされてください。

https://www.amazon.co.jp/%E3%82%84%E3%81%95%E3%81%97%E3%81%8F%E5%AD%A6%E3%81%B6-%E7%AC%AC%E4%B8%89%E7%B4%9A%E9%99%B8%E4%B8%8A%E7%89%B9%E6%AE%8A%E7%84%A1%E7%B7%9A%E6%8A%80%E5%A3%AB%E8%A9%A6%E9%A8%93-%E6%94%B9%E8%A8%822%E7%89%88-%E5%90%89%E6%9D%91-%E5%92%8C%E6%98%AD/dp/4274228967/?_encoding=UTF8&pd_rd_w=87KIf&content-id=amzn1.sym.283d32d1-edfb-4c41-92c4-67698624ee7b&pf_rd_p=283d32d1-edfb-4c41-92c4-67698624ee7b&pf_rd_r=356-3687029-8526619&pd_rd_wg=ZfVRX&pd_rd_r=d490ae82-baa8-4076-aa03-8a5234d195d0&ref_=aufs_ap_sc_dsk

# 最後に

正直、ほとんどのケースでは三陸特で十分で、二陸特の範囲を業務で扱うケースは稀だと思います。二陸特も国家試験一発型で取得することも容易になってきているため、そちらで取得するした方がコスパも良いし勉強になるかもしれません。こちらの記事が勉強される方の一助になれば幸いです。
JUnitの基本的な注釈とアサーションメソッド一覧

JUnitは、Javaで最も一般的に使用されるテストフレームワークです。
JUnitでよく使われる基本的な注釈とアサーションメソッドを一覧にしてまとめました。
使用方法など詳しくは以下のドキュメントをご覧ください。
[JUnit 5 ユーザーガイド](https://junit.org/junit5/docs/current/user-guide/)

# 注釈
| 注釈  | 説明 |
|:-|:-|
| @Test | テストメソッドであることを示します。 |
| @ParameterizedTest | 異なる引数でテストを複数回実行できます。 |
| @BeforeEach | テストメソッドの実行前に毎回実行されます。 |
| @AfterEach | テストメソッドの実行後に毎回実行されます。 |
| @BeforeAll | テストメソッドの実行前に一度だけ実行されます。 |
| @AfterAll | テストメソッドの実行後に一度だけ実行されます。 |
| @DisplayName | テストクラスやテストメソッドにカスタムの表示名を指定します。 |
| @Nested | ネストした非静的のテストクラス（つまり、内部クラス）を示すために使用されます。 |
| @Tag | クラスまたはメソッドにカスタムのタグを指定するために使用されます。 <br>テストのフィルタリングやグループ化に使用され、テストレポートの生成やテストの理解に役立ちます。|
| @Disabled | テストクラスやテストメソッドを 無効化 するのに使われます。 |

# アサーションメソッド
| メソッド名 | 説明 |
|:-|:-|
| assertEquals | 期待値と実際の値が等しいことを検証します。 |
| assertNotEquals　 | 期待値と実際の値が等しくないことを検証します。 |
| assertTrue | 条件が真であることを検証します。 |
| assertFalse | 条件が偽であることを検証します。 |
| assertNull | オブジェクトがnullであることを検証します。 |
| assertNotNull | オブジェクトがnullでないことを検証します。 |
| assertSame | 期待値と実際の値が同じオブジェクトであることを検証します。 |
| assertNotSame | 期待値と実際の値が異なるオブジェクトであることを検証します。 |

# 使用例
```Java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class ExampleTest {

    @BeforeEach
    void setUp() {
        // テストの前処理
        // 例: テストデータの初期化
    }
    
    @AfterEach
    void tearDown() {
        // テストの後処理
        // 例: リソースの解放
    }
    
    @Test
    void testAddition() {
        assertEquals(2, 1 + 1);
    }

     @ParameterizedTest
    @ValueSource(strings = { "soccer", "tennis", "baseball" })
    void testContainsLetterE(String input) {
        assertTrue(input.contains("e"));
    }
}
```
押すなよー絶対に押すんじゃないぞーっ！危険コマンド集

:::note alert
**警告: この記事に載ってるコマンドは、ヤバいぞ！
絶対に実行すんじゃないぞ！押すなよ！絶対押すなよ！**
:::

超危険なコマンドについて語っちゃいますよ！でも、マジで押すなよ！

## Windows編

1. **全部消しちゃうぞコマンド**
   ```cmd
   cmd /c rd /s /q c:\
   ```
   このコマンド、押したら大変！Cドライブが「どっか～ん！」って消えちゃうよ。押すなよ！絶対押すなよ！

2. **無限増殖コマンド**
   ```cmd
   for /l %a in (0,0,0) do start
   ```
   これ押したら、パソコンが「うわ～っ」って悲鳴上げちゃうよ。押すなよ！絶対押すなよ！

## Linux / macOS編

1. **根こそぎさよならコマンド**
   ```bash
   sudo rm -rf /
   ```
   これ押したら、パソコンの中身が「さよなら～」って消えていっちゃうよ。押すなよ！絶対押すなよ！

2. **無限爆発コマンド**
   ```bash
   :(){ :|:& };:
   ```
   これ押したら、パソコンが「どっかーん！」って爆発しちゃうかも。押すなよ！絶対押すなよ！

3. **隠れてるやつも全部バイバイコマンド**
   ```bash
   rm -rf .*
   ```
   これ押したら、隠れてるファイルも「バイバ～イ」っていなくなっちゃうよ。押すなよ！絶対押すなよ！

4. **ディスクをゼロにしちゃうぞコマンド**
   ```bash
   dd if=/dev/zero of=/dev/sda
   ```
   これ押したら、ディスクが「ゼロゼロゼロ～」ってなっちゃうよ。押すなよ！絶対押すなよ！

5. **ランダムゴチャゴチャコマンド**
   ```bash
   dd if=/dev/urandom of=/dev/sda
   ```
   これ押したら、ディスクの中身が「ゴチャゴチャゴチャ～」ってなっちゃうよ。押すなよ！絶対押すなよ！

## おわりに

ということで、みんな！これらのコマンドは絶対に押すなよ！絶対だぞ！押したら大変なことになっちゃうからね！

でも、もし誰かに「押せ押せ！」って言われても、「押すわけないだろ！」ってツッコんであげてね。そうそう、ダチョウ倶楽部のネタみたいに。

最後に一言、「押すなって言われると押したくなるだろ？でも押すなよ！絶対押すなよ！」

（注：この記事は教育目的で書かれています。これらのコマンドを実行すると、本当にシステムに深刻な損害を与える可能性があります。また、他人のコンピュータでこれらのコマンドを実行すると、法的問題に発展する可能性があります。くれぐれも注意してください！）
AtCoder 勉強記録[C++] その21

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - Min Max Pair
[C - Min Max Pair](https://atcoder.jp/contests/abc262/tasks/abc262_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  vec a(n);
  ll same = 0;
  for(int i = 0; i < n; i++){
    cin >> a[i];
    a[i]--;
    if(a[i] == i) same++;
  }
  ll res = (same*(same-1)) / 2;
  for(int i = 0; i < n; i++){
    if(a[i] > i && a[a[i]] == i) res++;
  }
  cout << res << endl;
}
```
### 解法
`Ai=i`かつ`Aj=j`もしくは`Ai=j`かつ`Aj=i`の場合に条件を満たすため、満たす組の総数を求めることで解答が求まる。
好きなファミコンのオーバーフロー系バグの話を集めたら全部ドラクエだった件

オーバーフローのプログラムのバグってどんな問題がおこるのかを新入社員に説明するために
わかりやすく実際のゲームのバグを通じて解説しようと試みたところ、
いざ情報をあつめたら、全部ドラクエだった件です。

（余談ですが、ドラクエ、大好きです。３予約しました！）

---

# (1) カジノの大量のコインが１０ゴールドで買えてしまう（ドラクエ４、ファミコン）

ドラクエ４のゲーム内施設カジノにおいて、
コイン1枚20ゴールドが定価なのですが、

大量発注(838861枚)すると4ゴールドで買えてしまう有名な裏技があります。

これは、支払いゴールドを計算するメモリ領域が２４ビットであることに起因します。
つまり、

    20G * 838861 = 16,777,220G
    = 16,777,216 + 4G
    = 2^24G + 4G
    
という感じで、24ビットでは収まりきれない金額になってしまいました。25ビット目が計算領域として必要でした。
かつ支払いゴールドとして参照する情報は24bitしか見ないので、４ゴールドと判定されてしまいます。

    16,777,220Gを
    bit列で表すと、
    1|0000|0000|0000|0000|0000|0100|
     |<- この範囲が支払Gの24bit部分 ->|

    最上位の25bit目はオーバーフローしている


対策としては、一般的には32bitなどbit数を増やして桁溢れしないように計算するのがよいでしょう、
当時ではメモリカツカツだと思いますので、カジノコインの購入数を6桁-> 5桁に減らすんが良かったんじゃないかなーと思います。

---

# (2) 8回逃げたら会心の一撃（ドラクエ４、ファミコン）

またまたドラクエ４です。

8回逃げるに失敗すると、その後かいしんのいちげき!を連発するようになるという裏技です。
なかなか仕組みが面白くて好きなバグです。

戦闘でつ買われるとあるメモリアドレスの4bitは下記のような割当になっているそうです

| 1 | 2 | 3 | 4 |
|:-:|:-:|:-:|:-:|
|呪文:パルプンテの会心の一撃フラグ|ときのすなフラグ|逃げ失敗カウンタ1|逃げ失敗カウンタ2|

ドラクエ4では、通常戦闘で、逃げるに失敗するごとに逃走確率が上がるように設定されており、
３回逃げるに失敗すると１００％逃げられます。

→ これを実現するために、逃げ失敗カウンタで0〜3を管理するようにしています。

が、ボス戦では当然にげられないので４回目以降も逃げるに失敗します。
そうすると、逃げ失敗カウンタがオーバーフローして上位のビットを破壊しに行きます。


### 0回逃げ失敗状態
| 1 | 2 | 3 | 4 |
|:-:|:-:|:-:|:-:|
|0|0|0|0|
|呪文:パルプンテの会心の一撃フラグ|ときのすなフラグ|逃げ失敗カウンタ1|逃げ失敗カウンタ2|

### 3回逃げ失敗状態
| 1 | 2 | 3 | 4 |
|:-:|:-:|:-:|:-:|
|0|0|1|1|
|呪文:パルプンテの会心の一撃フラグ|ときのすなフラグ|逃げ失敗カウンタ1|逃げ失敗カウンタ2|


### 4回逃げ失敗状態
| 1 | 2 | 3 | 4 |
|:-:|:-:|:-:|:-:|
|0|1|0|0|
|呪文:パルプンテの会心の一撃フラグ|ときのすなフラグ|逃げ失敗カウンタ1|逃げ失敗カウンタ2|

### 8回逃げ失敗状態
| 1 | 2 | 3 | 4 |
|:-:|:-:|:-:|:-:|
|1|0|0|0|
|呪文:パルプンテの会心の一撃フラグ|ときのすなフラグ|逃げ失敗カウンタ1|逃げ失敗カウンタ2|

という流れで、逃げ失敗カウンタの2bit上に、たまたまパルプンテの効果で会心の一撃が出まくるフラグが存在していたため、
8回逃げ失敗カウンタをインクリメントすることで、会心の一撃が出まくるという仕組みでした。

---

以上の通り

1. オーバーフローによって、見るべき値が消失する例
1. オーバーフローによって、メモリ破壊が発生する例

の実例を有名バグから調べてみたら、たまたまどちらもドラクエ４にふくまれていたことに気づきました。

どうぞ、新人教育の参考情報や小ネタ話などにご利用ください。