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

      p進大好きサークル

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

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

機能和声の実装 - 幹音

2020/01/12

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

twitter pixiv yukicoder お題箱 マシュマロ

数式での翻訳

英語のアルファベットを記号とする文字列の集合 \[ \textrm{KanOn} = \{\textrm{Do},\textrm{Re},\textrm{Mi},\textrm{Fa},\textrm{So},\textrm{La},\textrm{Ti}\} \] に属する文字列を幹音と呼びます。定義から、幹音にはちょうど\(7\)種類の文字列があります。完全に公理的集合論で定義をしたい場合は、英語のアルファベットを以下の規則で自然数にコードすることで、\(\mathbb{N}\)を記号の集合とする文字列の集合に翻訳して下さい。 \[ \begin{align} \textrm{A} & := 0 \\
\textrm{B} & := 1 \\
\textrm{C} & := 2 \\
\textrm{D} & := 3 \\
\textrm{E} & := 4 \\
\textrm{F} & := 5 \\
\textrm{G} & := 6 \\
\textrm{H} & := 7 \\
\textrm{I} & := 8 \\
\textrm{J} & := 9 \\
\textrm{K} & := 10 \\
\textrm{L} & := 11 \\
\textrm{M} & := 12 \\
\textrm{N} & := 13 \\
\textrm{O} & := 14 \\
\textrm{P} & := 15 \\
\textrm{Q} & := 16 \\
\textrm{R} & := 17 \\
\textrm{S} & := 18 \\
\textrm{T} & := 19 \\
\textrm{U} & := 20 \\
\textrm{V} & := 21 \\
\textrm{W} & := 22 \\
\textrm{X} & := 23 \\
\textrm{Y} & := 24 \\
\textrm{Z} & := 25 \\
\textrm{a} & := 26 \\
\textrm{b} & := 27 \\
\textrm{c} & := 28 \\
\textrm{d} & := 29 \\
\textrm{e} & := 30 \\
\textrm{f} & := 31 \\
\textrm{g} & := 32 \\
\textrm{h} & := 33 \\
\textrm{i} & := 34 \\
\textrm{j} & := 35 \\
\textrm{k} & := 36 \\
\textrm{l} & := 37 \\
\textrm{m} & := 38 \\
\textrm{n} & := 39 \\
\textrm{o} & := 40 \\
\textrm{p} & := 41 \\
\textrm{q} & := 42 \\
\textrm{r} & := 43 \\
\textrm{s} & := 44 \\
\textrm{t} & := 45 \\
\textrm{u} & := 46 \\
\textrm{v} & := 47 \\
\textrm{w} & := 48 \\
\textrm{x} & := 49 \\
\textrm{y} & := 50 \\
\textrm{z} & := 51 \end{align} \] ただし集合\(X\)を記号の集合とする文字列というのは、写像\(f\)であって以下の条件を満たすもののことです:

  1. ある\(n \in \mathbb{N}\)が存在し、\(f\)の定義域が\(\{i \in \mathbb{N} \mid i \lneq n\}\)である。
  2. \(f\)の終域が\(X\)である。

特にこの流儀では空列も文字列となりますが、今回は長さ\(2\)の文字列しか扱っていないため空列の扱いを気にする必要はありません。また写像 \[ \begin{align} \textrm{GetNum} \colon \textrm{KanOn} & \to \mathbb{Z}/7 \mathbb{Z} \\
N & \mapsto \textrm{GetNum}(N) \end{align} \] を以下のように定めます:

  1. \(N = \textrm{Do}\)ならば、\(\textrm{GetNum}(N) = 0\)である。
  2. \(N = \textrm{Re}\)ならば、\(\textrm{GetNum}(N) = 1\)である。
  3. \(N = \textrm{Mi}\)ならば、\(\textrm{GetNum}(N) = 2\)である。
  4. \(N = \textrm{Fa}\)ならば、\(\textrm{GetNum}(N) = 3\)である。
  5. \(N = \textrm{So}\)ならば、\(\textrm{GetNum}(N) = 4\)である。
  6. \(N = \textrm{La}\)ならば、\(\textrm{GetNum}(N) = 5\)である。
  7. \(N = \textrm{Ti}\)ならば、\(\textrm{GetNum}(N) = 6\)である。

