14
\$\begingroup\$

As the title -- although discretely -- hints, I only pay with dollars.

The challenge

Write a function/program that takes a string as input, which is a monetary value preceded by a symbol. ex) £4.99. Then, return that same amount converted to USD.

Input

You will get a string as input. It will have the currency symbol followed by a number with two decimal places (which could be .00). There will either be decimal points . and/or commas , separating the number. The following currency symbols will come in the inputs:

Euro: €
Pound Sterling: £
Yuan Renminbi: ¥

Also, there will be a comma or decimal point depending on the currency to separate the 'dollars' from the 'cents':

Euro: #.###,##
Pound Sterling: #,###.##
Yuan Renminbi: #,###.##

Output

You will convert the input from the currency determined by the symbol to USD, rounding to two decimal places. The output will be in the format $#,###.##, and there will of course be more numbers on the left of the output if need be (EDIT: this means that there is an arbitrary number of commas in the output, just like in the input). The currency exchange rate we will be using are below.

You can assume that the input contains a symbol that is only one of the above (€ £ ¥ . ,)--that it is always valid.

Exchange rates

€1 : $1.10
£1 : $1.37
¥1 : $0.15

Examples

Input:
€1,37
£4.00
¥2,782,122.78

Respective output:
$1.51
$5.48
$417,318.42

Final words

  1. If you use one of the above symbols (€, £, ¥), you may count them as 1 byte
  2. This is code golf, so shortest code in bytes wins!
\$\endgroup\$
  • 1
    \$\begingroup\$ If you want to use true l10n, renminbi should have a comma delimiter at the 10k mark, not at the 1k mark. (e.g., 10,0000.15) \$\endgroup\$ – Not that Charles Jun 24 '16 at 14:27
  • 24
    \$\begingroup\$ It's funny that if you've posted this question yesterday, the English Pound's exchange rate would have been £1 : $1.51 xD \$\endgroup\$ – Kevin Cruijssen Jun 24 '16 at 14:27
  • 1
    \$\begingroup\$ Ok @Adnan, I'll do that. Done. \$\endgroup\$ – Daniel Jun 24 '16 at 14:35
  • 2
    \$\begingroup\$ Hmm, is that output correct? 1.37 * 1.10 = 1,507 = 1,51 (so not 1.52) and 4.00 * 1.37 = 5.48 (not 5.50) and 2782122.78 * 0.15 = 417318.417 = 417318.42 (not 420165.06)... :S \$\endgroup\$ – Kevin Cruijssen Jun 24 '16 at 15:00
  • 1
    \$\begingroup\$ @KevinCruijssen, I just realized that, when using Google to convert, the exchange rate had already changed. Fixed it. \$\endgroup\$ – Daniel Jun 24 '16 at 15:12

11 Answers 11

1
\$\begingroup\$

Pyth - 54 53 48 47 bytes

Forgot about conditional application W.

.F"${:,.2f}"*v-tXWqhQ\€Q",.")\,@[1.1.15d1.37)Ch

Test Suite.

\$\endgroup\$
  • \$\begingroup\$ Hmm.. is it me or is this a pretty big answer for Pyth in terms of bytes? o.Ô It's almost 1/4th of my Java answer! (Usually it's 1/50th or so.. xD) \$\endgroup\$ – Kevin Cruijssen Jun 24 '16 at 18:53
  • 1
    \$\begingroup\$ @KevinCruijssen yeah, the string formatting and the raw currency data make up almost half the size. \$\endgroup\$ – Maltysen Jun 24 '16 at 18:55
5
\$\begingroup\$

Python 3.6 (pre-release), 87

lambda s:f"${int(s.translate({46:'',44:''})[1:])*[110,15,0,137][ord(s[0])%4]/1e4:,.2f}"

Uses f-strings to evaluate the result and format it.

s.translate({46:'',44:''}) removes dots and commas from s, thus making it a valid int literal, then int(...) converts it into the actual int object.

\$\endgroup\$
4
\$\begingroup\$

Convex, 56 55 54 bytes

