一、背景
在某网站上看到ThoughtWorks在武汉招人,待遇在本地还算不错,就投递了简历。第二天HR就打开电话,基本了解了一下情况(工作环境不错,男人妹子比例:1:1,双休,六险一金,满一年年假15天,病假8天,月薪1W--2W)。然后立马收到一封:Coding Assignment的笔试题目。网上搜索了一下,发现这个公司还是挺大的,公司面试流程是出了名的繁杂和苛刻。据说有8轮:电话面试=》笔试=》Homework=》结对编程(中午管饭)=》技术面试=》PM面试=》HR Manager的面试=》Boss面谈。
了解到武汉这边的主要是做知道华为这样的公司做敏捷开发培训,需要出差,也会有自己公司的一些些代码的需求。这边公司规模也就20几个人。希望对其他想去的童鞋有所帮助。
管它呢,试试再说/本文重点说一下笔试题目,因为我觉得还挺有意思的。
不好意思,刚收到邮件通知,我己经阵亡,说是没有适合我 skills and background 的职位。莫非跟这个题目有关,大家帮我看一下哦。
二、题目:
三个问题任选其一:我就选了第一个”Problem One: Merchant‘s Guide To The Galaxy“,另外两道题有需要的原有找我要。
题干给大家贴出来,下面有中文说明,可跳过。
Symbol |
Value |
I |
1 |
V |
5 |
X |
10 |
L |
50 |
C |
100 |
D |
500 |
M |
1,000 |
可以用:Java, Ruby, or C#, JavaScript.
中文:大意就是我成了地球首富,然后有很多钱,但是地球已经不适合人类居住了,需要跑到银河系去做生意,但是银河系使用的是罗马字母表示钱,所以座位程序员的我打算自己写一个罗马字母和十进制数字互转的小程序,以帮助我做生意。
罗马字母有: I,V,X,L,C,D,M
转换规则:
1. I:可以表示十进制数字1,V:可以表示十进制数字5,X:可以表示十进制数字10,L:可以表示十进制数字50,C:可以表示十进制数字100,D:可以表示十进制数字500,M:可以表示十进制数字1000;
2.I, X, C, and M可以重复出现最多3次;
3.一般是从后往前排列:即MDCLXVI的顺序,当然也允许相邻的两个倒序,但是需要符合以下规则:
I :只能组合IV ,IX
X:只能组合XL,XC
C:只能组合CD,CM
V,L,D不能倒序
大概是这个意思,上周做的,现在大脑还残存这些碎片。
三、我的思路
既然要考察面向对象的编程,就建一个Roman的类表示单个罗马字母,根据转换规则添加一些Property,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RomanNumber { /// <summary> /// A Featured Roman char /// </summary> public class Roman { /// <summary> /// I,V,X,L,C,D,M /// </summary> public char Symbol { set; get; } /// <summary> /// I:1,X:5,X:10,L:50,C:100,D:500,M:1000 /// </summary> public int Value { set; get; } /// <summary> /// is allow repeated? such as II,III /// only I,X,C,M can repeated /// </summary> public bool AllowRepeated { set; get; } /// <summary> /// is allow subtracted? /// only I,X C can subtracted /// such as: IV,IX; XL,XC;CD,CM; /// </summary> public bool AllowSubtracted { set; get; } /// <summary> /// if allow subtracted, how distence? /// I,V,X,L,C,D,M /// such as: /// IV,IX:distence is 2; /// XL,XC:distence is 2; /// CD,CM:distence is 2; /// </summary> public int SubtractedDestence { set; get; } } }
在新建一个类专门做转换:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RomanNumber { public class RomanService { private char[] _allowRomans = new char[] { ‘I‘, ‘V‘, ‘X‘, ‘L‘, ‘C‘, ‘D‘, ‘M‘ }; /// <summary> /// The featured roman list /// </summary> public List<Roman> FeaturedRomans { private set; get; } private static RomanService _instance; public static RomanService Instance { get { if (_instance == null) _instance = new RomanService(); return _instance; } } private RomanService() { var vs = new int[] { 1, 5, 10, 50, 100, 500, 1000 }; FeaturedRomans = new List<Roman>(); for (var i = 0; i < _allowRomans.Length; i++) { FeaturedRomans.Add(new Roman { Symbol = _allowRomans[i], Value = vs[i], AllowRepeated = _allowRomans[i] == ‘I‘ || _allowRomans[i] == ‘X‘ || _allowRomans[i] == ‘C‘ || _allowRomans[i] == ‘M‘, AllowSubtracted = _allowRomans[i] == ‘I‘ || _allowRomans[i] == ‘X‘ || _allowRomans[i] == ‘C‘, SubtractedDestence = (_allowRomans[i] == ‘I‘ || _allowRomans[i] == ‘X‘ || _allowRomans[i] == ‘C‘) ? 2 : 0 }); } } /// <summary> /// calculate a roman expression‘s value /// </summary> /// <param name="exp"></param> /// <returns></returns> public int Calculate(string exp) { if (string.IsNullOrEmpty(exp)) return 0; var romans = exp.ToCharArray(); var result = 0; if (romans.Length == 1) { return FeaturedRomans.FirstOrDefault(x => x.Symbol == romans[0]).Value; } for (int i = 0; i <= romans.Length - 1; i = i + 2) { var current = FeaturedRomans.FirstOrDefault(x => x.Symbol == romans[i]); if (i >= romans.Length - 1) { result += current.Value; break; } var next = FeaturedRomans.FirstOrDefault(x => x.Symbol == romans[i + 1]); if (current == null) { throw new Exception(string.Format("unexpected roman char:{0}", romans[i])); } if (next == null) { throw new Exception(string.Format("unexpected roman char:{0}", romans[i + 1])); } if (current.Value > next.Value) { result += current.Value; i--; } else if (current.Value == next.Value) { if (!current.AllowRepeated) { throw new Exception(string.Format("Not allow {0} repeate", current.Symbol)); } int repeatedCount = 2; for (int j = i + 2; j < romans.Length; j++) { if (romans[j] != current.Symbol) break; repeatedCount++; if (repeatedCount > 3) { throw new Exception(string.Format("Not allow {0} repeated more than 3 times", current.Symbol)); } } result += current.Value; i--; } else { result += next.Value - current.Value; } } return result; } } }
程序输出:
代码不解释,请大牛批评指正。
代码下载:http://files.cnblogs.com/deepleo/RomanNumber.rar
ThoughtWorks笔试题之Merchant's Guide To The Galaxy解析,布布扣,bubuko.com
ThoughtWorks笔试题之Merchant's Guide To The Galaxy解析
原文:http://www.cnblogs.com/deepleo/p/ThoughtWorks.html