<commit_before>#ifndef __LARGEINT_H__
#define __LARGEINT_H__

#include <cmath>
#include <initializer_list>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
#include <type_traits>

namespace Euler
{
  template <typename Int_t>
  class LargeInt
  {
  private:
    /** 巨大な整数の内部表現 */
    std::vector<Int_t> num;
    /** 符号 */
    bool is_negative;
    /** 内部値が不正な場合failed == true */
    bool failed;

  public:
    /** 各要素の最大桁数(使用する整数型の最大値の桁数-1; 最大桁でやると計算途中で溢れる可能性がある) */
    static constexpr Int_t MAX_DIGITS = std::log10(std::numeric_limits<Int_t>::max());
    static constexpr Int_t LIMIT_PER_TERMS = std::pow(10, MAX_DIGITS - 1);

  public:  // コンストラクタ
    /**
     * 普通のInt_tから生成
     * @param init 初期値
     */
    LargeInt(Int_t init)
      : is_negative(init < 0),
        failed(false)
    {
      num.push_back(init < 0 ? -init : init);
    }

    /**
     * 値を表現する数値列から生成
     * ex) 12345 -> {1,2,3,4,5}
     * @param  vec 初期値を表す数値列
     */
    LargeInt(const std::initializer_list<Int_t>& vec)
      : is_negative(false),
        failed(false)
    {
      Int_t n = 0;
      const auto size = vec.size();
      using SizeType = typename std::remove_const<decltype(size)>::type;
      if (size > 0) {
        num.reserve(static_cast<SizeType>(std::log10(size) + 1) / (MAX_DIGITS - 1));
      }

      for (SizeType i = 0; i < size; i++) {
        if (*(vec.end() - i - 1) > 9) {
          failed = true;
          return;
        }
        if ((i > 0 && i + 1 < size && i % (MAX_DIGITS - 1) == 0)) {
          num.push_back(n);
          n = 0;
        }
        n += std::pow(10, i % (MAX_DIGITS - 1)) * (*(vec.end() - i - 1));
      }
      num.push_back(n);
    }

    /**
     * コピーコンストラクタ
     */
    LargeInt(const LargeInt<Int_t>& src)
    noexcept
    {
      *this = src;
    }

    /**
     * ムーブコンストラクタ
     */
    LargeInt(LargeInt<Int_t>&& src)
    noexcept
    {
      *this = std::move(src);
    }

  private:
    /**
     * 生成に失敗したオブジェクトを使っていないかチェック
     */
    inline
    void check_availability() const
    {
      if (failed) {
        throw std::runtime_error("cannot use a \'failed\' LargeInt object");
      }
    }

  private:
    /**
     * 足し算の内部実装
     * @param another  足す数(a+bのときのb)
     * @param dest     結果を返す先
     */
    void add_impl(const LargeInt<Int_t>& another, LargeInt<Int_t>* dest)
    const
    {
      check_availability();
      another.check_availability();
      const auto another_size = another.num.size();
      if (dest->num.size() < another_size) {
        dest->num.resize(another_size, 0);
      }
      const auto size = dest->num.size();
      using SizeType = typename std::remove_const<decltype(size)>::type;

      for (SizeType i = 0; i < size; i++) {
        if (i >= another_size) {
          break;
        }
        dest->num.at(i) += another.num.at(i);
        // 要素を跨ぐ繰り上げ
        auto n = i;
        while (dest->num.at(n) >= LIMIT_PER_TERMS) {
          dest->num.at(n) -= LIMIT_PER_TERMS;
          n++;
          if (n < size) {
            dest->num.at(n) += 1;
          }
          else {
            dest->num.push_back(1);
            break;
          }
        }
      }
    }

