私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「ファイル名を作ろう」(CodeIQ)を参照してください。
問題
ファイルをディレクトリ内に作成する際、同じ名前のファイルがあると、末尾に数字を付けるなどして同じ名前にならないようにします。
こうした処理をプログラムで書くことにします。
たとえば「dog」というファイルを作ろうとした場合、同じ名前のファイルが既にある場合は「dog_copy」という名前にします。「dog_copy」もある場合は「dog_copy2」という名前にします。「dog_copy2」もある場合は「dog_copy3」という名前にします。以下、末尾の数字が1ずつ増えていきます。
与えられる入力は、フォルダ内のファイル名のリストです。ただし、末尾の名前だけリストには含まれず、作成したいファイルの名前になります。
この末尾のファイル名を、上記の手順で変換して、作成可能なファイル名にします。そして、標準出力に出力して下さい。
下記では、「dog、tiger、dog_copy、rat、snake、monkey、snake_copy、rat_copy、snake_copy2、cat」がファイル名のリストで、「dog」が作成したいファイルの名前になります。
そして出力するファイル名は「dog_copy2」になります。
// 入力例
dog
tiger
dog_copy
rat
snake
monkey
snake_copy
rat_copy
snake_copy2
cat
dog
// 出力例
dog_copy2
Rubyで解答しています。
#!/usr/bin/ruby def solve(target, inputs) inputs.sort mx = -1 for i in inputs next if i.index(target) != 0 if i == target then mx = 0 if mx < 0 elsif i == target + "_copy" then mx = 1 if mx < 1 else rp = Regexp.new(target + "_copy") num = i.gsub(rp, "").to_i mx = num if mx < num end end if mx == -1 then return target elsif mx == 0 then return target + "_copy" else return target + "_copy" + (mx+1).to_s end end # main inputs = [] while line = gets line.strip! next if line.empty? inputs << line end target = inputs.pop puts solve(target, inputs)
息抜き問題なので簡単です。
考え方というほどのものはありません。
対象のファイル名と先頭部分が一致するファイルだけをチェクし、一番大きい番号+1をつけるだけです。
このとき、「dog」しかない場合と「dog」と「dog_copy」しかない場合は特別に処理して0と1として扱います。
入力値をinputsに取得し、最後を除いてtargetに取っています。 solve()にtargetとinputsを渡して結果の文字列を印字します。
とりあえずinputsをソートします(必要ありませんでした)。
inputsの要素を順に繰り返し、targetと先頭が一致する文字列でなければ無視します(このコードは厳密にはバグ)。
文字列がtargetに一致していたら番号(mx)を0、target+"_copy"に一致していたらmx=1、それ以外なら「filename_cpoy数字」から「failname_copy」をから文字列に置換して数字だけを取り出しmxに代入します。
mx=-1ならそのファイル名は無いのでそのまま、mx=0なら_copy、それ以外なら_copy+(mx+1)をファイル名につけて出力すればOKです。
答え合わせのページにヒントがあって、確か1,2,3,…とカウントアップしながらファイル名を順次チェックし、見つからなくなったところでその値を使えば良い、という様な内容だったと思います。
このロジックより私のコードの方が少し効率が良いです。
ただ、「dog, dog_copy, dog_cpoy1, dog_copy3」の様に番号が跳んでいたら結果が異なってしまいますが、どちらを想定していたんだろう?