Bir Threepennies Brüt Kaç Gine?


32

1971’deki desimalleşmeye kadar , İngiliz parası poundu 240 fona bölmeye dayanıyordu . Bir şilin 12 kuruş oldu, bu yüzden 20 şilin bir pound yaptı. En küçük değer, bir kuruşun dörtte birinde osurmaktı. Madeni paralar için birçok mezhep ve takma adlar vardı, eğer sisteme alışmazsanız oldukça kafa karıştırıcı olabilir.

Meydan okuma

Eski İngiliz parasının herhangi bir türünü diğerlerine dönüştürebilecek (neredeyse) program veya işlev yazın. Kullanıcıyı kolaylaştırmak için çoğulları ve takma adları desteklemeniz gerekir.

Bunlar, mezhepler ve onların desteklemesi gereken eşanlamlı terimlerdir. Kolaylık sağlamak için, uzak mesafelerdeki değerleri her satıra yönlendirir.

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

(İngiliz değilim, bu liste hiçbir şekilde yetkili değildir, ancak bu zorluk için yeterli olacaktır.)

Stdin veya function argümanı aracılığıyla formun bir dizgisine girmelisiniz

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

ve iade veya yazdırma

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

burada [converted value]bir [value to convert]denomination 1 birimleri denomination 2'ye dönüştürülen.

[value to convert]Ve [converted value]olumlu yüzer vardır. Çıktıda her ikisi de 4 ondalık basamağa yuvarlanmalı veya kesilmelidir. İstenirse [value to convert], giriş sırasında her zaman bir ondalık basamağı ve sıfır olduğunu varsayabilirsiniz (örneğin, 1.0yerine 1).

Mezhepler 1 ve 2 yukarıdaki listeden herhangi iki terim olabilir. Çoğul olup olmadıkları konusunda endişelenmeyin, tüm mezheplere ve eş anlamlılara aynı şekilde davranın. Giriş biçimini ve mezheplerin her zaman geçerli olduğunu varsayabilirsiniz.

Örnekler

1 pounds in shilling1 pounds is 20 shilling
(iyi 1.0000 pounds is 20.0000 shillingolurdu)

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

puanlama

Bayt cinsinden en kısa kod kazanır.


1
"Pennies", bir miktar paraya değil, yalnızca bir miktar paraya atıfta bulunmak için kullanılır.
David Richerby

4
Nit-alma: Mesaj decimalisation, çoğulu quidDİR quid. Büyük olasılıkla bu eski para ile aynı olurdu. Örnek: Five quid a pint! Cor blimey guvnor. İstisna: quids-in
Dijital Travma

7
Muhtemelen birçok insanı "ha'penny" eklemelerini gerektirecek kadar karıştırırdım.
kaine

3
Ben bir ha'penny denilen bir şey duymadım ama ha'penny, @kaine. Olduğu gibi en.wikipedia.org/wiki/Ha%27penny_Bridge . Tabii ki, konuşmada çok sık duymuş olamadığım için çok gencim, fakat kesme işareti yazılı olarak standart görünüyor.
TRiG

Yanıtlar:


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

Daha okunur (yeni satırlar ve girintiler çalıştırılmak üzere kaldırılmalıdır):

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

Güncelleme: Dize dizini işlemini çalıştırmadan önce dizeyi 2 karakter dizesi listesine bölmek 1 karakterden daha kısa (boşluk gerekli değil) çıkıyor. /x"string"<b2 2-> xc"string"2<b2. Başka hiçbir şeyin değiştirilmesi gerekmiyor.

