Delegate


 久々にツイッターにログインしたらデリゲートがわからないと書いてあって
「自分やん」
と思ったのでまとめつつ備忘録として書いてみる。

delegate

 英語の意味としては代表・委任・権限の委譲、ということらしいです。
delegateキーワードを付けると代表者になれるってことですね。多分。


取りあえず書き
using System;
using System.Diagnostics;
using System.Collections.Generic;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            tes t = new tes();
        }
    }

    class tes
    {
        //デリゲート型を指定
        //デリゲート型芭蕉
        private delegate String basyou(String a, String b);
        //デリゲート型動物
        private delegate void doubutu(String s);

        public tes()
        {
            //例1
            basyou b = gyaku;
            Debug.WriteLine("芭蕉曰く「" + b("砕けない", "ダイヤモンドは") + "」");

            //例2
            List<basyou> k = new List<basyou>();

            k.Add(futuu);
            k.Add(gyaku);

            foreach (basyou i in k)
            {
                Debug.WriteLine("芭蕉曰く「" + i("君たちは", "腐ったミカンだ") + "」");
            }

            //例3(匿名型)
            basyou n = delegate (string a1, string a2) { return a1.Replace("神","ネコ") + a2; };
            Debug.WriteLine(n("神と", "和解せよ"));

            //例4(ラムダ式)
            basyou op = (c1, c2) => c2.Replace("か", "");
            Debug.WriteLine(op("力が", "欲しいか"));

            //例5(デリゲートの連結) ActionかFuncじゃないと無理?(未確認)
            doubutu pome, ame, nanika;
            pome = inu;
            ame = neko;
            nanika = pome + ame;
            nanika("ティラノサウルス");
        }

        //結合
        private String futuu(String a, String b)
        {
            return a + b;
        }

        //前後を逆にして結合
        private String gyaku(String a, String b)
        {
            return b + a;
        }

        //これは犬です
        private void inu(string s)
        {
            Debug.WriteLine(s + "は犬");
        }

        //疑いようもなく猫です
        private void neko(string s)
        {
            Debug.WriteLine(s + "は猫");
        }

    }
}


出力

芭蕉曰く「ダイヤモンドは砕けない」
芭蕉曰く「君たちは腐ったミカンだ」
芭蕉曰く「腐ったミカンだ君たちは」
ネコと和解せよ
欲しい
ティラノサウルスは犬
ティラノサウルスは猫


 これ、関数ポインタじゃないの?というのが最初の感想。

連結

・ActionやFuncのタイプじゃないと連結してくれないんだろうか?

『Tactical Chronicle』始めました

f:id:pongeponge:20161207183136j:plain
 久々にヒットしたフリーゲームRPG


プレイ動画


14分くらいから 村の外へ
44分くらいから 討伐戦


公式サイト

Tactical Chronicle


三行感想

・正直面白い
・功績点を効率よく得るにはどうしたらいいんだろう?
ファーストクイーン思い出すわ




(アヴィレックス)AVIREX PDW TACTICAL N2 JKT 6662008 09BLK BLACK M

(アヴィレックス)AVIREX PDW TACTICAL N2 JKT 6662008 09BLK BLACK M

Project Euler : Problem 29 『Distinct powers』

犬と猫犬と猫 / kagawa_ymg

問題

projecteuler.net


 ab (2 ≤ a ≤ 100, 2 ≤ b ≤ 100) で作れる数は何個あるか?


値が大きいので極力計算しない方向で

 100100なんか計算してられないし。
何より、100100までの数字をチェックしないといけないなんて悪夢だ…。


重複を見る

 例えば、24 と 42 は共に16で重複してる。
なぜ重複してるのかというと、4 = 22なので、
42
= (22)2
= 22×2
= 24
 同じ底aで揃えた場合、同じ指数bになれば同じ数字だとわかる。
この場合、底と指数が違うのに計算結果が同じになるので、値のダブルチェックを回避する。


 ……とりあえず説明が凄くめんどくさいので、後はコードを見てください(手抜き)


コード
using System.Diagnostics;
using System.Linq;

namespace Problem29
{
    class Program
    {
        //範囲
        static int min = 2;
        static int max = 100;

        static void Main(string[] args)
        {
            Debug.WriteLine(DistinctPowers());
        }

        static int DistinctPowers()
        {
            bool[] findA = new bool[max + 1];
            int sum = 0;

            for (int a = min; a <= max; a++)
            {
                if (findA[a] == false)
                {
                    int b = maxB(a, findA);

                    sum += NumberCount(b);
                }
            }

            return sum;
        }

