X

C#でプロジェクトオイラーを解く(問題42「符号化三角数」)

どーも、みつおです。

問題

三角数のn項は tn = ½n(n+1)で与えられる. 最初の10項は

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …

である.

単語中のアルファベットを数値に変換した後に和をとる. この和を「単語の値」と呼ぶことにする. 例えば SKY は 19 + 11 + 25 = 55 = t10である. 単語の値が三角数であるとき, その単語を三角語と呼ぶ.

16Kのテキストファイル words.txt 中に約2000語の英単語が記されている. 三角語はいくつあるか?

出典:Problem42

解答

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

namespace Problem42
{
    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 Data
    {
        public string Word { set; get; }

        public int Score { set; get; }

        public Data()
        {
            this.Word = "";
            this.Score = 0;
        }

        public Data(string word)
        {
            this.Word = word;
            this.Score = GetScore(word);
        }

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

            //単語のアルファベットの数値の和
            for (int i = 0; i < word.Length; i++)
            {
                //単語のアルファベットを数値に変換
                var enmVal = (Alphabet)Enum.Parse(typeof(Alphabet), word[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 int Solve()
        {
            int ret = 0;

            //三角数のリストを作成
            var sankakulist = CreateSankakuList();

            //ファイルを読み込み
            var datalist = CreateDataList();

            foreach(var data in datalist)
            {
                //三角数を取得
                var find = sankakulist.Find(tmp => tmp == data.Score);

                //三角数が見つかればカウントアップ
                if (0 < find) ret++; 
            }

            return ret;
        }

        private static List<Data> CreateDataList()
        {
            List<Data> datalist = new List<Data>();

            //ファイルの読み込み
            using (StreamReader file = new StreamReader(@"C:\Work\プロジェクトオイラー\問題42\p042_words.txt"))
            {
                //行を読み込み
                string line = file.ReadLine();

                //カンマ区切り
                string[] list = line.Split(',');

                string s = "";
                for (int i = 0; i < list.Count(); i++)
                {
                    //データクラスのリストに追加
                    s = list[i].Trim('"');
                    Data tmp = new Data(s);
                    datalist.Add(tmp);
                }
            }

            return datalist;
        }

        private static List<int> CreateSankakuList()
        {
            int num = 0;
            int max = 26 * 30;
            List<int> ret = new List<int>();

            for (int i = 1; i < max; i++)
            {
                //三角数を算出
                num = (i * (i + 1)) / 2;

                //最大文字数よりも小さい値なら三角数のリストに追加
                if (num > max) break;
                else ret.Add(num);
            }

            return ret;
        }
    }
}

 

出力

162

みつお: