結果

問題 No.708 (+ー)の式
ユーザー AreTrash
提出日時 2019-04-28 02:41:44
言語 C#(csc)
(csc 3.9.0)
結果
AC  
実行時間 32 ms / 2,000 ms
コード長 8,749 bytes
コンパイル時間 1,030 ms
コンパイル使用メモリ 109,568 KB
実行使用メモリ 19,712 KB
最終ジャッジ日時 2024-11-30 14:03:42
合計ジャッジ時間 2,308 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 12
権限があれば一括ダウンロードができます
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc)
Copyright (C) Microsoft Corporation. All rights reserved.

ソースコード

diff #
プレゼンテーションモードにする

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace No708
{
public class Program
{
static void Main(string[] args)
{
var syntax = new Syntax(Console.ReadLine());
var expression = new Expression();
expression.Parse(syntax);
var res = expression.Calc();
Console.WriteLine(res);
}
}
public class Syntax
{
readonly string expression;
int prev = -1;
int index = 0;
public char Previous => prev < 0 ? '\0' : expression[prev];
public char Current => index >= expression.Length ? '\0' : expression[index];
public Syntax(string expression)
{
this.expression = expression;
}
public void Next()
{
prev = index;
do index++;
while (Current == ' ');
}
}
public abstract class Node
{
Syntax syntax;
readonly List<Node> nodes = new List<Node>();
protected IReadOnlyList<Node> Nodes => nodes;
protected void Add(Node node)
{
node.Parse(syntax);
nodes.Add(node);
}
protected abstract void ParseCore(Syntax syntax);
// ReSharper disable once ParameterHidesMember
public void Parse(Syntax syntax)
{
nodes.Clear();
ParseCore(this.syntax = syntax);
}
public abstract double Calc();
}
public class Letter : Node
{
string letter;
protected override void ParseCore(Syntax syntax)
{
letter = syntax.Current.ToString();
syntax.Next();
}
public override double Calc()
{
throw new Exception("LetterNode");
}
public override string ToString()
{
return letter;
}
}
public class Number : Node
{
//<number> ::= ('0'-'9') {'0'-'9'} ['.'{'0'-'9'}]
protected override void ParseCore(Syntax syntax)
{
var dots = 0;
if (!char.IsDigit(syntax.Current)) throw new Exception("NumberNode");
while (char.IsDigit(syntax.Current) || (syntax.Current == '.' && ++dots <= 1)) Add(new Letter());
}
public override double Calc()
{
return double.Parse(ToString());
}
public override string ToString()
{
return string.Join("", Nodes);
}
}
public class Bracket : Node
{
//<bracket> ::= '(' <expression> ')'
protected override void ParseCore(Syntax syntax)
{
if (syntax.Current != '(') throw new Exception("BracketNode");
Add(new Letter());
Add(new Expression());
if (syntax.Current != ')') throw new Exception("BracketNode");
Add(new Letter());
}
public override double Calc()
{
return Nodes[1].Calc();
}
public override string ToString()
{
return string.Join("", Nodes);
}
}
public class Factor : Node
{
bool isNegative = false;
//<factor> ::= (<number>|<bracket>)
protected override void ParseCore(Syntax syntax)
{
if (syntax.Current == '-')
{
if (syntax.Previous != '\0' && syntax.Previous != '(') throw new Exception("");
isNegative = true;
Add(new Letter());
}
if (char.IsDigit(syntax.Current)) Add(new Number());
else if (syntax.Current == '(') Add(new Bracket());
else throw new Exception("FactorNode NumberNode BracketNode ");
}
public override double Calc()
{
return (isNegative ? -1 : 1) * Nodes.Last().Calc();
}
public override string ToString()
{
return string.Join("", Nodes);
}
}
public class SquareRoot : Node
{
//<root> ::= {'r'} <factor>
protected override void ParseCore(Syntax syntax)
{
while (syntax.Current == 'r') Add(new Letter());
Add(new Factor());
}
public override double Calc()
{
var x = Nodes.Last().Calc();
if (Nodes.Count == 1) return x;
if (x < 0) throw new Exception("");
for (var i = 0; i < Nodes.Count - 1; i++) x = Math.Sqrt(x);
return x;
}
public override string ToString()
{
return string.Join("", Nodes);
}
}
public class Factorial : Node
{
//<factorial> ::= <square_root> {'!'}
protected override void ParseCore(Syntax syntax)
{
Add(new SquareRoot());
while (syntax.Current == '!') Add(new Letter());
}
public override double Calc()
{
var d = Nodes.First().Calc();
var x = (int)Math.Round(d);
if (Nodes.Count == 1) return d;
if (Math.Abs(d - x) > double.Epsilon || x < 0) throw new Exception("0");
if (x == 0) return 1;
for (var i = 0; i < Nodes.Count - 1; i++)
{
for (var y = x - 1; y >= 2; y--) x *= y;
}
return x;
}
public override string ToString()
{
return string.Join("", Nodes);
}
}
public class Power : Node
{
//<power> ::= <factorial> {'^' <factorial>}
protected override void ParseCore(Syntax syntax)
{
Add(new Factorial());
while (syntax.Current == '^')
{
Add(new Letter());
Add(new Factorial());
}
}
public override double Calc()
{
var x = Nodes[0].Calc();
for (var i = 2; i < Nodes.Count; i += 2)
{
var y = Nodes[i].Calc();
x = Math.Pow(x, y);
}
return x;
}
public override string ToString()
{
return string.Join(" ", Nodes);
}
}
public class MulDiv : Node
{
//<mul_div> ::= <power> {('*'|'/') <power>}
protected override void ParseCore(Syntax syntax)
{
Add(new Power());
while (syntax.Current == '*' || syntax.Current == '/')
{
Add(new Letter());
Add(new Power());
}
}
public override double Calc()
{
var x = Nodes[0].Calc();
for (var i = 2; i < Nodes.Count; i += 2)
{
var op = Nodes[i - 1].ToString();
var y = Nodes[i].Calc();
if (op == "*") x *= y;
if (op == "/") x /= y;
}
return x;
}
public override string ToString()
{
return string.Join(" ", Nodes);
}
}
public class AddSub : Node
{
//<add_sub> ::= <mul_div> {('+'|'-') <mul_div>}
protected override void ParseCore(Syntax syntax)
{
Add(new MulDiv());
while (syntax.Current == '+' || syntax.Current == '-')
{
Add(new Letter());
Add(new MulDiv());
}
}
public override double Calc()
{
var x = Nodes[0].Calc();
for (var i = 2; i < Nodes.Count; i += 2)
{
var op = Nodes[i - 1].ToString();
var y = Nodes[i].Calc();
if (op == "+") x += y;
if (op == "-") x -= y;
}
return x;
}
public override string ToString()
{
return string.Join(" ", Nodes);
}
}
public class Expression : Node
{
//<expression> ::= <add_sub>
protected override void ParseCore(Syntax syntax)
{
Add(new AddSub());
}
public override double Calc()
{
return Nodes.Last().Calc();
}
public override string ToString()
{
return string.Join("", Nodes);
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0