(\®\.|,"ö)\e_\'.\++~\"€£¥"#[1.1_.27+.15]=*"%,.2f"\Ø'$\

Well, this can definitely be shortened. Try it online!

Saved a byte thanks to Lynn!

Explanation to come when I can get access to a computer.

\$\endgroup\$
  • \$\begingroup\$ How about [1.1_.27+.15]? \$\endgroup\$ – Lynn Jun 24 '16 at 20:47
  • \$\begingroup\$ @Lynn thats genius! Thanks! \$\endgroup\$ – GamrCorps Jun 24 '16 at 20:49
  • \$\begingroup\$ "Explanation to come when I can get access to a computer," implying that that little nugget of awesome unreadability was written on a mobile device. well done, learned scholar. well done. \$\endgroup\$ – strugee Jun 25 '16 at 5:35
  • 1
    \$\begingroup\$ @strugee Yeah, Ive been out all day but I have made a CP-1252 keyboard for my iPhone for this purpose. \$\endgroup\$ – GamrCorps Jun 25 '16 at 5:37
  • \$\begingroup\$ Why the last 55 bytes mark is struck out? Also, typo in definetely - definitely. \$\endgroup\$ – user48538 Jun 25 '16 at 7:31
3
\$\begingroup\$

Python 3.5, 137 131 121 120 117 bytes:

(Thanks to Maltysen for a hint on saving 6 bytes (137 -> 131)!)

lambda u:'${:,.2f}'.format(float(u[1:].translate([{44:''},{44:46,46:''}]['€'in u]))*{'€':1.1,'£':1.37,'¥':.15}[u[0]])

Try It Online! (Ideone)

\$\endgroup\$
  • 2
    \$\begingroup\$ you don't need to do your own rounding, .format() does it for you if you do ${:,.2f} \$\endgroup\$ – Maltysen Jun 24 '16 at 18:22
  • \$\begingroup\$ @Maltysen Thanks! I did not know I could do that! :) \$\endgroup\$ – R. Kap Jun 24 '16 at 18:23
  • \$\begingroup\$ 46:0 replaces dots with NUL characters. \$\endgroup\$ – vaultah Jun 25 '16 at 7:22
  • \$\begingroup\$ @vaultah So what? It works for Euro inputs. \$\endgroup\$ – R. Kap Jun 25 '16 at 8:45
  • \$\begingroup\$ @vaultah Well, it works perfectly fine on Ideone and my computer. \$\endgroup\$ – R. Kap Jun 25 '16 at 8:48
3
\$\begingroup\$

JavaScript (ES6), 107

Simple and straightforward, probably more golfable

Note: tested in FireFox. Many browsers (especially mobile) have buggy support of toLocaleString

a=>(a.replace(/\D/g,'')/1e4*(a<'¥'?137:a>'€'?110:15)).toLocaleString('en',{style:'currency',currency:'USD'})

TEST

function test()
{
  var i=I.value
  var F=a=>(a.replace(/\D/g,'')/1e4*(a<'¥'?137:a>'€'?110:15)).toLocaleString('en',{style:'currency',currency:'USD'})
  O.textContent=F(i)
}

test()
<input id=I value='¥2,782,122.78' oninput='test()'>
<pre id=O></pre>

\$\endgroup\$
  • \$\begingroup\$ I could only test this on Firefox. Can you give me a link to Firefoex? \$\endgroup\$ – NoOneIsHere Jun 25 '16 at 15:58
  • \$\begingroup\$ @NoOneIsHere Google "Firefoex", it will give you the correct link even if it's misspelled \$\endgroup\$ – edc65 Jun 25 '16 at 21:16
3
\$\begingroup\$

Java 7, 240 227 215 211 207 202 199 196 bytes

(201 - 2 bytes because of the rule "If you use one of the above symbols (€, £, ¥), you may count them as 1 byte")
Thanks to @Frozn for saving a lot of bytes.

String c(String a){int c=a.charAt(0);return java.text.NumberFormat.getCurrencyInstance(java.util.Locale.US).format(new Long(a.substring(1).replaceAll(",|\\.",""))*(c<'¥'?1.37:c>'¥'?1.1:.15)/100);}

Ungolfed & test code:

Try it here.

class Main{
  static String c(String a){
    int c = a.charAt(0);
    return java.text.NumberFormat.getCurrencyInstance(java.util.Locale.US)
        .format(new Long(a.substring(1).replaceAll(",|\\.","")) *
                 (c < '¥'
                   ? 1.37
                   : c > '¥'
                     ? 1.1
                     : .15
                  ) / 100);
  }

  public static void main(String[] a){
    System.out.println(c("€1,37"));
    System.out.println(c("£4.00"));
    System.out.println(c("¥2,782,122.78"));
  }
}

Output:

