Created
September 24, 2014 14:44
-
-
Save kuuso/6754d9321b5e1fe1d408 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Collections; | |
using System.Collections.Generic; | |
class TEST{ | |
static void Main(){ | |
String InputFile="./data.utf8.txt"; | |
StreamReader SR=new StreamReader(InputFile); | |
//Stream stdin=Console.OpenStandardInput(); | |
//StreamReader SR=new StreamReader(stdin); | |
String s=""; | |
List<String> L=new List<String>(); | |
while(!String.IsNullOrEmpty(s=SR.ReadLine())){ | |
var ss=s.Split('\t'); | |
Sol mySol =new Sol(ss); | |
bool chk=mySol.Solve(); | |
if(!chk)L.Add(ss[0]); | |
} | |
Console.WriteLine(""); | |
Console.WriteLine("Answer--result does not match with expectation -Total {0}",L.Count); | |
for(int i=0;i<L.Count;i++){ | |
Console.Write(i==0?"{0}":",{0}",L[i]); | |
} | |
Console.WriteLine(""); | |
} | |
} | |
class Sol{ | |
public bool Solve(){ | |
MakeUnitTable(); | |
/* if(Ans(eq1)!=Ans(eq2)){ | |
Console.WriteLine("Case:{0}",idx); | |
Console.WriteLine("\teq1: {0} \n\t\tans={1}",eq1,Ans(eq1)); | |
Console.WriteLine("\teq2: {0} \n\t\tans={1}",eq2,Ans(eq2)); | |
} | |
*/ | |
return Ans(eq1)==Ans(eq2); | |
} | |
Dictionary<String,long> unit; | |
void MakeUnitTable(){ | |
unit=new Dictionary<String,long>(); | |
//長さ:mm基準 | |
unit["mm"]=1; | |
unit["cm"]=10; | |
unit["m"]=1000; | |
unit["km"]=1000*1000; | |
//重さ:mg基準 | |
unit["mg"]=1; | |
unit["g"]=1000; | |
unit["kg"]=1000*1000; | |
//時間:秒基準 | |
unit["秒"]=1; | |
unit["分"]=60; | |
unit["時間"]=60*60; | |
unit["日"]=24*unit["時間"]; | |
} | |
long Ans(String equ){ | |
//□のある辺を左辺に | |
var s=equ.Split('='); | |
if(s[0].IndexOf('□')==-1){ | |
String tmp=s[0];s[0]=s[1];s[1]=tmp; | |
} | |
String left=s[0]; | |
String right=s[1]; | |
//□とその単位の位置を調べる。符号(あれば)を含める。 | |
int strt=left.IndexOf('□'); | |
int len=0; | |
while(strt+len<left.Length && left[strt+len]>'9')len++; | |
if(strt>0 && (left[strt-1]=='-'||left[strt-1]=='+')){ | |
strt--; | |
len++; | |
} | |
//Console.WriteLine("left:\t{0}",left); | |
//Console.WriteLine(" :\t{0},Eval={1}",left.Substring(0,strt),Eval(left.Substring(0,strt))); | |
//Console.WriteLine(" :\t{0}",left.Substring(strt,len)); | |
//Console.WriteLine(" :\t{0},Eval={1}",left.Substring(strt+len),Eval(left.Substring(strt+len))); | |
//Console.WriteLine("right:\t{0},Eval={1}",right,Eval(right)); | |
//□の項以外を右辺に移項し計算後、□の単位・符号で割り算 | |
long ret=Eval(right)-Eval(left.Substring(0,strt))-Eval(left.Substring(strt+len)); | |
left=left.Substring(strt,len); | |
if(left[0]=='-')ret/=-1; | |
ret/=unit[left.Substring(left.IndexOf('□')+1)]; | |
return ret; | |
} | |
long Eval(String expr){ | |
if(expr=="")return 0; | |
long ret=0; | |
String s=expr; | |
// -xx時間yy分zz秒 のようなケースのパースのため、符号をsigで覚えておく。 | |
long sig=1; | |
while(s!=""){ | |
//各項ごとに値を計算。('+'と'-'のasciiコードは数字より若い) | |
bool flg=false; | |
for(int i=0;i<s.Length;i++){ | |
if(i==0){ | |
if(s[0]=='-')sig=-1; | |
if(s[0]=='+')sig=1; | |
} | |
if(!flg && s[i]<='9'){ | |
continue; | |
} | |
if(s[i]>'9'){ | |
flg=true; | |
if(i!=s.Length-1)continue; | |
} | |
if((flg && (s[i]<='9')) || i==s.Length-1){ | |
if(i==s.Length-1)i++; | |
var t=s.Substring(0,i); | |
long val=ParseWithUnit(t); | |
if(t[0]!='-'&&t[0]!='+'){ | |
val*=sig; | |
} | |
s=s.Substring(i); | |
ret+=val; | |
break; | |
} | |
} | |
} | |
return ret; | |
} | |
long ParseWithUnit(String expr){ | |
int cnt=0; | |
while(expr[cnt]<='9')cnt++; | |
long val=long.Parse(expr.Substring(0,cnt)); | |
val*=unit[expr.Substring(cnt)]; | |
return val; | |
} | |
String idx; | |
String eq1; | |
String eq2; | |
public Sol(String[] ss_){ | |
//コンストラクタ:入力データはフィールドで保持。 | |
idx=ss_[0]; | |
eq1=ss_[1]; | |
eq2=ss_[2]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
【解答】 | |
111,112,222,223,333,334,444,445,555,556,666,667,777,778,888,889,999 | |
【コード概要】 | |
・まず与えられた式を | |
expr1+□+expr2=expr3 の形に変形し、expr1,expr2,expr3を評価して□を計算します。 | |
・各exprの評価は、例えば | |
3m20cm-3m10cm-□mm=5mm なら | |
+3m +20cm -3m -10cm -□mm = +5mm と読み替え。 | |
⇒ expr1="+3m +20cm -3m -10cm" | |
expr2="" | |
expr3="+5mm" | |
こういう単位で分けます。符号については、文字列に加えるのではなくてparseの際に前後の文脈で判断します。 | |
・単位は基準単位の何倍か、という数値を事前にテーブル化しておいてparseします。 | |
今回は整数演算になるよう、最小単位を1にそろえています。 | |
・詰め切れず、こういう問題が解けない実装になっています。。 | |
2500g-1kg□g80mg=1300g20mg ←これは不正解する | |
2500g+1kg□g20mg=4000g20mg ←これは正解する | |
(こういうケースがないことは一応確認しましたが) | |
あとかっこ算もないので、再帰のくだりも省略しています。 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment