合計3ペニーに何匹のギニアがいますか?


32

1971年の10進数化まで、英国のお金はポンドを240ペニーに分割することに基づいていました。シリングは12ペニーでしたので、20シリングはポンドになりました。最小額面は、ペニーの4分の1のファージングでした。コインには他にも多くの宗派やニックネームがありましたが、システムに慣れていない場合はかなり混乱する可能性があります。

チャレンジ

(ほとんど)古い英語の金銭を他の金銭に変換できるプログラムまたは関数を作成します。ユーザーが使いやすくするには、複数形とニックネームをサポートする必要があります。

これらはあなたが支持しなければならない宗派とそれらの同義語です。便宜上、ファージングでの価値が各ラインをリードしています。

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は、上記のリストの任意の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
「ペニー」は、金額ではなく、多くのコインを指すためにのみ使用されます。
— デビッドリチャービー14年

4
Nit-pick:10進数化後、複数形はquidですquid。おそらく、これは古いお金でも同じだったでしょう。例:Five quid a pint! Cor blimey guvnor。例外:クイッドイン
— デジタルトラウマ14年

7
私はおそらく「ha'penny」を含めるように要求する多くの人々を台無しにします。
— ケイン14年

3
@kaineというha'penny以外のものと呼ばれるha'pennyを聞いたことがありません。同様にen.wikipedia.org/wiki/Ha%27penny_Bridge。もちろん、私はあまりにも頻繁にスピーチでそれを聞いたことがありませんが、アポストロフィは書面で標準的なようです。
— TRiG 14年

回答:


9

ピス、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。他に何も変更する必要はありません。

使い方:

  • これは、最初の2文字を使用して通貨の値を検索する@xnorのアプローチと、イニシャルhalfまたはを検出してtwo削除し、関数を再度呼び出すトリックを使用します。

  • 最初の2文字の値を検索するには、文字列内の通貨の最初の2文字の位置を見つけ、2で除算してリスト内のそのインデックスの値を取得します。これはpythのdictよりもはるかに短いです。

  • x(文字列内の検索)失敗時に-1を返すという事実を使用して、文字列にpo(ポンド)qu(quid)またはso(sovereigns)を入れないようにし、デフォルトでリストの最後の要素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
私はあきらめます...;)
— マーティンエンダー14年

私は知りませんでした<と>、文字列/リストのスライスオペレーターとして働いていました。それは、頭やチョップの終わりを取るよりもはるかに良いです:)
— FryAmTheEggman

@FryAmTheEggmanも同様にドキュメントから欠落しているように見えます-私はそれを追加しました。
— isaacg 14年

macros.pyをより注意深く読む必要があります:)
— FryAmTheEggman

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に出力します。

短い正規表現を使用して、各値に必要な額面のみを一致させています。対応するインデックスには、正規表現と値を持つ2つの配列があります。正規表現配列はスペースで区切られた配列リテラルであり、値配列はUTF-8文字の文字列にパックされます。

各金種に一致する正規表現を検索して、値のインデックスを選択しています。また、最長正規表現を必要とするため、tuppence / half-groatの場合(値8)にデフォルト設定しています。同様に、一部のパターンでは、他の値が以前のパターンとすでに一致していると想定しているため、各正規表現は目的の値と残りの値のみを区別します。これを使用すると、金種の順序を並べ替えることで、おそらくさらに数バイトを削ることができます。

私を助けるためVenteroのおかげでPythを打つ、それより短くなって!


1
s[k]上書きするのは正規表現マッチング()です$1。マップブロックをラムダに移動し、最後の行でそれを直接呼び出すことにより、いくつかの文字を保存できます(これにより、$1and の割り当てを削除することもできます$2)。も.indexより短いです.find_index。
— ヴェンテロ14年

@Ventero Ah、それは理にかなっています。ありがとうございました!
— マーティンエンダー14年

1
Regexp.new k→ /#{k}/と$><<gets.sub(/foo/){a=$3;...}→ gets[/foo/];a=$3;puts...合計221。そしてもちろん、int配列を文字列にパックし(を使用.pack("U*"))、その文字列にインデックスを付けるという古いトリックを使用できます。195文字/ 200バイトになります。
— ヴェンテロ14年

さらに良い:a=gets[/foo/,3]
— Ventero 14年

@Venteroどうもありがとう。印刷できないASCIIを避けるために文字コードにオフセットを追加したため、196/202になりました。Pythよりもまだ短い。;)
— マーティン・エンダー14年

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最初の2文字を見つけることにより、辞書を使用して最初の2文字をフィンガープリントすることにより、通貨文字列のシリング値を取得します。プレフィックス「half」と「two」は、プレフィックスとスペースを切り取り、乗数を適用することで検出および説明されます。「halfpenny」には「half」の後にスペースがないため、これは「enny」になりますが、架空の「en」エントリで処理されます。

辞書検索を大幅に改善してくれた@isaacgと@grcに感謝します。


私はそれができることを知っていました:)私はあなたがそのような辞書を定義できることを知らなかったことも非常に恥ずかしいです...:S
— FryAmTheEggman 14年

2
@FryAmTheEggmanこのサイトの回答で使用されるのを見るまで、キーワードで辞書を定義することはできませんでした。あなたがゴルフを学ぶ事...
— XNOR

これのPythバージョンを作成し、207文字を得ました。コミュニティWikiの回答を追加または投稿するためにここに投稿しますか?
— FryAmTheEggman 14年

1
その2/4**(c<'t')部分に+1 。
— njzk2

1
.get(c[:2],960)辞書から値を検索し、辞書po=960,so=960,qu=960,からエントリを省略することで、13文字を保存できます。
— isaacg 14年

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

入力番号はPythonのフロートである必要があります 144.1

私はこれがPython 3で短縮できると思います...

... @ xnorに感謝します。また、より良いアルゴリズムを持つことが重要であることを確認しました;)


私が代わるq=raw_input().split(' in ')ことでq,b=raw_input().split(' in ')
— njzk2

@ njzk2まったく正しい...次の行にもこれを使用しました、今:)
— FryAmTheEggman 14年

私は間に矛盾があると思うh+' gr':8し、h+' g':504半分割りのために最初に評価され、誰に応じて
— njzk2

@ njzk2本当のこと...追加uモルモット1 ...に
— 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])

ハッシュ関数アプローチを使用しました...入力処理がどれほど複雑になるかを(比較的)過小評価したと思います(正規表現アプローチよりも、数値を気にしません)。


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文字を(スペースとともに)保存するためにラムダを書き換えることもできます。これはかなりきちんとしたアイデアです、ところで:)
— FryAmTheEggman 14年

おかげで、私はしばらくこの三項表記法をいじりました。これは常に冗長であるとand/or思いますが、そのことには関係しませんでした。
— njzk2 14年

ええ、私はここでそれを学びました:)また、「ハーフソブリン」のようなスペースを持つ通貨についてもu.split(' ')発言する必要があると思いますu.split(' ',1)。
— FryAmTheEggman 14年

それが理由です, 1!
— njzk2

2
3項x and y or 0は一般にに短縮できます。これはx and y、どちらがFalseyである0か、または同等Falseに評価されるためxです。
— xnor 14年

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.