$1.51
$5.48
$417,318.42
\$\endgroup\$
  • 2
    \$\begingroup\$ char c=a.charAt(0) (all in all you don't need c at all, see my answer) \$\endgroup\$ – edc65 Jun 24 '16 at 15:57
  • 1
    \$\begingroup\$ By pulling the d * out of the ternary you save some duplication. Looks like this: d*(c=='€'?1.1:c=='£'?1.37:.15)/100. \$\endgroup\$ – Frozn Jun 25 '16 at 11:04
  • \$\begingroup\$ @Frozn Thanks. Also, unfortunately /100 and *.01 is the same amount of bytes, and c=='€'?.011:c=='£'?.0137:.0015 is also the exact same as with the /100. \$\endgroup\$ – Kevin Cruijssen Jun 25 '16 at 11:19
  • 1
    \$\begingroup\$ Yeah that's bad. But here is the good news: Thanks to the unique unicode values of the currency signs you can shorten it because '£' < '¥' < '€'. Thus you can write c<'¥'?1.37:c>'¥'?1.1:.15 which is 2 characters shorter. \$\endgroup\$ – Frozn Jun 25 '16 at 11:37
  • 1
    \$\begingroup\$ Just saw we don't need d anymore as it is only used once. \$\endgroup\$ – Frozn Jun 25 '16 at 14:40
1
\$\begingroup\$

F#, 198 bytes

(s:string)="$"+(System.Double.Parse(if s.[0]='€'then s.[1..].Replace(".","").Replace(',','.')else s.[1..].Replace(",",""))*(if s.[0]='€'then 1.1 else if s.[0]='£'then 1.37 else 0.15)).ToString("N2")

Un-Golfed:

let IOnlyUseDollars(s : string) = 
    let cur = s.[0]
    let str = if cur = '€' then s.[1..].Replace(".","").Replace(',', '.') else s.[1..].Replace(",","")
    let amt = System.Double.Parse(str)
    let dol = amt * (if cur = '€' then 1.1 else if cur = '£' then 1.37 else 0.15)
    "$" + dol.ToString("N2")

I'm still trying to figure out F#, so dealing with the thousands separators is taking up a lot of bytes.

According to the challenge rules, the Euro, Yen, and Pound symbols count as one byte each, despite how Unicode stores them internally.

\$\endgroup\$
1
\$\begingroup\$

Python 3.5, 101 98

lambda x:'${:,.2f}'.format(int(x[1:].translate({44:'',46:''}))*{'€':110,'£':137,'¥':15}[x[0]]/1e4)

The Euro, Pound, and Yen symbols are counted as 1 byte/character each, per the challenge rules.

Instead of translating among or interpreting thousands and decimal separators, these are just stripped out to give a plain digit string.

The digit string (after the currency symbol) is converted to an integer.

The currency symbol is used as an index into a dictionary of conversion rates; the conversion is performed by multiplying by the conversion rate and dividing by 10000.

The result is formatted with a leading dollar sign, two decimal places of precision, and commas for grouping.

\$\endgroup\$
  • \$\begingroup\$ Why don't you delete the 0 from 1.10 to save 1 byte? \$\endgroup\$ – Daniel Jun 25 '16 at 1:15
  • \$\begingroup\$ Maybe you can skip the . in the ratios and divide by 1e4 \$\endgroup\$ – agtoever Jun 25 '16 at 12:14
0
\$\begingroup\$

Python 3, 112 bytes NOT COMPETING

def c(x):x=x.translate(None,",.");print“$”+‘{:,.2f}’.format([1.1,1.37,0.15][“€£¥”.index(x[0])]*int(x[1:])/100,2)

This is not competing because I do not think that I am allowed to answer my own question.

Also, I have not yet had a chance to run this on a computer, but it seems to me like it should work. I will run it on a computer as soon as I have a chance.

\$\endgroup\$
  • 4
    \$\begingroup\$ You are completely fine to answer your own question. Some people even come up with an answer before making the question itself. Usually they still get beaten by golfing languages like Jelly, Pyth, Pyke and alike, though. ;) \$\endgroup\$ – Kevin Cruijssen Jun 24 '16 at 21:13
0
\$\begingroup\$

PHP, 117 bytes

function f($s){return'$'.number_format(ereg_replace('[^0-9]','',substr($s,1))*[E=>.011,P=>.0137,Y=>.0015][$s[0]],2);}

This makes use of a deprecated function; replace ereg_replace('[^0-9]' with preg_replace('%[^\d]%' to make the code fully modern; adds 1 byte.

\$\endgroup\$
0
\$\begingroup\$

CJam, 54 bytes

'$q(\",."-de-2\"€£¥"#[1.1 1.37 .15]=*2mOs'./~\3/',*'.@

Try it here!

\$\endgroup\$
  • \$\begingroup\$ Nice answer, and welcome to the site! Just so you know, there is an online CJam interpreter here You could link to that in your post to make it easier for reader to run/test your answer. \$\endgroup\$ – DJMcMayhem Jun 25 '16 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.