Nasıl çalışır:

  • Bu, @ xnor'ın ilk iki harfini kullanarak para biriminin değerine bakma yaklaşımını, aynı zamanda ilkini algılama hilesini halfveya twoonu kaldırmayı ve işlevi tekrar çağırmayı kullanır.

  • İlk iki karakterin değerini aramak için, para biriminin ilk iki harfinin bir dizgede bulunduğu yeri bulur, ardından 2'ye böler ve bu listedeki değeri listede alır. Bu, pyth içindeki bir serseriden çok daha kısadır.

  • Gerçeğini kullanır xkoyarak önlemek için getiriler -1 başarısızlık üzerine (string içinde bulmak) po(pound) qu(sterlin) ya da sodizede (hükümdarlarını) ve sadece varsayılan olarak, liste, 960 son elemanını döndürür.

  • Arama sistemindeki para birimleri sırasını yeniden düzenleyerek ve dikkatli bir şekilde, başlangıçta K4ve J24ardından, listedeki sayıları ayırmak için gereken tüm boşluklar kaldırılarak kaldırıldı.

  • Kullanımları pyth ikili atama operatörü A, giriş split üzerine inayrı değişkenlerde girdi başını ve sonunu alır.

  • Temelde sonunda aynı arama yapar, pyth olmasa da .split(_,1), bu yüzden biraz hantal.

Örnekler:

$ 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
Pes ediyorum ...;)
Martin Ender

Bilmiyordum <ve >dize / liste dilim operatörleri olarak çalıştı; bir pirzola kafasını veya sonunu almaktan çok daha iyi :)
FryAmTheEggman

@FryAmTheEggman Belgelerde de eksik görünüyordu - Ben de ekledim.
isaacg,

Muhtemelen daha dikkatli bir şekilde macros.py okumak gerekir :)
FryAmTheEggman

14

Ruby, 345 306 302 288 287 278 273 253 252 242 232 221 202 190 bayt

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'den girdi alır ve STDOUT'a yazdırır.

Her değer için yalnızca istenen değerleri eşleştirmek için kısa normal ifadeler kullanıyorum. İlgili endekslerde biri regexli diğeri de değerleri olan iki dizi vardır. Regex dizisi bir boşlukla ayrılmış dizi değişmezidir ve değer dizisi bir UTF-8 karakter dizisine paketlenir.

Her bir değere uyan bir regex arayarak dizini değerlere seçiyorum. Ayrıca, tuppence / yarı-groat davasına da varsayılan değer veriyorum (değer 8), çünkü en uzun regex gerekiyordu. Benzer şekilde, bazı paternler diğer değerlerin daha önceki paternlerle zaten eşleştirildiğini varsayar, bu nedenle her bir regex sadece istenen değeri sadece diğerlerinden ayırır. Bunu kullanarak, muhtemelen mezheplerin sırasını yeniden düzenleyerek başka bir çift baytı tıraş edebilirim.

Bana yardım ettiğin için Ventero sayesinde Pyth yendi daha kısa hale!


1
Bu regex eşleştirme var ( s[k]) üzerine yazar olduğunu $1vs. Bir lambda içine harita bloğu hareketli ve doğrudan son satırında (ayrıca sağlayan sen atamalarını düşmesi olduğunu çağırarak birkaç karakter kaydedebilirsiniz $1ve $2). Ayrıca .indexdaha kısa .find_index.
Ventero

@ Ventero Ah, bu mantıklı. Teşekkür ederim!
Martin Ender

1
Regexp.new k/#{k}/ve $><<gets.sub(/foo/){a=$3;...}gets[/foo/];a=$3;puts...toplamda 221 için. Tabi eski int dizisini bir dizgiye (kullanarak .pack("U*")) koyup sonra dizgeye indeksleyerek kullanabilirsiniz. Seni 195 karakter / 200 bayta indirmeli.
Ventero

Daha da iyisi:a=gets[/foo/,3]
Ventero

@Ventero Çok teşekkürler. 196/202 ile bitirdim, çünkü yazdırılamayan ASCII'yi önlemek için char kodlarına ofset ekledim. Hala Pyth'ten daha kısa. ;)
Martin Ender

8

Python 3: 264 239 karakter

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)

İşlev , ilk iki harfi bir dizede bularak sözlüğü kullanarak ilk iki harfe parmak izi fbasarak para birimi dizesinin şilin değerini alır . "Half" ve "two" önekleri, ön eki ve alanı keserek ve bir çarpan uygulayarak algılanır ve muhasebeleştirilir. "Halfpenny", "half" den sonra boşluk bırakmadığından, bu "enny" ile sonuçlanır, ancak bu kurgusal bir "en" girişi ile ele alınır.c

