プログラム問題集

プログラム問題集

多分プログラミングの問題集でも書いていく

そろばん風表現

そろばん ー Computer History Museumそろばん ー Computer History Museum / nyanchew

問題

 入力された値 n をそろばん風に表現してください。


・100000 > n ≧ 0
・n > 100000 の時は100000を表示する
・長くて小数点以下3桁まで(小数点以下4桁切り捨て)表示する
・1の位を表現する定位点は*、その他の定位点は・を使用する

例1

>7.00








例2

>40972.331
〇〇||〇〇〇〇
||〇〇||||
―・――*――・
〇|〇〇〇〇〇〇
〇〇〇〇〇〇〇|
〇〇〇||〇〇〇
〇〇〇〇〇||〇
|〇|〇〇〇〇〇

解答例

Program.cs

using System;

namespace soroban1
{
    class Program
    {
        static void Main(string[] args)
        {
            Soroban sb = new Soroban();
            sb.Number = Read();
            sb.Draw();
            Console.ReadKey();
        }

        static double Read()
        {
            return double.Parse(Console.ReadLine());
        }
    }
}


Soroban.cs

using System;
using System.Linq;

namespace soroban1
{
    class Soroban
    {
        /// <summary>
        /// 保持する値
        /// </summary>
        private double number;
        public double Number
        {
            protected get { return this.number; }
            set { SetNumber(ref this.number, value); }
        }

        /// <summary>
        /// 値の保存とそろばんのセット
        /// </summary>
        /// <param name="number">保存する値</param>
        /// <param name="value">入力値</param>
        private void SetNumber(ref double number, double value)
        {
            number = this.CheckNumber(value);
            this.SetState();
        }

        /// <summary>
        /// そろばんの状態
        /// </summary>
        private char[,] state;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public Soroban()
        {

        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="n"></param>
        public Soroban(double n)
        {
            this.SetNumber(ref number, n);
        }

        /// <summary>
        /// コンソールに描画する
        /// </summary>
        public void Draw()
        {
            for (int y = 0; y < state.GetLength(1); y++)
            {
                for (int x = 0; x < state.GetLength(0); x++)
                {
                    Console.Write(state[x, y]);
                }
                Console.Write(Environment.NewLine);
            }
        }

        /// <summary>
        /// そろばんの状態を決める
        /// </summary>
        private void SetState()
        {
            string intNum = this.GetIntegerPart();
            string decNum = this.GetDecimalPart();

            this.InitState(intNum.Length + decNum.Length);

            SetAnchorPoint(intNum.Length, decNum.Length);

            SetNumbers(intNum + decNum);
        }

        /// <summary>
        /// 珠の状態を決定する
        /// </summary>
        /// <param name="num">数値</param>
        private void SetNumbers(string num)
        {
            for (int i = 0; i < num.Length; i++)
            {
                int n = num[i] - '0';

                if (n >= 5)
                {
                    state[i, 0] = '|';
                    n = n - 5;
                }
                else
                {
                    state[i, 1] = '|';
                }

                state[i, 3 + n] = '|';
            }
        }

        /// <summary>
        /// 定位点を設置する
        /// </summary>
        /// <param name="intNum"></param>
        private void SetAnchorPoint(int intLength, int decLength)
        {
            //第一位桁の定位点を設置する
            this.state[intLength - 1, 2] = '*';

            //整数側の定位点
            if (intLength > 3)
            {
                for (int x = (intLength - 1) / 3; x > 0; x--)
                {
                    this.state[intLength - 1 - 3 * x, 2] = '・';
                }
            }

            //少数側の定位点
            if (decLength == 3)
            {
                this.state[this.state.GetLength(0) - 1, 2] = '・';
            }
        }

        /// <summary>
        /// そろばんを初期(珠で埋める)状態にする
        /// </summary>
        /// <param name="digits">必要桁数</param>
        private void InitState(int digits)
        {
            state = new char[digits, 8];

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < digits; x++)
                {
                    if (y == 2) state[x, y] = '―';
                    else state[x, y] = '〇';
                }
            }
        }

        /// <summary>
        /// 整数部分の取り出し
        /// </summary>
        /// <returns>整数部分</returns>
        private string GetIntegerPart()
        {
            return ((int)this.number).ToString();
        }

        /// <summary>
        /// 小数部分の取り出し
        /// </summary>
        /// <returns>小数部分</returns>
        private string GetDecimalPart()
        {
            string str = this.number.ToString();

            if (str.Contains('.') == false) return string.Empty;

            return str.Split('.')[1].Substring(0, 3);
        }

        /// <summary>
        /// 値のチェック
        /// </summary>
        /// <returns></returns>
        private double CheckNumber(double n)
        {
            if (n > 100000.0) return 100000;
            if (n < 0.0) return 0;

            return n;
        }
    }
}