B - Palindrome with leading zeros

本日はこちらの問題をやらせていただいた。

B問題であるにも関わらず、コードがクッソ長くなって泣きました。しかし、一応ACになったのでよし。

こちらの問題は、ある数字Nが入力されて、そのNが回文になるとき、または、そのNの先頭に0を何個か加えた結果回文になるとき、”Yes”と出力して、そうでない場合は”No”と出力する問題です。

それでは早速コード紹介。

import sys

def is_kaibun(text):
 
 texHalf1 = ""
 texHalf2 = ""
 halfIndex = len(text)//2
 if len(text) % 2 == 0:
   texHalf1 = text[:halfIndex]
   texHalf2 = text_reverse_sort(text[halfIndex:])
 else:
   texHalf1 = text[:halfIndex]
   texHalf2 = text_reverse_sort(text[(halfIndex+1):])
   
 if texHalf1 == texHalf2:
   return True
 return False

def text_reverse_sort(text):
 textList = ["a" for _ in range(len(text))] 
 for i,text in enumerate(text):
   textList[-(i+1)] = text
 reverseText = ""
 for char in textList:
   reverseText += char
   
 return reverseText
 
numTex = input().rstrip()
if is_kaibun(numTex):
 print("Yes")
 exit()

for _ in range(10):
 numTex = "0" + numTex
 if is_kaibun(numTex):
   print("Yes")
   exit() 

print("No")

長い長すぎる。とてもB問題のコードとは思えん。

早速コード解説です。

まず今回は二つの関数を作っているので、その一つ目からお披露目

def is_kaibun(text):
 
 texHalf1 = ""
 texHalf2 = ""
 halfIndex = len(text)//2
 if len(text) % 2 == 0:
   texHalf1 = text[:halfIndex]
   texHalf2 = text_reverse_sort(text[halfIndex:])
 else:
   texHalf1 = text[:halfIndex]
   texHalf2 = text_reverse_sort(text[(halfIndex+1):])
   
 if texHalf1 == texHalf2:
   return True
 return False

こちらは引数として与えられた文字列が回文であるか否かを判定するための関数です。回文だったらTrueを返し、そうでないならFalseを返します。

まず与えられた文字列の文字数が偶数か奇数かで条件分岐が発生しています。文字数が偶数だろうと奇数だろうと、やっていることは文字の半分となるところで分割して、文字列の前半をtexHalf1に、文字列の後半をtexHalf2に代入しているだけです。しかし、文字列の偶奇によって、参照するインデックスが少し異なったため、このような条件分岐をせざるを得んかったです。

ちなみに、texHalf2の方では、単純に文字列の後半を引き抜くだけではなく、その文字列を逆順にソートして代入を行っています。

"abc" → "cba" 、"bow" → "wob" といった感じですね。
この関数の最後のIF文では、文字列の先頭と逆順にした文字列の後半を比較して、全く同じ文字列なら”True”を返し、そうでないなら”False”を返します。

次に文字列の逆順ソートをするときに用いた関数を紹介します。

def text_reverse_sort(text):
 textList = ["a" for _ in range(len(text))] 
 for i,text in enumerate(text):
   textList[-(i+1)] = text
 reverseText = ""
 for char in textList:
   reverseText += char
   
 return reverseText

引数にtextをとっています。

まず最初にtextListをtextの文字数分の”a”で初期化しています。
次にfor文でtextの先頭から一文字一文字を取り出していって、それをtextListの最後尾からスタートして一番前まで入れていきます。

最後にtextListを先頭から文字をとっていき、reverseTextに代入しています。
そして、文字列reverseTextを返り値をして吐き出しています。

多分もっといい方法あります。

さあ最後のメインの処理です。

numTex = input().rstrip()
if is_kaibun(numTex):
 print("Yes")
 exit()

for _ in range(10):
 numTex = "0" + numTex
 if is_kaibun(numTex):
   print("Yes")
   exit() 

print("No")

numTexに回文判定をする文字列を格納。

先ほど紹介したis_kaibun関数で回文かどうかを判定し、回文なら”Yes”を出力して処理終了。

そうでないなら、for文に入ります。for文では、numTexの先頭に"0"の文字列を付加して、また回文かどうかを判定しています。回文なら処理終了。
この作業を10回繰り返しています。
なぜ10回にしたかという説明をします。こちらの問題では制約が設けられており、与えられる文字列(数字)であるNの範囲が 0<= N <= 10**9 となっているため、Nの上限は1を先頭にして、その後ろに0が9つ連なっている数字です。そのため、0を9つ新たに先頭に付加することで回文になります。

なので、今考えると10回じゃなくて9回でよかったですね。この記事を書いている途中で気づきましたw

最後まで0を付加したにも関わらず、まだ回文になってくれない不届きな文字列には”No”という文字列を突き付けてファイナルアンサーです(決まった)

プログラムに関してまだまだ駆け出しなので、アドバイス等ありましたらコメントお願いします。以上、知識乞食の記録でした。


この記事が気に入ったらサポートをしてみませんか?