กี่กีนีในจำนวนรวมของ Threepennies


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 หรือฟังก์ชันอาร์กิวเมนต์คุณควรใช้ในรูปแบบของสตริง

[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 shilling1 pounds is 20 shilling
( 1.0000 pounds is 20.0000 shillingไม่เป็นไร)

0.6 tuppence in tanner0.6 tuppence is 0.2 tanner

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

144 threepennies in guineas144 threepennies is 1.7143 guineas

เกณฑ์การให้คะแนน

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


1
"เพนนี" ใช้เพื่ออ้างถึงจำนวนเหรียญเท่านั้นไม่ใช่จำนวนเงิน
David Richerby

4
จู้จี้เลือก: โพสต์ decimalisation พหูพจน์ของมีquid quidส่วนใหญ่มีแนวโน้มที่จะได้รับเหมือนกันกับเงินเก่า ตัวอย่าง: Five quid a pint! Cor blimey guvnor. ข้อยกเว้น: quids-in
Digital Trauma

7
ฉันอาจจะเลอะผู้คนจำนวนมากขึ้นเพื่อให้พวกเขารวมถึง "ฮ่าเงิน"
kaine

3
ฉันไม่เคยได้ยินฮาเฮ็นเพนพูดอะไรเลยนอกจากเฮกเพน @kaine ในขณะที่en.wikipedia.org/wiki/Ha%27penny_Bridge แน่นอนฉันเองยังเด็กเกินไปที่จะได้ยินบ่อยเกินไป แต่อะพอสโทรฟีดูเหมือนเป็นมาตรฐานในการเขียน
TRiG

คำตอบ:


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

อัปเดต: ปรากฎว่ามีความยาว 1 อักขระ (ไม่จำเป็นต้องมีช่องว่าง) เพื่อตัดสตริงลงในรายการของอักขระ 2 ตัวก่อนเรียกใช้การดำเนินการดัชนีสตริง ->/x"string"<b2 2 xc"string"2<b2ไม่มีอะไรจะต้องมีการเปลี่ยนแปลง

มันทำงานอย่างไร:

  • วิธีนี้ใช้วิธีของ @ xnor ในการค้นหามูลค่าของสกุลเงินโดยใช้ตัวอักษรสองตัวแรกรวมถึงเคล็ดลับในการตรวจจับค่าเริ่มต้นhalfหรือtwoลบออกแล้วเรียกใช้ฟังก์ชันอีกครั้ง

  • ในการค้นหาค่าของอักขระสองตัวแรกมันจะค้นหาตำแหน่งของตัวอักษรสองตัวแรกของสกุลเงินในสตริงจากนั้นหารด้วย 2 และนำค่าที่ดัชนีนั้นในรายการ นี่สั้นกว่าพจน์ใน pyth มาก

  • ใช้ความจริงที่ว่าx(find inside string) ส่งคืน -1 เมื่อล้มเหลวเพื่อหลีกเลี่ยงการใส่po(ปอนด์) qu(quid) หรือso(sovereigns) ในสตริงและส่งคืนองค์ประกอบสุดท้ายของรายการ 960 ตามค่าเริ่มต้น

  • โดยการจัดเรียงลำดับของสกุลเงินใหม่ในระบบการค้นหาและเริ่มต้นอย่างระมัดระวังด้วยK4และJ24ช่องว่างทั้งหมดที่จะต้องใช้เพื่อแยกตัวเลขในรายการจะถูกลบออก

  • ใช้ตัวดำเนินการกำหนดค่าแบบคู่ของ pyth Aบนตัวแบ่งอินพุต inเพื่อรับจุดเริ่มต้นและจุดสิ้นสุดของอินพุตในตัวแปรแยกต่างหาก

  • การค้นหาในตอนท้ายเหมือนกันเป็นหลักแม้ว่า pyth ไม่มี.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

ฉันไม่รู้จัก<และ>ทำงานเป็นตัวดำเนินการสตริง / ลิสต์ ที่มากดีกว่าการใช้หัวหรือท้ายของสับ :)
FryAmTheEggman

@FryAmTheEggman ดูเหมือนว่าจะหายไปจากเอกสารเช่นกัน - ฉันได้เพิ่มแล้ว
isaacg

