1. ホーム
  2. python

[解決済み] Llanfairpwllgwyngyllgogerychwyrndrobwllantysiliogogogochの文字はどのように数えるのでしょうか?

2023-08-30 15:55:32

質問

Llanfairpwllgwyngyllgogerychwyrndrobwllantysiliogogogochの文字はどのように数えるのでしょうか?

print(len('Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'))

58の発言

そんな簡単なことなら、あなたに頼んでないわよね!?

ウィキペディアによると( https://en.wikipedia.org/wiki/Llanfairpwllgwyngyll#Placename_and_toponymy )

この名前の長い形式は、イギリスで最も長い地名であり、58文字という世界で最も長い地名の一つです。 58文字で、世界で最も長い地名の1つです。 (51 ch"と"ll"はダイグラフであり、ウェールズ語では1文字として扱われるため、51文字となる。 ウェールズ語では1文字として扱われます)。

だから、それを数えて51という答えを出したい。

オッケーオッケー。

print(len(['Ll','a','n','f','a','i','r','p','w','ll','g','w','y','n','g','y','ll','g','o','g','e','r','y','ch','w','y','r','n','d','r','o','b','w','ll','ll','a','n','t','y','s','i','l','i','o','g','o','g','o','g','o','ch']))
51

ええ、しかしそれは不正行為です。明らかに私はリストではなく、入力として単語を使いたいのです。

また、Wikipediaによると、ウェールズ語のダイグラフは ch, dd, ff, ng, ll, ph, rh, th です。

https://en.wikipedia.org/wiki/Welsh_orthography#Digraphs

というわけで、出発です。長さを足し算して、二重計算を外しましょう。

word='Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'
count=len(word)
print('starting with count of',count)
for index in range(len(word)-1):
  substring=word[index]+word[index+1]
  if substring.lower() in ['ch','dd','ff','ng','ll','ph','rh','th']:
    print('taking off double counting of',substring)
    count=count-1
print(count)

これでここまで来ました

starting with count of 58
taking off double counting of Ll
taking off double counting of ll
taking off double counting of ng
taking off double counting of ll
taking off double counting of ch
taking off double counting of ll
taking off double counting of ll
taking off double counting of ll
taking off double counting of ch
49

どうやら引き算をしすぎたようです。51になるはずなのですが。さて、ひとつ問題があるとすれば llll で、3つの ll を見つけ、2つではなく3つ取り除いています。だから、それを修正する必要があるのです。(重ならないようにしなければなりません)

それからもうひとつ問題があります。その ng . Wikipediaには、名前に "ng" が入っていることについては何も書かれていませんでしたが、上で引用したページでは、ダイグラフの1つとしてリストアップされているんですね。

ウィキペディアはここでさらにいくつかの手がかりを与えてくれます。 . そして、".の例を挙げています。 llongyfarch "では、ngは単なる"文字の並置"であり、" llong となっています。

ということで、どうやら「Llanfairpwllgwy」は ng yllgogerychwyrndrobwllllantysiliogogogoch'は、-ng-が単なる文字の並置であるような単語の1つである。

そして明らかにコンピュータがそれを知る術はないのです。ですから、Wikipediaにあるような「追加情報」を与えなければならないのです。

そこでとにかく、オンライン辞書で調べてみることにしました。 http://geiriadur.ac.uk/gpc/gpc.html と調べると llongyfarch (ウィキペディアの例で、文字の並置があるもの) を見ると、それを n と g の間に縦線 と表示されますが、"llong"を調べると、このようなことはありません。

というわけで、追加情報を提供するために必要なことは | を入力文字列に入れることで、追加情報を提供する必要があります。 ng ビットが実際には 2 文字であることをアルゴリズムに認識させるためです。しかし、明らかに私は | を文字としてカウントさせたくないのは明らかです。

というわけで、今度はこんな入力がありました。

word='llong'
ANSWER NEEDS TO BE 3 (ll o ng)

word='llon|gyfarch'
ANSWER NEEDS TO BE 9 (ll o n g y f a r ch)

word='Llanfairpwllgwyn|gyllgogerychwyrndrobwllllantysiliogogogoch'
ANSWER NEEDS TO BE 51 (Ll a n f a i r p w ll g w y n g y ll g o g e r y ch w y r n d r o b w ll ll a n t y s i l i o g o g o g o ch)

と、やはりこのようなダイグラフのリストがあります。

['ch','dd','ff','ng','ll','ph','rh','th']

といったルールになりそうです。

  1. ケースを無視する

  2. ダイグラフがあれば1としてカウントする。

  3. は、左から右に向かって、次のように動作します。 llllll + ll でなく l + ll + l

  4. が表示されたら | があったらカウントしてはいけませんが、完全に無視することはできません。 ng はダイグラフである

を51とカウントして、フカシではなく、ちゃんとした理由でやって欲しいです。

現在51を取得していますが、これは | を 1 文字としてカウントし (1 高すぎ)、さらにその 1 文字分を llll (1 too low) - ERRORS CANCEL OUT

これは llong の右側にある(3)。

取得しているのは llon|gyfarch が間違っている (10個) - 数えると | をもう一度

どうすれば正しい方法で修正できるのでしょうか?

どのように解決するのですか?

文字列に関する多くの問題のように、これは正規表現を用いて簡単な方法で行うことができます。

>>> word = 'Llanfairpwllgwyn|gyllgogerychwyrndrobwllllantysiliogogogoch'
>>> import re
>>> pattern = re.compile(r'ch|dd|ff|ng|ll|ph|rh|th|[^\W\d_]', flags=re.IGNORECASE)
>>> len(pattern.findall(word))
51

文字クラス [^\W\d_] から ここで ) は、数字やアンダースコア以外の単語文字、つまり、発音区分符号付きの文字も含めて、文字にマッチします。