#はじめに
今回はマヤ数字についてお話していきます。
#マヤ数字とは
(マヤ文字って美しいですよね)
マヤ数字とはマヤ文明で使われていた数字です。
私たちが一般に使っているのは、
10個の記号を使って数字を表す**"十進法"**ですが
(10個の記号: 0123456789)
マヤ数字は
20個の記号を使って数字を表す**"二十進法"**なんです!
(20個の記号: 𝋠𝋡𝋢𝋤𝋥𝋦𝋧𝋨𝋩𝋪𝋪𝋫𝋬𝋭𝋮𝋯𝋰𝋱𝋲𝋳)
※比較的最新の環境でないと上記のマヤ数字がみられません。
もっと詳細にいうと
"十進法"は10 を底とし、底およびその冪を基準にして数を表す方法
"二十進法"は20 を底とし、底およびその冪を基準にして数を表す方法
です。
マヤ数字のすごいところは**"0"を表す記号があることですね。
古代から数字を発明し、暦の計算に使っていたマヤ人**はすごいです。
横棒は5ずつ増えます。
#数値からマヤ数字へ変換
#pragma once
#include <iostream>
#include <vector>
namespace maya {
//通常の数字をマヤ数字に変換する
template <typename NormalNum, typename MayaNum>
void mayaNumber(NormalNum num_, std::vector<MayaNum>& maya_num_) {
//各位の上限値
constexpr NormalNum num_20 = (NormalNum)20;
constexpr NormalNum num_18 = (NormalNum)18;
constexpr NormalNum num_0 = (NormalNum)0;
//要素を消去
maya_num_.clear();
//元の数字が0以下の場合
if (num_ <= num_0) {
maya_num_.emplace_back((MayaNum)0);
return;
}
//1桁目を選定 (0~19)
maya_num_.emplace_back((MayaNum)(num_ % num_20));
if ((num_ /= num_20) == 0) return;
//2桁目を選定 (0~17)
maya_num_.emplace_back((MayaNum)(num_ % num_18));
if ((num_ /= num_18) == 0) return;
//3桁目以降を選定 (0~19)
while (true) {
maya_num_.emplace_back((MayaNum)(num_ % num_20));
if ((num_ /= num_20) == 0) return;
}
}
template <typename MayaNum>
void mayaNumber(const float num_, std::vector<MayaNum>& maya_num_) {
mayaNumber((unsigned long long)num_, maya_num_);
}
template <typename MayaNum>
void mayaNumber(const double num_, std::vector<MayaNum>& maya_num_) {
mayaNumber((unsigned long long)num_, maya_num_);
}
template <typename MayaNum>
void mayaNumber(const long double num_, std::vector<MayaNum>& maya_num_) {
mayaNumber((unsigned long long)num_, maya_num_);
}
//マヤ数字を出力する
template <typename MayaNum>
void mayaNumberOutput(const std::vector<MayaNum>& maya_num_) {
for (size_t i = 0; i < maya_num_.size(); ++i)
std::cout << maya_num_[i] << ',';
}
template <>
void mayaNumberOutput(const std::vector<unsigned char>& maya_num_) {
for (size_t i = 0; i < maya_num_.size(); ++i)
std::cout << (int)maya_num_[i] << ',';
}
template <>
void mayaNumberOutput(const std::vector<signed char>& maya_num_) {
for (size_t i = 0; i < maya_num_.size(); ++i)
std::cout << (int)maya_num_[i] << ',';
}
//通常の数字をマヤ数字に変換して出力する
template <typename NormalNum, typename MayaNum>
void mayaNumberOutput(const NormalNum& num_, std::vector<MayaNum>& maya_num_) {
mayaNumber(num_, maya_num_);
mayaNumberOutput(maya_num_);
}
//通常の数字をマヤ数字に変換して出力する
template <typename NormalNum>
void mayaNumberOutput(const NormalNum& num_) {
std::vector<unsigned char> maya_num_;
mayaNumber(num_, maya_num_);
mayaNumberOutput(maya_num_);
}
}
まずは手始めにプログラミングしてみました。
###原理
マヤ数字は20進法なので**"mayaNumber()"**で20進法へ変換します。
ただし、ここで注意点があります。
マヤ数字の下から2桁目は17までしかありません。
つまり下から2桁目が最上位になる正の数は20~359です。(20~399ではありません)
おそらくこの仕様は暦の計算がしやすくなるよう1年の長さ(365日)に近くなるように
考えられたからではないかと思います。
###出力
#include <MayaGlyph.hpp>
int main() {
maya::mayaNumberOutput(100);
return 0;
}
0,5,
16,0,2,9,
これでデータ上ではマヤ数字の生成ができました!
#マヤ数字を画像として出力する
楽に画像を出力するため、DxLibを使用してコードを書いていきます。
#include <cstdint>
#include <string>
#include <MayaGlyph.hpp>
#include <DxLib.h>
int main()
{
//マヤ数字を生成
std::uint64_t num{};
std::cin >> num;
std::vector<size_t> maya_num;
maya::mayaNumber(num, maya_num);
if (maya_num.size() < 2) return 0;
DxLib::SetOutApplicationLogValidFlag(0);
DxLib::ChangeWindowMode(1);
DxLib::SetGraphMode(1, 1, 32);
if (DxLib::DxLib_Init() == -1) return -1;
//数字の画像を読み込む
constexpr size_t array_num = 20;
int num_texture[array_num];
for (size_t i = 0; i < array_num; ++i)
num_texture[i] = DxLib::LoadGraph(std::string(std::to_string(i) + ".png").c_str(), 1);
//画像サイズを元に作成する画像のサイズを決める
int size_x, size_y;
if (DxLib::GetGraphSize(num_texture[0], &size_x, &size_y) == -1) return -1;
const int window_size_y = size_y * (int)maya_num.size();
int screen = DxLib::MakeScreen(size_x, window_size_y, 1);
DxLib::SetDrawScreen(screen);
DxLib::ClearDrawScreen();
for (size_t i = 0; i < maya_num.size(); ++i)
DxLib::DrawExtendGraph(0, window_size_y - (size_y*(int)i + size_y), size_x, window_size_y - size_y * (int)i, num_texture[maya_num[i]], 1);
//PNG形式で画像保存
DxLib::SaveDrawScreenToPNG(0, 0, size_x, size_y*(int)maya_num.size(), std::string(std::to_string(num) + ".png").c_str(), 0);
//終了処理
DxLib::DxLib_End();
return 0;
}
##使用例
###"360"のマヤ数字
###"65536"のマヤ数字
###"1000000000000"(1兆)のマヤ数字
###"10000000000000000"(1京)のマヤ数字
手書きのマヤ数字を出力してみました。
#結論
マヤ数字っておもしろい!
##ソースコードのライセンス