ฉันอาจจะอ่านผ่าน macros.py อย่างระมัดระวังมากขึ้น :)
FryAmTheEggman

14

Ruby, 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

ฉันใช้นิพจน์ทั่วไปสั้น ๆ เพื่อจับคู่เฉพาะค่าที่ต้องการสำหรับแต่ละค่า มีสองอาร์เรย์หนึ่งมี regexes และหนึ่งมีค่าที่ดัชนีที่สอดคล้องกัน อาเรย์ regex เป็นอาเรย์ที่มีตัวคั่นของช่องว่างและอาเรย์ของมูลค่าถูกบรรจุในสตริงของอักขระ UTF-8

ฉันกำลังเลือกดัชนีเป็นค่าโดยค้นหา regex ที่ตรงกับแต่ละนิกาย ฉันยังเริ่มต้นกับกรณี tuppence / half-groat (ค่า 8) เพราะนั่นต้อง regex ที่ยาวที่สุด ในทำนองเดียวกันบางรูปแบบสมมติว่าค่าอื่น ๆ ได้รับการจับคู่แล้วโดยรูปแบบก่อนหน้าดังนั้นแต่ละ regex จะแยกความแตกต่างของค่าที่ต้องการจากค่าที่เหลือเท่านั้น การใช้สิ่งนี้ฉันอาจจะโกนทิ้งอีกสองสามไบต์โดยจัดเรียงลำดับของนิกายใหม่

ขอบคุณ Ventero ที่ช่วยฉันเอาชนะ Pythทำให้มันสั้นลง!


1
มันจับคู่ regex ( s[k]) ที่เขียนทับ$1ฯลฯ คุณสามารถบันทึกตัวอักษรไม่กี่บล็อกโดยการย้ายแผนที่เข้าแลมบ์ดาและเรียกว่าโดยตรงในบรรทัดสุดท้าย (ซึ่งยังช่วยให้คุณลดลงได้รับมอบหมายสำหรับ$1และ$2) นอกจากนี้ยังจะสั้นกว่า.index .find_index
Ventero

@Ventero Ah นั่นเหมาะสมแล้ว ขอขอบคุณ!
Martin Ender

1
Regexp.new k/#{k}/และ$><<gets.sub(/foo/){a=$3;...}gets[/foo/];a=$3;puts...รวมเป็น 221 และแน่นอนคุณสามารถใช้เคล็ดลับเก่าของการบรรจุอาร์เรย์ int ลงในสตริง (โดยใช้.pack("U*")) แล้วทำดัชนีลงในสตริงนั้น ควรนำคุณลงไปที่ 195 chars / 200 bytes
Ventero

ดียิ่งขึ้น:a=gets[/foo/,3]
Ventero

@ Ventero ขอบคุณมาก ฉันลงเอยด้วย 196/202 เพราะฉันเพิ่มออฟเซ็ตลงในรหัสถ่านเพื่อหลีกเลี่ยง ASCII ที่ไม่สามารถพิมพ์ได้ ยังสั้นกว่า Pyth ;)
Martin Ender

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โดยพิมพ์ตัวอักษรสองตัวแรกโดยใช้พจนานุกรมโดยการค้นหาในสตริง คำนำหน้า "ครึ่ง" และ "สอง" ถูกตรวจพบและคิดโดยการตัดส่วนนำหน้าและช่องว่างและใช้ตัวคูณ เนื่องจาก "halfpenny" ขาดช่องว่างหลังจาก "half" ผลลัพธ์นี้ใน "enny" แต่ถูกจัดการด้วยรายการ "en" fictional

ขอบคุณ @isaacg และ @grc สำหรับการปรับปรุงจำนวนมากในการค้นหาพจนานุกรม


ฉันรู้ว่ามันสามารถทำได้ :) ฉันยังอายอย่างมากที่ฉันไม่รู้ว่าคุณสามารถกำหนดพจนานุกรมแบบนั้น ... : S
FryAmTheEggman

2
@FryAmTheEggman ฉันไม่สามารถกำหนดพจนานุกรมผ่านคำหลักได้จนกว่าฉันจะเห็นคำตอบในเว็บไซต์นี้ สิ่งที่คุณเรียนรู้การเล่นกอล์ฟ ...
XNOR

