• トップページ
  • project
    • 全ての作品
    • 全てのタグ
  • blog
    • 全ての記事
    • 全てのタグ
  • tag
    • 全てのタグ
    • 全ての作品タグ
    • 全ての記事タグ
  • about
    • p進大好きサークル photo

      p進大好きサークル

      p進大好きサークルのHPです。

    • もっと読む
    • Twitter
    • pixiv
    • 巨大数Wiki

機能和声の実装 - 変化記号

2020/01/13

トップページ 前の記事 親記事 次の記事

twitter pixiv yukicoder お題箱 マシュマロ

数式での翻訳

\(n \in \mathbb{N} \setminus \{0\}\)に対し、記号\(\textrm{♭}\)および\(\textrm{♯}\)のみからなる長さ\(n\)の文字列をそれぞれ\(\textrm{♭}^n\)と\(\textrm{♯}^n\)で表し、空文字列を\(\textrm{□}\)と置きます。記号\(\textrm{♭}\)と\(\textrm{♯}\)のみからなる文字列の集合 \[ \textrm{HenKaKiGou} = \{\textrm{♭}^n \mid n \in \mathbb{N} \setminus \{0\}\} \cup \{\textrm{□}\} \cup \{\textrm{♯}^n \mid n \in \mathbb{N} \setminus \{0\}\} \] に属する文字列を変化記号と呼びます。定義から、変化記号には可算無限種類の文字列があります。例えば\(\textrm{♭}\textrm{♭}\)や\(\textrm{♯}\textrm{♯}\textrm{♯}\)は変化記号ですが、\(\textrm{♭}\textrm{♯}\)や\(\textrm{♯}\textrm{♭}\)は変化記号ではありません。完全に公理的集合論で定義をしたい場合は、記号を以下の規則で自然数にコードすることで、\(\mathbb{N}\)を記号の集合とする文字列の集合に翻訳して下さい。 \[ \begin{align} \textrm{♭} & := 0 \\
\textrm{♯} & := 1 \end{align} \] 通常の流儀では空文字列を変化記号と呼ぶことはしないと思いますが、今回は実装の便宜上空文字列を変化記号とみなしています。また流儀によっては\(\textrm{??}\)(環境によっては正しく表示できません)や\(\textrm{?}\)や\(\textrm{??}\)(環境によっては正しく表示できません)を変化記号として用いますが、ここではそれらを用いません。

また写像 \[ \begin{align} \textrm{GetNum} \colon \textrm{HenKaKiGou} & \to \mathbb{Z} \\
S & \mapsto \textrm{GetNum}(S) \end{align} \] を以下のように定めます:

  1. \(S = \textrm{♭}^n\)を満たす\(n \in \mathbb{N} \setminus \{0\}\)が存在するならば、\(\textrm{GetNum}(S) = -n\)である。
  2. \(S = \textrm{□}\)ならば、\(\textrm{GetNum}(S) = 0\)である。
  3. \(S = \textrm{♯}^n\)を満たす\(n \in \mathbb{N} \setminus \{0\}\)が存在するならば、\(\textrm{GetNum}(S) = n\)である。

この写像\(\textrm{GetNum} \colon \textrm{HenKaKiGou} \to \mathbb{Z}\)は全単射であるので、これを通じて\(\textrm{HenKaKiGou}\)に環構造を誘導します。ちなみに幹音の記事において定義した写像\(\textrm{KanOn} \to \mathbb{Z}/7 \mathbb{Z}\)もまた\(\textrm{GetNum}\)と表していましたが、\(\textrm{KanOn} \cap \textrm{HenKaKiGou} = \emptyset\)であるため、このような記法の重複による曖昧さはあまり問題を起こしません。このように記法を重複させることをオーバーロードと言い、数学において曖昧さが致命的でない範囲で断りなく多用されるものですので、今後も断りなく使っていきます。

C++での宣言

変化記号のクラスおよび関係する関数たちを以下のように宣言します。


class HenKaKiGou
{

private:
  int m_num;

public:
  inline HenKaKiGou( const int& num ) noexcept;

  HenKaKiGou& operator++() noexcept;
  HenKaKiGou& operator--() noexcept;
  
  inline string Display() const noexcept;
  inline const int& GetNum() const noexcept;

  static string IntToString( const int& num ) noexcept;

};

inline bool operator==( const HenKaKiGou& S1 , const HenKaKiGou& S2 ) noexcept;
inline bool operator!=( const HenKaKiGou& S1 , const HenKaKiGou& S2 ) noexcept;

inline HenKaKiGou operator+( const HenKaKiGou& S1 , const HenKaKiGou& S2 ) noexcept;
inline HenKaKiGou operator-( const HenKaKiGou& S1 , const HenKaKiGou& S2 ) noexcept;

C++での定義

実際の実装例についてはこちらをご覧下さい。実装においては以下の仕様を要請します。

  • inline HenKaKiGou::HenKaKiGou( const int& num ) noexceptはメンバ初期化子リストm_S( IntToString( num ) ) , m_num( num )で定める。
  • HenKaKiGou& HenKaKiGou::operator++() noexceptとHenKaKiGou& HenKaKiGou::operator--() noexceptはそれぞれm_num += 1とm_num -= 1を実行し、return *thisと定める。
  • inline string HenKaKiGou::Display() const noexceptはreturn IntToString( m_num )と定める。
  • inline const int& HenKaKiGou::GetNum() const noexceptはreturn m_numと定める。
  • static string HenKaKiGou::IntToString( const int& num )はnum == 0ならば空文字列を、num > 0ならば"♯"のみからなる長さ-numの文字列を、num < -1ならば"♭"のみからなる長さnumの文字列を返す。
  • クラスHenKaKiGouに対する等号演算子は自然なものである。
  • クラスHenKaKiGouに対する加法演算子と減法演算子は、HenKaKiGou::GetNum()が加法演算子と減法演算子と可換になるように定める。
トップページ 前の記事 親記事 次の記事

twitter pixiv yukicoder お題箱 マシュマロ