この写像\(\textrm{GetNum} \colon \textrm{KanOn} \to \mathbb{Z}/7 \mathbb{Z}\)は全単射であるため、これを通じて\(\textrm{KanOn}\)に環構造を誘導します。ただし\(\textrm{GetNum}\)の定義において、\(n \in \mathbb{Z}\)の\(\mathbb{Z}/7 \mathbb{Z}\)での像\(n + 7 \mathbb{Z}\)もまた\(n\)と略記しました。一般に、環\(R\)に対して一意な環準同型\(\mathbb{Z} \to R\)による\(n \in \mathbb{Z}\)の像もまた\(n\)と略記します。このような略記は数学において曖昧さが致命的でない範囲で断りなく多用されるものですので、今後も断りなく使っていきます。

また各\(M \in \mathbb{Z}\)に対し写像 \[ \begin{align} \textrm{Represent} \colon \mathbb{Z}/M \mathbb{Z} & \to \{n \in \mathbb{N} \mid n < M\} \\
n & \mapsto \textrm{Represent}(n) \end{align} \] を代表元を取る写像と定めます。

C++での宣言

\(M \in \mathbb{N} \setminus \{0\}\)に対し、Mod<M>で\(\mathbb{Z}/M \mathbb{Z}\)に相当するクラスを表します。幹音のクラスおよび関係する関数たちを以下のように宣言します。


class KanOn
{

private:
  Mod<7> m_num;

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

  KanOn& operator++() noexcept;
  KanOn& operator--() noexcept;
  
  inline const string& Display() const noexcept;
  inline const Mod<7>& GetNum() const noexcept;
  
  static const string& IntToString( const int& num ) noexcept;
  static inline const string& IntToString( const Mod<7>& num ) noexcept;

};

inline bool operator==( const KanOn& N1 , const KanOn& N2 ) noexcept;
inline bool operator!=( const KanOn& N1 , const KanOn& N2 ) noexcept;

inline const KanOn& operator+( const KanOn& N1 , const Mod<7>& N2 ) noexcept;
inline Mod<7> operator-( const KanOn& N1 , const KanOn& N2 ) noexcept;

const KanOn& Do() noexcept;
const KanOn& Re() noexcept;
const KanOn& Mi() noexcept;
const KanOn& Fa() noexcept;
const KanOn& So() noexcept;
const KanOn& La() noexcept;
const KanOn& Ti() noexcept;
const KanOn& KanOnTable( const int& num ) noexcept;
inline const KanOn& KanOnTable( const Mod<7>& num ) noexcept;


C++での定義

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

  • Mod<n>は通常の環構造に相当する演算子を持つ。
  • Mod<n>は標準射影\(\mathbb{Z} \twoheadrightarrow \mathbb{Z}/n \mathbb{Z}\)に相当するコンストラクタMod<n>::Mod<n>( const int& n )とMod<n>::Mod<n>( const uint& n )を持つ。
  • Mod<n>は完全代表系\(\{i \in \mathbb{N} \mid i \lneq n\}\)の定める切断\(\mathbb{Z}/n \mathbb{Z} \hookrightarrow \mathbb{Z}\)に相当するメンバ関数inline const int& Mod<n>::Represent() const noexceptを持つ。
  • inline KanOn::KanOn( const uint& num )はメンバ初期化子リストm_num( num )で定める。
  • KanOn& KanOn::operator++() noexceptとKanOn& KanOn::operator--() noexceptはそれぞれm_num += 1とm_num -= 1を実行し、return *thisと定める。
  • inline const string& KanOn::Display() const noexceptはreturn IntToString( m_num )と定める。
  • inline const Mod<7>& KanOn::GetNum() const noexceptはreturn m_numと定める。
  • static const string& KanOn::IntToString( const uint& num )は"Do"~"Ti"のうちnum + 1番目の値を返す。
  • static inline const string& KanOn::IntToString( const Mod<7>& num ) noexceptはreturn IntToString( num.Represent() )と定める。
  • クラスKanOnに対する等号演算子は自然なものである。
  • inline const KanOn& operator+( const KanOn& N1 , const Mod<7>& N2 ) noexceptはreturn KanOnTable( N1.GetNum() + N2 )と定める。
  • inline Mod<7> operator-( const KanOn& N1 , const KanOn& N2 ) noexceptはreturn N1.GetNum() - N2.GetNum()と定める。
  • const KanOn& Do() noexcept~const KanOn& Ti() noexceptはconst KanOn型静的局所変数NであってN.Display()の戻り値が関数名自身とメタに等しいような\(\textrm{KanOn}\)の元である文字列であるものへの参照返しである。
  • const KanOn& KanOnTable( const uint& num ) noexceptはDo()~Ti()のうちnum + 1番目の関数の戻り値を返す。
  • inline const KanOn& KanOnTable( const Mod<7>& num ) noexceptはreturn KanOnTable( num.Represent() )と定める。
トップページ 親記事 次の記事

twitter pixiv yukicoder お題箱 マシュマロ