ฉันทำรุ่น Pyth และได้ตัวอักษร 207 ชุด คุณต้องการให้ฉันโพสต์ไว้ที่นี่เพื่อให้คุณเพิ่มหรือโพสต์คำตอบของวิกิของชุมชนหรือไม่
FryAmTheEggman

1
+1 สำหรับ2/4**(c<'t')ส่วนนั้น
njzk2

1
คุณสามารถบันทึก 13 อักขระโดยใช้.get(c[:2],960)เพื่อค้นหาค่าจากพจนานุกรมและละเว้นpo=960,so=960,qu=960,รายการจากพจนานุกรม
isaacg

5

Python 2 - 345 358

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

ต้องใส่หมายเลขเพื่อเป็นทศนิยมในหลามเช่น 144.1

ฉันคิดว่ามันสั้นลงใน python 3 ...

... ได้รับการยืนยันขอบคุณ @xnor ยังยืนยันว่าการมีอัลกอริทึมที่ดีกว่ามีความสำคัญมาก;)


ฉันจะแทนที่q=raw_input().split(' in ')ด้วยq,b=raw_input().split(' in ')
njzk2

@ njzk2 ค่อนข้างถูกต้อง ... ฉันเคยใช้สิ่งนี้เพื่อบรรทัดถัดไปตอนนี้ :)
FryAmTheEggman

ฉันคิดว่ามีความขัดแย้งระหว่างh+' gr':8และh+' g':504ขึ้นอยู่กับผู้ที่ได้รับการประเมินครั้งแรกสำหรับครึ่ง groats
njzk2

@ njzk2 นั่นเป็นความจริง ... เพิ่มuไปยังหนึ่งกินี ...
FryAmTheEggman

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])

ฉันใช้วิธีแฮชฟังก์ชัน ... ฉันคิดว่าฉันประเมินค่าต่ำกว่า (ค่อนข้าง) ความซับซ้อนของการประมวลผลอินพุต (เหนือวิธี regex ที่ไม่สนใจจำนวน)


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และสตริงที่จัดรูปแบบ คุณสามารถเขียนแลมบ์ดาอีกครั้งs=lambda x:x and C.get(x,s(x[:-1]))or 0เพื่อบันทึกอักขระ (พร้อมช่องว่าง) นี่เป็นความคิดที่ค่อนข้างดี btw :)
FryAmTheEggman

ขอบคุณฉันเล่นสักพักด้วยสัญกรณ์ที่สามซึ่งฉันมักจะพบ verbose แต่ไม่ได้ทำand/orสิ่งนั้น
njzk2

ใช่ฉันเรียนที่นี่แล้ว :) ฉันคิดว่าคุณจำเป็นต้องu.split(' ')พูดu.split(' ',1)ถึงสกุลเงินที่มีช่องว่างเช่น "อธิปไตยครึ่ง"
FryAmTheEggman

นั่นคือเหตุผลสำหรับการ, 1!
njzk2

2
Ternary x and y or 0สามารถทำให้สั้นลงโดยทั่วไปx and yเนื่องจากทั้งคู่ประเมิน0หรือเท่ากันFalseเมื่อxFalsey
xnor

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)}

นี้ได้รับค่าของสกุลเงินในแต่ละโดยการตรวจสอบมันกับ regexes ต่างๆที่เริ่มต้นด้วยกว้าง/t/; ค่าจะถูกเขียนทับหากพบการแข่งขันอื่น อาจมีวิธีการโกนไบต์คู่โดยการเรียงลำดับสตริง regex ใหม่ คุณสามารถทดสอบโดยใช้ตัวอย่างด้านบน (เป็นรูปแบบที่จะใช้กล่องโต้ตอบและลบฟังก์ชั่นลูกศร ES6 เพื่อให้ทุกคนสามารถทดสอบโค้ดได้อย่างง่ายดาย) ขอบคุณ Alconja สำหรับคำแนะนำ


1
คุณสามารถตัด2ตัวอักษรโดยใช้'t0sh|bo0^p....'.split(0), 4มากขึ้นโดยใช้.mapแทน.forEachและ3มากขึ้นโดยการเรียกc(0)และc(1)และการทำs[d].match
Alconja
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.