Project Euler 16

Problem 16

  • 累乗の計算には、BigInteger.Pow() スタティックメソッドを使う。
  • 文字の数値への変換は、c - '0' とします。int.Parse(string) でもいいみたいです。
using System;
using System.Numerics;

class PE016 {
    public static void Main() {
        int sum = 0;
        var x = BigInteger.Pow(new BigInteger(2), 1000);
        foreach (char c in x.ToString()) {
            sum += c - '0';
        }

        Console.WriteLine(sum);
    }
}

mcs コマンドに -r:System.Numerics オプションを付けてコンパイルします。

% mcs -r:System.Numerics 016.cs -out:a.exe

追記 (2014-05-18)

BigInteger を使わずに、List に 1 桁ずつ値をもたせて計算する方法でもやってみました。

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Linq;

class PE016 {
    // BigIntegerを使う方法
    static int Calc1() {
        int sum = 0;
        var x = BigInteger.Pow(new BigInteger(2), 1000);
        foreach (char c in x.ToString()) {
            sum += c - '0';
        }
        return sum;
    }

    static List<int> Twice(List<int> ls) {
        var ret = new List<int>();
        int carry = 0;
        foreach (int x in ls) {
            int y = 2 * x + carry;
            ret.Add(y % 10);
            carry = y / 10;
        }
        if (carry > 0)
            ret.Add(carry);
        return ret;
    }

    // リストを使う方法
    static int Calc2() {
        var xs = new List<int>() { 1 };
        for (int i = 0; i < 1000; i++) {
            xs = Twice(xs);
        }
        return xs.Sum();
    }

    // Aggregateを使う方法
    static int Calc3() {
        var xs = Enumerable.Range(1, 1000).Aggregate(new List<int> { 1 }, (x, y) => Twice(x));
        return xs.Sum();
    }

    static void Main() {
        Console.WriteLine(Calc1());
        Console.WriteLine(Calc2());
        Console.WriteLine(Calc3());
    }
}

参考: