ChatGPT は CJK Compatibility 文字が苦手？

「Unicodeの正規化形式について」尋ねてみたら、回答の中に

> 例えば、"㌀"（U+3380）は、"アキュメ"という文字列に対応するが、NFKCでは"アキュメ"という文字列と同等のコードポイントである"アキュメ"（U+30A2, U+30AD, U+30E5, U+30E1）に変換されます。

があった。("㌀" は U+3300 で、U+3380 は「㎀」)

そこで、「㌀ ㌁ ㌂ ㌃ ㌄..」みたいな文字について尋ねてみることにした。

---

『「㍌」について』

> 「㍌」は、日本語で「平成」という意味を表す特殊な記号です。この記号は、1990年代に日本で広く使用されていた元号「平成」を表すために作られました。
> 〜〜後略〜〜

問う度に回答が変化しますが、多くの回答で出てくるキーワードが「平成」です。

---

『「㍌」のUnicode名称は？』

> 「㍌」のUnicode名称は「SQUARE ERA NAME HEISEI」となっています。UnicodeコードポイントはU+337Cで、日本の特定用途文字として定義されています。

正しくは「SQUARE MEGATON」ですが、どうも ChatGPT の中では「㍌」に限らす「SQUARE ERA NAME HEISEI」と判断することが少なくないようです（ちょくちょく出てきます）。

U+337Cは「㍼」で、U+337B が「㍻」で「SQUARE ERA NAME HEISEI」です。

---
(追記：2023/3/23)

『文字 "㍌" を NFKC 形式を JavaScript で表示するには？』

> 文字 "㍌" をNFKC形式で表示するには、以下のようにコードを記述することができます。

```JavaScript:回答
const str = "\u334C";
console.log(str.normalize("NFKC")); // "平成"
```

> 上記のコードでは、まず文字列リテラル"\u334C"を使用して文字 "㍌" を表し、normalizeメソッドを使用してNFKC形式に変換しています。結果は "平成" となります。

『そのプログラムでは「平成」ではなく「メガトン」と出力される』（が何度も修正の度に発生）

> おそらく、コードポイント U+337B に対して normalize("NFKC") メソッドを適用すると、「メガトン」という文字列に変換されるため、そのような結果になったのだと思われます。つまり、正しくは「平成」と表示されるべき文字列が、不正な文字列になっている可能性があります。
>
> 例えば、以下のようなプログラムを使うことで、文字列が正しく変換されているかどうかを確認することができます。

```JavaScript:回答
const str = "㍌";
const codePoint = "U+337B";
if (str.codePointAt(0).toString(16).toUpperCase() === codePoint.split("+")[1]) {
  const normalized = str.normalize("NFKC");
  if (normalized === "平成") {
    console.log("正しい出力: " + normalized);
  } else {
    console.log("不正な出力: " + normalized);
  }
} else {
  console.log("不一致");
}
```

> このプログラムでは、まず文字列がコードポイント U+337B に対応しているかを確認し、対応している場合は normalize("NFKC") メソッドを適用して正規化し、「平成」と一致するかどうかを確認しています。

"㍌" は U+334C なので、当然「不一致」です。


---

『「㍻」について』

> 「㍻」とは、円周率（π）の値を表す記号です。この記号は、日本の度量衡法において正式に使用されています。
> 
> 「㍻」は、「円周率」の最初の漢字「円」を表す「㍱」に、「周」を表す「回」を重ね合わせた形で、「回」の下に横棒を引いた形で表されます。
>
> 〜〜後略〜〜

---

『「㍻」の Unicode 名称は？』

> 「㍻」のUnicode名称は「CIRCLED KATAKANA PI」（サークル付き片仮名「パイ」）となっています。Unicodeの正式名称は、U+32FBという符号で、これは日本で採用された特殊な文字の一つです。ただし、Unicodeでは「㍻」の代わりに「π」という記号を使用することが推奨されています。

U+32FB は「㋻」(CIRCLED KATAKANA WA)。「CIRCLED KATAKANA PI」の最後はローマ字よみだろうから「ピ」だろうけど、Unicode 14.0 には見つけられなかった。ChatGPTにより作り出された名称でしょう。（他の文字でも存在しない名称の回答を見かけている…）

---

『「㍻」をNFKC形式にすると？』

> 「㍻」は、「株式会社」を意味する記号であり、NFKC形式に変換すると「株式会社」となります。

『"㍻" を JavaScript でNFKC変換して出力させるには?』

> JavaScriptでは、Stringオブジェクトのnormalize()メソッドを使用して、文字列をNFKC形式に変換できます。以下は、"㍻"をNFKC変換して出力する例です。

```JavaScript:
let str = "㍻";
let normalizedStr = str.normalize("NFKC");
console.log(normalizedStr); // 出力結果: 株式会社
```

> 〜〜後略〜〜

プログラムに問題はないのですが、結果の部分は"㍿"の情報を引っ張り出していることが分かります。

システム的に当然かもしれませんが、回答前に実行確認はしないのです。

---
(追記：2023/3/23)

『Unicode コードポイント U+3300 から U+3357 の範囲で、元号を示す文字は？』

> Unicode コードポイント U+3300 から U+3357 の範囲には、日本の元号を示す文字が含まれています。具体的には、以下のような元号が含まれます。
>
> U+337B ㍻ : 昭和
> U+337C ㍼ : 大正
> U+337D ㍽ : 明治
> U+337E ㍾ : 平成
> U+337F ㍿ : 令和
> これらの文字は、Unicode の "CJKの記号及び句読点の補助" ブロックに収録されています。

コードポイントに対する情報が一つずれてることが分かります。

---
（追加：2023/3/22）