        /// <summary>
        /// a^bの最も大きいbを調べる
        /// </summary>
        static int maxB(int a, bool[] findA)
        {
            int b = 0;

            for (int i = a; i <= max; i *= a)
            {
                findA[i] = true;
                b++;
            }

            return b;
        }

        /// <summary>
        /// b乗まである場合の出現個数を求める
        /// </summary>
        static int NumberCount(int b)
        {
            if (b == 1) return max - min + 1;

            bool[] findB = new bool[b * max + 1];

            for (int d = 1; d <= b; d++)
            {
                for (int j = min * d; j <= d * max; j += d)
                {
                    if (findB[j] == false) findB[j] = true;
                }
            }

            return findB.Where(obj => obj == true).Count();
        }
    }
}
結果

 9183


 ホント説明しにくいわ…。
ホワイトボードなんかで対話的にバーッと書いてやれるんならどれだけラクか。



指数で儲けるカンタン売買

指数で儲けるカンタン売買

EQ こころの知能指数 (講談社+α文庫)

EQ こころの知能指数 (講談社+α文庫)

Project Euler : Problem 28 『Number spiral diagonals』


SpiralSpiral / mrhayata

問題

projecteuler.net


 時計回りで渦巻き状に数字が並んでいる。
サイズが1001×1001の場合、対角線上の数字の総和はいくらか?


何ループ目か

 最初の1を0ループ目として、次の2から9を1ループ目とする。
0ループ目は1だけしかないのでサイズは1×1。
1ループ目は3×3、2ループ目は5×5。


表にするとこんな感じ。

ループ012(n - 1) / 2
サイズ135n


 サイズがn×nのとき、一番外側は(n - 1) / 2ループ目になる。
出題では1001×1001なので、
(1001 - 1) / 2 = 500
よって500ループ目まで調べる必要がある、ということになります。


右下を見ていこう

 対角線上にある数のうち、右下を数列 an とみなします。
\( a_{n} = 1, 3, 13, 31, \cdots \)
よくわからないまま差分を取ります。
\(b_{n} = 2, 10, 18, \cdots \)
何かに突き動かされるように、さらに差分を取ります。
\(c_{n} = 8, 8, \cdots \)


 cn が8,8,…ということは、bn は等差数列になっています。
\(b_{n} = 2 + 8n \)
anは各項の差がbn-1なので
\(a_{0} = 1 \\
a_{n} = a_{n-1}+b_{n-1} \ \ \ (n>0)\)


 これで右下の値を求めるめどがつきました。


1週分の和を求める

 中央の1は1周という感じじゃないですが、まぁ l0 とします。
\( l_{0} = 1 \)


 次は l1 の2~9、1周分を考えます。
右下の3を起点と考えると、
\( l_{1} = 3+5+7+9 \\
= 3+(3+2)+(3+4)+(3+6) \\
= 4 \times 3+12\)


 次に l2 の10~25を考えます。
右下の13を起点と考えると、
\( l_{1} = 13+17+21+25 \\
= 13+(13+4)+(13+8)+(13+12) \\
= 4 \times 13+24\)


 段々それっぽい規則性が見えてきましたが、確認のために l3 を。
\( l_{1} = 31+37+43+49 \\
= 31+(31+6)+(31+12)+(31+18) \\
= 4 \times 31+36\)


以上から、 m週目の lm
\( l_{0} = a_{0} = 1 \\
l_{m} = 4a_{m} + 12m \)
で求まることがわかりました。


 あとはプログラムに落とし込むだけ!


コード
using System;
using System.Diagnostics;

namespace Problem28
{
    class Program
    {
        static void Main(string[] args)
        {
            Debug.WriteLine(NumberSpiralDiagonals(1001));
        }

        static Int64 NumberSpiralDiagonals(int size)
        {
            int loops = (size - 1) / 2;

            int a = 0;
            Int64 sum = 0;
            for (int m = 0; m <= loops; m++)
            {
                a = ComputeA(a, m - 1);
                sum += LoopSum(a, m);
            }

            return sum;
        }

        /// <summary>
        /// m週目の右下の値aを求める
        /// </summary>
        static int ComputeA(int a, int m)
        {
            if (m < 0) return 1;

            int b = 2 + 8 * m;

            return a + b;
        }

        /// <summary>
        /// 一周分の和を求める
        /// </summary>
        static Int64 LoopSum(int a, int m)
        {
            if (m == 0) return a;

            return 4 * a + 12 * m;
        }
    }
}