|
#!/usr/bin/env ruby |
|
# encoding: UTF-8 |
|
|
|
require 'csv' |
|
|
|
# 処理開始メッセージ |
|
puts "日本の駅名の逆順とアナグラムのペアを探すプログラムを実行します..." |
|
|
|
# CSVファイルから駅名を読み込む |
|
stations = [] |
|
begin |
|
CSV.foreach('output.csv', headers: true, encoding: 'UTF-8') do |row| |
|
if row['駅名'] && !row['駅名'].empty? |
|
stations << { |
|
name: row['駅名'], |
|
company: row['事業者名'], |
|
line: row['路線名'] |
|
} |
|
end |
|
end |
|
puts "#{stations.size}個の駅情報を読み込みました" |
|
rescue => e |
|
puts "エラー: CSVファイルの読み込みに失敗しました - #{e.message}" |
|
exit 1 |
|
end |
|
|
|
# 駅名だけの配列を作成 |
|
station_names = stations.map { |s| s[:name] } |
|
|
|
# 駅名から情報を素早く引き出せるようにハッシュを作成 |
|
station_info = {} |
|
stations.each do |station| |
|
name = station[:name] |
|
# 同じ駅名が複数ある場合は配列に追加 |
|
if station_info[name] |
|
station_info[name] << station |
|
else |
|
station_info[name] = [station] |
|
end |
|
end |
|
|
|
# 重複を削除 |
|
unique_station_names = station_names.uniq |
|
puts "重複を除いた駅名は#{unique_station_names.size}個です" |
|
|
|
# 完全な逆順ペアとアナグラムペアを保存する配列 |
|
complete_reverse_pairs = [] |
|
anagram_pairs = [] |
|
|
|
# 効率化のための駅名ハッシュを作成 |
|
station_hash = {} |
|
unique_station_names.each do |name| |
|
# 1文字の駅名はスキップ |
|
next if name.length <= 1 |
|
|
|
# 駅名の文字を逆順にした文字列 |
|
reversed = name.chars.reverse.join |
|
|
|
# 駅名の文字をソートした文字列 |
|
sorted = name.chars.sort.join |
|
|
|
station_hash[name] = { |
|
reversed: reversed, |
|
sorted: sorted |
|
} |
|
end |
|
|
|
puts "駅名の解析中..." |
|
|
|
# 完全な逆順ペアを探す |
|
station_hash.each_key do |name1| |
|
# 自分自身が回文(逆から読んでも同じ)の場合はスキップ |
|
next if name1 == station_hash[name1][:reversed] |
|
|
|
# 逆順の駅名がリストにあるかチェック |
|
reversed_name = station_hash[name1][:reversed] |
|
if station_hash.key?(reversed_name) && name1 < reversed_name |
|
complete_reverse_pairs << [name1, reversed_name] |
|
end |
|
end |
|
|
|
# アナグラムペアを探す(同じ文字を使った別の駅名) |
|
station_names = station_hash.keys.sort |
|
station_names.each_with_index do |name1, i| |
|
(i+1...station_names.length).each do |j| |
|
name2 = station_names[j] |
|
|
|
# 同じ文字セットを持つかチェック(逆順ペアでないもの) |
|
if name1 != station_hash[name2][:reversed] && |
|
station_hash[name1][:sorted] == station_hash[name2][:sorted] |
|
anagram_pairs << [name1, name2] |
|
end |
|
end |
|
end |
|
|
|
# 駅名ペアの詳細情報を表示するメソッド |
|
def print_station_pair(pair, station_info) |
|
station1, station2 = pair |
|
|
|
puts "『#{station1}』 - 『#{station2}』" |
|
|
|
puts " 【#{station1}】" |
|
station_info[station1].each do |info| |
|
puts " #{info[:company]} - #{info[:line]}" |
|
end |
|
|
|
puts " 【#{station2}】" |
|
station_info[station2].each do |info| |
|
puts " #{info[:company]} - #{info[:line]}" |
|
end |
|
|
|
puts "" # 空行を入れて見やすくする |
|
end |
|
|
|
# 結果を出力 |
|
puts "\n==== 完全な逆順のペア(#{complete_reverse_pairs.size}個)====" |
|
if complete_reverse_pairs.empty? |
|
puts "該当するペアが見つかりませんでした。" |
|
else |
|
complete_reverse_pairs.each do |pair| |
|
print_station_pair(pair, station_info) |
|
end |
|
end |
|
|
|
puts "\n==== アナグラム(同じ文字を使った別の駅名)のペア(#{anagram_pairs.size}個)====" |
|
if anagram_pairs.empty? |
|
puts "該当するペアが見つかりませんでした。" |
|
else |
|
# 結果が多すぎる場合は制限する |
|
display_limit = 100 |
|
pairs_to_display = anagram_pairs.take(display_limit) |
|
|
|
pairs_to_display.each do |pair| |
|
print_station_pair(pair, station_info) |
|
end |
|
|
|
if anagram_pairs.size > display_limit |
|
puts "...他 #{anagram_pairs.size - display_limit}件" |
|
end |
|
end |
|
|
|
puts "\n処理が完了しました!" |