『"㌀" を Python で Unicode NFKC 形式で出力したい』

> 以下のコードを使用して、PythonでUnicode NFKC形式の"㌀"を出力できます。

```python:回答
s = "\u3380"
nkfc_s = s.encode('utf-8').decode('unicode-escape').encode('ascii', 'ignore').decode('unicode-escape')
print(nkfc_s)
```

> 出力結果は、"㌀"のUnicode NFKC形式の文字である"\u30a2\u30fc\u30c8"となります。

『回答のプログラムによる出力結果は "\u30a2\u30fc\u30c8" ではなく空文字列 "" でした。』

> 申し訳ありません。間違った情報を提供してしまいました。
> 
> 以下のように、unicodedata.normalize()関数を使用して、Unicode NFKC形式に変換することができます

```python:回答
import unicodedata

s = "\u3380"
nkfc_s = unicodedata.normalize('NFKC', s)
print(nkfc_s)
```

> 出力結果は、"㌀"のUnicode NFKC形式の文字である"\u30a2\u30fc\u30c8"になります。

『回答のプログラムによる出力結果は "\u30a2\u30fc\u30c8" ではなく "pA" でした』

> 申し訳ありません、またもや誤った情報を提供してしまいました。
>
> 以下のコードを使用して、PythonでUnicode NFKC形式の"㌀"を出力できます。

```python:回答
s = "\u3380"
nkfc_s = s.encode('utf-8').decode('utf-8')
nkfc_s = unicodedata.normalize('NFKC', nkfc_s)
print(nkfc_s)
```

> 出力結果は、"㌀"のUnicode NFKC形式の文字である"\u30a2\u30fc\u30c8"になります。


"\u30a2\u30fc\u30c8" は "アート" ですが、最初のプログラムの出力結果は空文字列です。
修正されたプログラムでは "\u3380" は "㎀" なので、出力結果は「pA」になります。

ChatGPT の中では "㌀"(U+3300) は U+3380 であり、NFKC 変換すると "アート" になると判断しているので、自ら正解に辿り着くことはありません。デバッグできずに嵌まったときのような状態に陥ります。

---

文字名称が「SQUARE ナンタラ」の文字は平面の単位とすることが少なくありません。その根拠は、文字名称が「SQUARE ナンタラ」だそうで（そういう回答をされた）。他にも "㍌" (U+334C) では

> UnicodeのU+334Cは「スクエア」の意味を持つ記号であり、NFKC正規化をすると、U+2764という「ハート」の意味を持つ特殊な記号「❤」に変換されます。

という回答があったりしています。さらに平方(SQUARE)から平成に繋がっている感が否めないのですが…

文章構成は素晴らしいし、反応が面白くて長々と使ってしまった。
GPT-4 では、このへんも良くなっているのかな？


---

**CJK Compatibility**

| |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|3300|㌀|㌁|㌂|㌃|㌄|㌅|㌆|㌇|㌈|㌉|㌊|㌋|㌌|㌍|㌎|㌏|
|3310|㌐|㌑|㌒|㌓|㌔|㌕|㌖|㌗|㌘|㌙|㌚|㌛|㌜|㌝|㌞|㌟|
|3320|㌠|㌡|㌢|㌣|㌤|㌥|㌦|㌧|㌨|㌩|㌪|㌫|㌬|㌭|㌮|㌯|
|3330|㌰|㌱|㌲|㌳|㌴|㌵|㌶|㌷|㌸|㌹|㌺|㌻|㌼|㌽|㌾|㌿|
|3340|㍀|㍁|㍂|㍃|㍄|㍅|㍆|㍇|㍈|㍉|㍊|㍋|㍌|㍍|㍎|㍏|
|3350|㍐|㍑|㍒|㍓|㍔|㍕|㍖|㍗|㍘|㍙|㍚|㍛|㍜|㍝|㍞|㍟|
|3360|㍠|㍡|㍢|㍣|㍤|㍥|㍦|㍧|㍨|㍩|㍪|㍫|㍬|㍭|㍮|㍯|
|3370|㍰|㍱|㍲|㍳|㍴|㍵|㍶|㍷|㍸|㍹|㍺|㍻|㍼|㍽|㍾|㍿|
|3380|㎀|㎁|㎂|㎃|㎄|㎅|㎆|㎇|㎈|㎉|㎊|㎋|㎌|㎍|㎎|㎏|
|3390|㎐|㎑|㎒|㎓|㎔|㎕|㎖|㎗|㎘|㎙|㎚|㎛|㎜|㎝|㎞|㎟|
|33A0|㎠|㎡|㎢|㎣|㎤|㎥|㎦|㎧|㎨|㎩|㎪|㎫|㎬|㎭|㎮|㎯|
|33B0|㎰|㎱|㎲|㎳|㎴|㎵|㎶|㎷|㎸|㎹|㎺|㎻|㎼|㎽|㎾|㎿|
|33C0|㏀|㏁|㏂|㏃|㏄|㏅|㏆|㏇|㏈|㏉|㏊|㏋|㏌|㏍|㏎|㏏|
|33D0|㏐|㏑|㏒|㏓|㏔|㏕|㏖|㏗|㏘|㏙|㏚|㏛|㏜|㏝|㏞|㏟|
|33E0|㏠|㏡|㏢|㏣|㏤|㏥|㏦|㏧|㏨|㏩|㏪|㏫|㏬|㏭|㏮|㏯|
|33F0|㏰|㏱|㏲|㏳|㏴|㏵|㏶|㏷|㏸|㏹|㏺|㏻|㏼|㏽|㏾|㏿|

一部（?点と?日）を除いて殆どの文字名称が「SQUARE ナンタラ」です。それが混乱の原因な気がしますが…