@İsaacg ve @grc'ye, sözlük taramasındaki birçok iyileştirme için teşekkürler.


Yapılabileceğini biliyordum :) Ayrıca, böyle bir sözlük tanımlayabileceğinizi bilmediğim için de çok utanıyorum ...: S
FryAmTheEggman

2
@FryAmTheEggman Bu sitede bir cevapta kullanıldığını görene kadar sözlükleri anahtar kelimelerle tanımlayamadım. Golf
oynamayı

Bunun Pyth versiyonunu yaptım ve 207 karakter aldım. Bir topluluk wiki cevabı ekleyebilmeniz veya gönderebilmenizi mi tercih ederim?
FryAmTheEggman

1
Bu 2/4**(c<'t')kısım için +1 .
njzk2

1
.get(c[:2],960)Sözlükten değere bakmak ve po=960,so=960,qu=960,girişleri sözlükten atlamak için 13 karakter kaydedebilirsiniz .
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

Giriş sayısının python yani 144.1

Sanırım bu python 3'te kısaltılabilir ...

... @xnor sayesinde onaylandı. Ayrıca daha iyi bir algoritmaya sahip olmanın çok önemli olduğunu doğruladı;)


Ben yerini alacak q=raw_input().split(' in ')tarafındanq,b=raw_input().split(' in ')
njzk2

@ njzk2 Oldukça doğru ... Bunu bir sonraki satır için de kullandım, şimdi :)
FryAmTheEggman

Ben arasında bir çelişki olduğunu düşünüyorum h+' gr':8ve h+' g':504yarım kabuksuz ilk değerlendirilir kişiye göre
njzk2

@ njzk2 doğru ... uGine'ye eklendi ...
FryAmTheEggman

2

Haskell - 315 bayt

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

Bir karma işlevi yaklaşımıyla gittim ... Sanırım girdi işlemenin ne kadar karmaşık olacağını (regex yaklaşımı üzerinden, sayıyı umursamayacak kadar) küçümsedim.


1

@ FryAmTheEggMan'ın cevabına dayanarak, farklı bir test yöntemiyle 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

Ben printve biçimlendirilmiş dizgeye bir boşluk eklemeniz gerektiğini düşünüyorum . Ayrıca lambda'yı s=lambda x:x and C.get(x,s(x[:-1]))or 0karakter kaydedecek şekilde yeniden yazabilirsiniz (boşluklarla birlikte). Bu oldukça temiz bir fikir, btw :)
FryAmTheEggman

teşekkürler, bir süredir her zaman ayrıntılı buluyorum ama hiçbir and/orşey düşünmedim bu üçlü gösterimle kemanladım .
njzk2

Evet, burada öğrendim :) Aynı zamanda "yarı egemen" gibi, boşlukları olan para birimleri için u.split(' ')söz etmeniz gerektiğini düşünüyorum u.split(' ',1).
FryAmTheEggman

bu yüzden nedeni , 1!
njzk2

2
Üçlü , Falsey'in ne zaman olduğu ya da eşdeğer olduğu için x and y or 0genel olarak kısaltılabilir . x and y0Falsex
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)}

Bu, her para biriminin değerini, en genişinden başlayarak çeşitli regex'lere göre kontrol ederek alır /t/; Başka bir eşleşme ile karşılaşıldığında değerin üzerine yazılır. Regex dizesini yeniden düzenleyerek birkaç byte'ı tıraş etmenin bir yolu olabilir. Yukarıdaki kod parçasını kullanarak test edebilirsiniz (Yalnızca iletişim kutularını kullanmak ve ES6 ok işlevlerini kaldırmak için biçimlendirilmiştir, böylece herkes kodu kolayca test edebilir). Önerileriniz için Alconja'ya teşekkürler.


1
Sen kırpabilirsiniz 2 kullanarak karakter 't0sh|bo0^p....'.split(0), 4 kullanarak daha .mapyerine .forEachve 3 daha arayarak c(0)ve c(1)ve yapıyors[d].match
Alconja
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.