そろばん風表現
そろばん ー 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; } } }