C#でプロジェクトオイラーを解く(問題22「名前のスコア」)

プロジェクトオイラー
Pocket

どーも、みつおです。

基本的にプロジェクトオイラーでクラス使わなくてもいいかと思ってたけど、今回は使った方が可読性が上がると思ったので使用したよ。

問題

5000個以上の名前が書かれている46Kのテキストファイル filenames.txt を用いる. まずアルファベット順にソートせよ.

のち, 各名前についてアルファベットに値を割り振り, リスト中の出現順の数と掛け合わせることで, 名前のスコアを計算する.

たとえば, リストがアルファベット順にソートされているとすると, COLINはリストの938番目にある. またCOLINは 3 + 15 + 12 + 9 + 14 = 53 という値を持つ. よってCOLINは 938 × 53 = 49714 というスコアを持つ.

ファイル中の全名前のスコアの合計を求めよ.

出典:Problem22

解答

読み込みデータは「names.txt」を参照してね。

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace Problem22
{
    public enum Alphabet
    {
        A = 1,
        B = 2,
        C = 3,
        D = 4,
        E = 5,
        F = 6,
        G = 7,
        H = 8,
        I = 9,
        J = 10,
        K = 11,
        L = 12,
        M = 13,
        N = 14,
        O = 15,
        P = 16,
        Q = 17,
        R = 18,
        S = 19,
        T = 20,
        U = 21,
        V = 22,
        W = 23,
        X = 24,
        Y = 25,
        Z = 26
    }

    public class Student
    {
        public string Name { set; get; }

        public int Score { set; get; }

        public Student()
        {
            this.Name = "";
            this.Score = 0;
        }

        public Student(string name)
        {
            //名前
            this.Name = name;

            //名前のスコア
            this.Score = GetScore(name);
        }

        public int GetScore(string name)
        {
            int ret = 0;

            //名前の長さ分ループ
            for (int i = 0; i < name.Length; i++)
            {
                //文字のアルファベットを取得
                var enmVal = (Alphabet)Enum.Parse(typeof(Alphabet), name[i].ToString(), true);

                //アルファベットを数値に変換
                int data = (int)Enum.ToObject(typeof(Alphabet), enmVal);

                //アルファベットの数値を足しこむ
                ret += data;
            }

            return ret;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Solve());
            Console.ReadLine();
        }

        private static long Solve()
        {
            long ret = 0;
            int no = 0;

            //ファイルを読み込んで生徒リストを作成
            var stlist = ReadFile(@"C:\Work\プロジェクトオイラー\問題22\names.txt");

            //名前の順にソート
            stlist.Sort((a, b) => a.Name.CompareTo(b.Name));

            //生徒数分ループ
            for (int i = 0; i < stlist.Count(); i++)
            {
                //リストの順序を取得
                no = i + 1;

                //順序と名前のスコアを掛け合わせた値を足しこむ
                ret += no * stlist[i].Score;
            }

            return ret;
        }

        private static List<Student> ReadFile(string filepath)
        {
            List<Student> ret = new List<Student>();

            using (StreamReader file = new StreamReader(filepath))
            {
                //ファイルを読み込み
                string line = file.ReadLine();

                //カンマで分割
                string[] list = line.Split(',');

                string s = "";

                //名前の数分ループ
                for (int i = 0; i < list.Count(); i++)
                {
                    s = list[i].Trim('"');

                    //生徒クラスのインスタンスを生成
                    Student tmp = new Student(s);

                    //リストに追加
                    ret.Add(tmp);
                }
            }

            return ret;
        }
    }
}

 

出力

871198282

コメント

タイトルとURLをコピーしました