なでしこで AtCoder の問題を解く (笑) #Node.js - Qiita
を書いている中で、衝撃の事実を発見した。
それは、なでしこの文字列リテラルでは、セミコロンを連続して書くとなぜか1個にされるということである。
そこで、この記事では、この謎仕様についてさらに詳しく見ていく。
Webブラウザ版でもやられるか? (はい)
AtCoder で用いているのは、Node.js 版のなでしこである。
そこで、
なでしこ3簡易エディタ - 日本語プログラミング言語「なでしこ3」 (v3.7.9)
で実行し、Webブラウザ版でもやられるかを確認する。
『
for (;;) { break; }
』を表示。
を実行してみると、AtCoder での実行結果と同じく
for (;) { break; }
が出力され、Webブラウザ版でもやられる (1個にされる) ことがわかった。
他の種類のカッコでもやられるか? (はい)
Web簡易エディタで
「;;;;;;;;;;」と表示。
『;;;;;;;;;;』と表示。
";;;;;;;;;;"と表示。
';;;;;;;;;;'と表示。
“;;;;;;;;;;”と表示。
🌴;;;;;;;;;;🌴と表示。
🌿;;;;;;;;;;🌿と表示。
を実行してみた。すると、出力
;
;
;
;
;
;
;
が得られ、
📖 なでしこ3 マニュアル - 文法/文字列
で紹介されている全ての種類の文字列でやられる (1個にされる) ことがわかった。
全角のセミコロンもやられるか? (いいえ)
Web簡易エディタで
「;;;;;;;;;;」と表示。
『;;;;;;;;;;』と表示。
";;;;;;;;;;"と表示。
';;;;;;;;;;'と表示。
“;;;;;;;;;;”と表示。
🌴;;;;;;;;;;🌴と表示。
🌿;;;;;;;;;;🌿と表示。
を実行してみた。すると、出力
;;;;;;;;;;
;;;;;;;;;;
;;;;;;;;;;
;;;;;;;;;;
;;;;;;;;;;
;;;;;;;;;;
;;;;;;;;;;
が得られ、セミコロンでも全角だとやられない (1個にされない) ことがわかった。
他の文字もやられるか? (いいえ)
Web簡易エディタで
テスト文字列配列は空配列。
文字で0x20から0x7eまで繰り返す
CHR(文字)を10でリフレインしてテスト文字列配列に配列追加。
ここまで。
テスト文字列はテスト文字列配列を改行で配列結合。
テストコードは「『{テスト文字列}』を表示」。
テストコードを表示。
テストコードをナデシコする。
を実行してみた。すると、以下の出力が得られた。
出力結果
『
!!!!!!!!!!
""""""""""
##########
$$$$$$$$$$
%%%%%%%%%%
&&&&&&&&&&
''''''''''
((((((((((
))))))))))
**********
++++++++++
,,,,,,,,,,
----------
..........
//////////
0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
::::::::::
;;;;;;;;;;
<<<<<<<<<<
==========
>>>>>>>>>>
??????????
@@@@@@@@@@
AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC
DDDDDDDDDD
EEEEEEEEEE
FFFFFFFFFF
GGGGGGGGGG
HHHHHHHHHH
IIIIIIIIII
JJJJJJJJJJ
KKKKKKKKKK
LLLLLLLLLL
MMMMMMMMMM
NNNNNNNNNN
OOOOOOOOOO
PPPPPPPPPP
QQQQQQQQQQ
RRRRRRRRRR
SSSSSSSSSS
TTTTTTTTTT
UUUUUUUUUU
VVVVVVVVVV
WWWWWWWWWW
XXXXXXXXXX
YYYYYYYYYY
ZZZZZZZZZZ
[[[[[[[[[[
\\\\\\\\\\
]]]]]]]]]]
^^^^^^^^^^
__________
``````````
aaaaaaaaaa
bbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee
ffffffffff
gggggggggg
hhhhhhhhhh
iiiiiiiiii
jjjjjjjjjj
kkkkkkkkkk
llllllllll
mmmmmmmmmm
nnnnnnnnnn
oooooooooo
pppppppppp
qqqqqqqqqq
rrrrrrrrrr
ssssssssss
tttttttttt
uuuuuuuuuu
vvvvvvvvvv
wwwwwwwwww
xxxxxxxxxx
yyyyyyyyyy
zzzzzzzzzz
{{{{{{{{{{
||||||||||
}}}}}}}}}}
~~~~~~~~~~』を表示
!!!!!!!!!!
""""""""""
##########
$$$$$$$$$$
%%%%%%%%%%
&&&&&&&&&&
''''''''''
((((((((((
))))))))))
**********
++++++++++
,,,,,,,,,,
----------
..........
//////////
0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
::::::::::
;
<<<<<<<<<<
==========
>>>>>>>>>>
??????????
@@@@@@@@@@
AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC
DDDDDDDDDD
EEEEEEEEEE
FFFFFFFFFF
GGGGGGGGGG
HHHHHHHHHH
IIIIIIIIII
JJJJJJJJJJ
KKKKKKKKKK
LLLLLLLLLL
MMMMMMMMMM
NNNNNNNNNN
OOOOOOOOOO
PPPPPPPPPP
QQQQQQQQQQ
RRRRRRRRRR
SSSSSSSSSS
TTTTTTTTTT
UUUUUUUUUU
VVVVVVVVVV
WWWWWWWWWW
XXXXXXXXXX
YYYYYYYYYY
ZZZZZZZZZZ
[[[[[[[[[[
\\\\\\\\\\
]]]]]]]]]]
^^^^^^^^^^
__________
``````````
aaaaaaaaaa
bbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee
ffffffffff
gggggggggg
hhhhhhhhhh
iiiiiiiiii
jjjjjjjjjj
kkkkkkkkkk
llllllllll
mmmmmmmmmm
nnnnnnnnnn
oooooooooo
pppppppppp
qqqqqqqqqq
rrrrrrrrrr
ssssssssss
tttttttttt
uuuuuuuuuu
vvvvvvvvvv
wwwwwwwwww
xxxxxxxxxx
yyyyyyyyyy
zzzzzzzzzz
{{{{{{{{{{
||||||||||
}}}}}}}}}}
~~~~~~~~~~
ASCII 印字可能文字の中では、セミコロンだけがやられる (1個にされる) ことがわかった。
もっと他の文字もやられるか? (いいえ)
Web簡易エディタで
NG文字は『{「」{』。
文字コードで0から0xffffまで繰り返す
文字はCHR(文字コード)。
文字列は文字を10でリフレイン。
もし、NG文字で文字を1から文字検索ならば
カッコ文字列は「『{文字列}』」。
違えば
カッコ文字列は「{カッコ}{文字列}{カッコ閉}」。
ここまで。
「実行結果は{カッコ文字列}」をナデシコする。
もし、実行結果が文字列と等しく無いならば
「{文字コード}:{文字列} → {実行結果}」を表示。
ここまで。
ここまで。
を実行してみた。すると、出力
13:
→
59:;;;;;;;;;; → ;
が得られた。
13 に関する出力は、CR が LF に置き換えられ、違いとして検出されたようである。
これは、
「実行結果は{カッコ}{CHR(13)}{カッコ閉}」をナデシコする。
ASC(実行結果)を表示。
を実行すると 10 が出力されることで確かめることができる。
そして、1個の UTF-16 コードユニットで表される文字の中では、やられる (1個にされる) のは半角セミコロンだけであることがわかった。
まとめ
検証の結果、以下のことがわかった。
- 文字列リテラル中の連続した半角セミコロンが1個にされる仕様は、Node.js 版だけでなく、Webブラウザ版のなでしこでも発動する
- この仕様は、文字列リテラルを表すカッコなどの種類にかかわらず発動する
- 全角セミコロンを含め、半角セミコロン以外の文字は連続しても1個にされなそうである
- 1個にされるのは文字列リテラル中の連続した半角セミコロンであり、プログラムで作成した文字列データ中で半角セミコロンが連続していても1個にされない