    /**
     * 引き算の内部実装
     * @param another  引く数(a-bのときのb)
     * @param dest     結果を返す先
     */<commit_msg>[Fix] small fix LargeInt<commit_after>#ifndef __LARGEINT_H__
#define __LARGEINT_H__

#include <cmath>
#include <initializer_list>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
#include <type_traits>

namespace Euler
{
  template <typename Int_t>
  class LargeInt
  {
  private:
    /** 巨大な整数の内部表現 */
    std::vector<Int_t> num;
    /** 符号 */
    bool is_negative;
    /** 内部値が不正な場合failed == true */
    bool failed;

  public:
    /** 各要素の最大桁数(使用する整数型の最大値の桁数-1; 最大桁でやると計算途中で溢れる可能性がある) */
    static constexpr Int_t MAX_DIGITS = std::log10(std::numeric_limits<Int_t>::max());
    static constexpr Int_t LIMIT_PER_TERMS = std::pow(10, MAX_DIGITS - 1);

  public:  // コンストラクタ
    /**
     * 普通のInt_tから生成
     * @param init 初期値
     */
    LargeInt(Int_t init)
      : is_negative(init < 0),
        failed(false)
    {
      num.push_back(init < 0 ? -init : init);
    }

    /**
     * 値を表現する数値列から生成
     * ex) 12345 -> {1,2,3,4,5}
     * @param  vec 初期値を表す数値列
     */
    LargeInt(const std::initializer_list<Int_t>& vec)
      : is_negative(false),
        failed(false)
    {
      Int_t n = 0;
      const auto size = vec.size();
      using SizeType = typename std::remove_const<decltype(size)>::type;
      if (size > 0) {
        num.reserve(static_cast<SizeType>(std::log10(size) + 1) / (MAX_DIGITS - 1));
      }

      for (SizeType i = 0; i < size; i++) {
        if (*(vec.end() - i - 1) > 9) {
          failed = true;
          return;
        }
        if ((i > 0 && i + 1 < size && i % (MAX_DIGITS - 1) == 0)) {
          num.push_back(n);
          n = 0;
        }
        n += std::pow(10, i % (MAX_DIGITS - 1)) * (*(vec.end() - i - 1));
      }
      num.push_back(n);
    }

    /**
     * コピーコンストラクタ
     */
    LargeInt(const LargeInt<Int_t>& src)
    noexcept
    {
      *this = src;
    }

    /**
     * ムーブコンストラクタ
     */
    LargeInt(LargeInt<Int_t>&& src)
    noexcept
    {
      *this = std::move(src);
    }

  private:
    /**
     * 生成に失敗したオブジェクトを使っていないかチェック
     */
    inline
    void check_availability() const
    {
      if (failed) {
        throw std::runtime_error("cannot use a \'failed\' LargeInt object");
      }
    }

  private:
    /**
     * 足し算の内部実装
     * @param another  足す数(a+bのときのb)
     * @param dest     結果を返す先
     */
    void add_impl(const LargeInt<Int_t>& another, LargeInt<Int_t>* dest)
    const
    {
      check_availability();
      another.check_availability();
      const auto another_size = another.num.size();
      if (dest->num.size() < another_size) {
        dest->num.resize(another_size, 0);
      }
      const auto size = dest->num.size();
      using SizeType = typename std::remove_const<decltype(size)>::type;

      for (SizeType i = 0; i < size; i++) {
        if (i >= another_size) {
          break;
        }
        dest->num.at(i) += another.num.at(i);
        // 要素を跨ぐ繰り上げ
        auto n = i;
        while (dest->num.at(n) >= LIMIT_PER_TERMS) {
          dest->num.at(n) -= LIMIT_PER_TERMS;
          n++;
          if (n < size) {
            dest->num.at(n)++;
          }
          else {
            dest->num.push_back(1);
            break;
          }
        }
      }
    }

    /**
     * 引き算の内部実装
     * @param another  引く数(a-bのときのb)
     * @param dest     結果を返す先
     */
{'fraction_non_alphanumeric': 0.14953271028037382, 'fraction_numerical': 0.011908350919505577, 'mean_word_length': 1.869809688581315, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5466249', 'n_tokens_mistral': 2756, 'n_tokens_neox': 2661, 'n_words': 472}