LoginSignup
63
25

More than 3 years have passed since last update.

C# で湯婆婆を実装してみる(𠮷田さんにも対応)

Posted at

ネタ記事が流行ってる!なので C# 9 で書いてみようと思います。
C# 8 ベースのものは別の方が書いてくれています。

C#で湯婆婆を実装してみる

トップレベルステートメントくらいしか使えるものがない

湯婆婆はシンプルなのでトップレベルステートメントくらいしか使えるものがありません…!なのでこうなります。

using System;

Console.WriteLine("契約書だよ。そこに名前を書きな。");
var name = Console.ReadLine();
Console.WriteLine($"フン。{name}というのかい。贅沢な名だねぇ。");

var random = new Random();
var newNameIndex = random.Next(name.Length);
var newName = name[newNameIndex];
Console.WriteLine($"今からお前の名前は{newName}だ。いいかい、{newName}だよ。分かったら返事をするんだ、{newName}!!");

𠮷田さん対応

空文字で落ちるのは仕様なので置いといて𠮷田さんが働けないのは問題です。Windows のコマンドプロンプトや PowerShell 上で𠮷田さんを表示できないので GitHub Codespace で適当な Linux マシンでやってみます。

そうすると申込用紙は𠮷田さんに対応してくれたみたいですが肝心の湯婆婆が𠮷田さんだとバグってしまいます。

image.png

これですが、俗にいう4バイト文字に対応していないことにより起こります。サロゲートペアとか4バイト文字あたりでぐぐると情報が出てきます。

C# では System.Globalization.StringInfo クラスを使って対応します。今回のように 1 文字だけ取り出せればいいというケースでは StringInfo クラスのインスタンスを作って LengthInTextElements でサロゲートペアもきちんと見てくれている状態での文字数カウントをして SubstringByTextElements でサロゲートペアとかもきちんと考慮した状態で 1 文字切り取ってやればいいでしょう。

ということで、𠮷田さんに対応した湯婆婆は以下のようになります。

using System;
using System.Globalization;

Console.WriteLine("契約書だよ。そこに名前を書きな。");
var name = Console.ReadLine();
Console.WriteLine($"フン。{name}というのかい。贅沢な名だねぇ。");

var nameInfo = new StringInfo(name);
var random = new Random();
var newNameIndex = random.Next(nameInfo.LengthInTextElements);
var newName = nameInfo.SubstringByTextElements(newNameIndex, 1);
Console.WriteLine($"今からお前の名前は{newName}だ。いいかい、{newName}だよ。分かったら返事をするんだ、{newName}!!");

では実行してみましょう。

image.png

ばっちりですね。これで𠮷田さんも働けます。もちろん空文字の場合は仕様通り例外が発生します。

image.png

まとめ

もう 1 記事くらい湯婆婆で書けそうな気がする。

63
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
63
25