กี่กีนีในจำนวนรวมของ 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 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

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.