总共三本钱中有几内亚几内亚?


32

直到1971年十进制化,英国货币的基础是将英镑分为240便士。一先令为12便士,所以20先令等于一磅。最小的面额是一分钱的四分之一。硬币还有许多其他面额和昵称,如果您不习惯该系统,可能会造成很多困惑。

挑战

编写一个程序或函数,可以将(几乎)任何面额的旧英语货币转换为其他任何货币。为了使用户更轻松,您需要支持复数形式和昵称。

这些是您必须支持的面额及其同义词。为方便起见,它们在零食中的价值领先于每一行。

1: farthing, farthings
2: halfpence, halfpenny, halfpennies
4: penny, pennies, pence, copper, coppers
8: twopenny, twopennies, twopence, tuppence, half groat, half groats
12: threepence, threepenny, threepennies, threepenny bit, threepenny bits, thruppence, thrupenny, thrupennies, thrupenny bit, thrupenny bits
16: groat, groats
24: sixpence, sixpenny, sixpennies, sixpenny bit, sixpenny bits, tanner, tanners
48: shilling, shillings, bob
96: florin, florins, two bob bit, two bob bits
120: half crown, half crowns
240: crown, crowns
480: half sovereign, half sovereigns
504: half guinea, half guineas
960: pound, pounds, pounds sterling, sovereign, sovereigns, quid, quids
1008: guinea, guineas

(我不是英国人,此列表绝不权威,但足以应付挑战。)

通过stdin或function参数,您应该采用以下形式的字符串

[value to convert] [denomination 1] in [denomination 2]

并返回或打印

[value to convert] [denomination 1] is [converted value] [denomination 2]

其中[converted value]是[value to convert]面额1的单位转换为现金种类2。

该[value to convert]和[converted value]是正的浮动。在输出中,两者都应四舍五入或舍入到小数点后4位。如果需要,您可以假设[value to convert]输入时总是有一个小数点和零(例如1.0代替1)。

命名1和2可以是上面列表中的任何两个术语。不必担心它们是否为复数,将所有面额和同义词都一样。您可以假设输入格式和面额始终有效。

例子

1 pounds in shilling→ 1 pounds is 20 shilling
(1.0000 pounds is 20.0000 shilling可以)

0.6 tuppence in tanner → 0.6 tuppence is 0.2 tanner

24 two bob bits in pounds sterling → 24 two bob bits is 2.4 pounds sterling

144 threepennies in guineas → 144 threepennies is 1.7143 guineas

计分

以字节为单位的最短代码获胜。


1
“便士”仅用于指代许多硬币,而不是金钱。
— David Richerby 2014年

4
吹毛求疵:邮政decimalisation,的复数quidIS quid。这很可能与旧钱一样。范例:Five quid a pint! Cor blimey guvnor。例外:quids-in
— Digital Trauma

7
我可能会把很多人弄得一团糟,要求他们包括“ ha'penny”。
— kaine 2014年

3
我从来没有听过ha'penny叫过什么,除了@kaine。如在en.wikipedia.org/wiki/Ha%27penny_Bridge中。当然,我自己还太年轻,以至于不能经常在语音中听到它,但是撇号在写作中似乎是标准的。
— TRiG 2014年

Answers:


9

Pyth,146 145

K4J24L?*y>b-5>b\t?2>b\t.5}<b2"hatw"@[1K8K12K16J48J1008*JT96*2J960)xc"fapetucothengrsishtagucrflbo"2<b2AGHcz" in"++G%" is %0.4f"*vhcGdcyjdtcGdytHH

更具可读性(必须删除换行符和缩进才能运行):

K4J24
L?*y>b-5>b\t?2>b\t.5
  }<b2"hatw"
  @[1K8K12K16J48J1008*JT96*2J960)
   xc"fapetucothengrsishtagucrflbo"2<b2
AGHcz" in"
++G
  %" is %0.4f"
   *vhcGdcyjdtcGdytH
 H

更新:结果是,在运行字符串索引操作之前,将字符串切成2个字符串的列表要短1个字符(无需空格)。/x"string"<b2 2-> xc"string"2<b2。无需更改。

怎么运行的:

  • 这使用@xnor的方法,即使用前两个字母来查找货币值,以及检测首字母halfor 的技巧two,将其删除并再次调用该函数。

  • 要查找前两个字符的值,它会找到货币中前两个字母在字符串中的位置,然后除以2,并取值列表中该索引处的值。这比pyth中的命令短得多。

  • 使用以下事实:x在失败时(在字符串内查找)返回-1,以避免在字符串中放入po(磅)qu(quid)或so(主权),并且默认情况下仅返回列表的最后一个元素960。

  • 通过在检索系统重新排列货币秩序,认真初始化,与K4和J24,将已经需要分隔列表中的号码的所有空间被拆除。

  • A在分割的输入上使用pyth的对偶赋值运算符, in以在单独的变量中获取输入的开始和结尾。

  • 最后,虽然pyth没有no .split(_,1),但是基本上进行了相同的查找,因此它比较麻烦。

例子:

$ pyth programs/currency.pyth <<< '5 florins in half guineas'
5 florins is 0.9524 half guineas

$ pyth programs/currency.pyth <<< '0.4 quid in sixpenny bits'
0.4 quid is 16.0000 sixpenny bits

3
我放弃...;)
— Martin Ender 2014年

我不知道<并>担任过字符串/列表切片运算符;这比
— 砍头

@FryAmTheEggman看起来文档中也缺少它-我已经添加了它。
— isaacg 2014年

我可能应该更仔细地阅读macros.py :)
— FryAmTheEggman 2014年

14

红宝石,345 306 302 288 287 278 273 253 252 242 232个 221 202 190字节

f=->s{" !#+/7OďǿȗϟЏ'"[%w{fa fp ^pe|co r..p ^gr x|ta sh|^b fl|b f.c ^c f.s .gu d|v ^g .}.index{|k|s[/#{k}/]}].ord-31}
$><<gets.sub(/ (.+ i)n /){" #{r=$1}s %0.4f ".%$`.to_f/f[$']*f[r]}

从STDIN接收输入并打印到STDOUT。

我正在使用简短的正则表达式来为每个值仅匹配所需的面额。在相应的索引处有两个数组,一个带有正则表达式,一个带有值。regex数组是用空格分隔的数组文字,而value数组打包为一串UTF-8字符。

我通过搜索与每种面额匹配的正则表达式来选择值的索引。我也默认使用tuppence / half-groat情况(值8),因为这需要最长的正则表达式。同样,某些模式假定其他值已被较早的模式匹配,因此每个正则表达式仅将所需值与其余值区分开。使用此方法,我可能可以通过重新排列面额顺序来减少另外两个字节。

感谢Ventero帮助我击败了Pyth,使其变得更短!


1
正则表达式匹配(s[k])会覆盖$1等。您可以通过将映射块移动到lambda并直接在最后一行中调用它来保存一些字符(这也允许您删除$1and 的赋值$2)。也.index比短.find_index。
— Ventero 2014年

@Ventero啊,有道理。谢谢!
— Martin Ender 2014年

1
Regexp.new k→ /#{k}/和$><<gets.sub(/foo/){a=$3;...}→ gets[/foo/];a=$3;puts...总共为221。当然,您可以使用古老的技巧将int数组包装到字符串中(使用.pack("U*")),然后索引到该字符串中。应该使您降至195个字符/ 200字节。
— Ventero 2014年

甚至更好:a=gets[/foo/,3]
— Ventero 2014年

@Ventero非常感谢。我以196/202结尾,因为我在字符代码中添加了偏移量以避免不可打印的ASCII。比Pyth还短。;)
— Martin Ender 2014年

8

Python 3中:264 239个字符

f=lambda c:c[:2]in"hatw"and f(c[5-(c>'t'):])*2/4**(c<'t')or[1,4,4,4,8,12,16,24,24,48,48,96,240,1008,960]['fapecoentuthgrsitashboflcrgu'.find(c[:2])//2]
a,b=input().split(" in ")
x,c=a.split(" ",1)
print(a,"is %0.4f"%(eval(x)*f(c)/f(b)),b)

该函数通过在字典中找到f字符串中c的前两个字母来对它们进行指纹识别,从而获得货币字符串的先令价值。通过截去前缀和空格并应用乘数,可以检测和解释前缀“ half”和“ two”。由于“ halfpenny”在“ half”之后没有空格,因此结果为“ enny”,但这是通过虚构的“ en”条目处理的。

感谢@isaacg和@grc对字典查找进行了大量改进。


我知道这是可以做到的:)我也很尴尬,因为我不知道您可以定义这样的字典...:S
— FryAmTheEggman 2014年

2
@FryAmTheEggman我不是,您也可以通过关键字定义字典,直到我在网站上的答案中看到它。您学习打高尔夫球的东西
— xnor 2014年

我为此制作了一个Pyth版本,并得到207个字符。您希望将其发布在此处供您添加还是发布社区Wiki答案?
— FryAmTheEggman 2014年

1
对该2/4**(c<'t')部分+1 。
— njzk2 2014年

1
通过使用.get(c[:2],960)从字典中查找值并从字典中省略po=960,so=960,qu=960,条目,您可以保存13个字符。
— isaacg 2014年

5

Python 2-345358

s=str.startswith
h='half'
u,v=raw_input().split(' in ')
a,b=u.split(' ',1)
C=dict(fa=1,pe=4,twop=8,tu=8,thr=12,gr=16,si=24,ta=24,sh=48,b=48,fl=96,c=240,po=960,so=960,q=960,gu=1008)
C.update({h+'p':2,h+' gr':8,'two ':96,h+' c':120,h+' s':480,h+' gu':504})
for c in iter(C):
 if s(b,c):k=C[c]
 if s(v,c):f=C[c]
print u+' is %0.4f '%(eval(a)*k/f)+v

要求输入数字是python中的浮点数,即 144.1

我认为这可以在python 3中缩短...

...感谢@xnor。还证实了拥有更好的算法很重要;)


我将替换q=raw_input().split(' in ')为q,b=raw_input().split(' in ')
— njzk2,2014年

@ njzk2非常正确...现在我也将其用于下一行:)
— FryAmTheEggman 2014年

我觉得这是发生冲突h+' gr':8,并h+' g':504取决于谁首先计算半米粒
— njzk2

@ njzk2是真的……已添加u到几内亚了……
— FryAmTheEggman 2014年

2

Haskell-315字节

w x=f(u x)*v(u x)
f=maybe 1 id.l"ha tw tu th si"[0.5,2,2,3,6]
v x@(_:xs)|Just w<-l"bo cr gr gu so co fa fl pe po qu sh ta"[12,60,4,252,240,1,0.25,24,1,240,240,12,6]x=w|True=v xs
l k v x=take 2 x`lookup`zip(words k)v
u=unwords
i s|(n:x,_:t)<-span(/="in")$words s=u$n:x++["is",show$read n*w x/w t]++t
main=interact i

2

JavaScript(ES5),344

I=prompt()
n=I.match(/[\d.]+ /)[0]
A=I.slice(n.length).split(" in ")
function m(x){return{fi:1,he:2,p:4,pe:4,cr:4,tn:8,hg:8,tp:12,te:12,g:16,gs:16,sn:24,tr:24,si:48,b:48,fn:96,to:96,hc:120,c:240,cs:240,hs:480,hgtrue:504,ps:960,se:960,q:960,ga:1008}[x[0]+(x[5]||"")+(x[10]=="a"||"")]}
alert(n+A[0]+" is "+(n*m(A[0])/m(A[1])).toFixed(4)+" "+A[1])

我采用了哈希函数方法...我想我(相对)低估了输入处理的复杂度(相对于正则表达式方法,它不在乎数字)。


1

基于@FryAmTheEggMan的答案,采用不同的测试方式str.startwith:

Python 2:317

h='half'
C=dict(fa=1,pe=4,twop=8,tu=8,thr=12,gr=16,si=24,ta=24,sh=48,b=48,fl=96,c=240,po=960,so=960,q=960,gu=1008)
C.update({h+'p':2,h+' gr':8,'two ':96,h+' c':120,h+' s':480,h+' gu':504})
u,v=raw_input().split(' in ')
a,b=u.split(' ',1)
s=lambda x:x and C.get(x, s(x[:-1]))
print u+' is %0.4f '%(eval(a)*s(b)/s(v))+v

我认为您需要在print和格式化的字符串中添加尾随空格。您也可以重写lambda s=lambda x:x and C.get(x,s(x[:-1]))or 0以保存字符(以及空格)。顺便说一句,这是一个很好的主意:)
— FryAmTheEggman 2014年

谢谢,我用这种三元符号摆弄了一段时间,我总是觉得它很冗长,但是却没有and/or。
— njzk2 2014年

是啊,我在这里学到了:)我还认为你需要u.split(' ')说u.split(' ',1)的是有空格的货币,像“半主权”。
— FryAmTheEggman 2014年

所以这就是原因, 1!
— njzk2 2014年

2
三元数x and y or 0通常可以缩短为x and y,因为当Falsey 时,两者都0等于或等效。Falsex
— xnor 2014年

1

的JavaScript ES6,264 273

f=t=>{s=t.split(x=' in')
c=d=>{'t0sh|bo0^p|co0f0fp0fl|b b0gu0d|v0wn0gr0f g|t..?p0f s0f gu0f c0x|an'.split(0).map((e,i)=>{v=s[d].match(e)?[12,48,4,1,2,96,1008,960,240,16,8,480,504,120,24][i]:v})
return v}
return s.join(' is '+~~(1e4*t.split(' ')[0]*c(0)/c(1))/1e4)}

通过从最广泛的正则表达式检查各种正则表达式来获得每种货币的价值/t/。如果遇到另一个匹配项,则该值将被覆盖。通过重新排序正则表达式字符串,可能有一种方法可以减少几个字节。您可以使用上面的代码片段对其进行测试(它的格式仅设置为使用对话框并删除ES6箭头功能,以便每个人都可以轻松地测试代码)。感谢Alconja的建议。


1
您可以修剪2个通过使用字符't0sh|bo0^p....'.split(0),4多用.map,而不是.forEach和3以上通过调用c(0)和c(1)和做s[d].match
— Alconja
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.