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\$
7
  • 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\$ Jun 24, 2016 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\$ Jun 24, 2016 at 14:27
  • 1
    \$\begingroup\$ Ok @Adnan, I'll do that. Done. \$\endgroup\$
    – Daniel
    Jun 24, 2016 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\$ Jun 24, 2016 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, 2016 at 15:12

11 Answers 11

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\$
0
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\$
6
  • \$\begingroup\$ How about [1.1_.27+.15]? \$\endgroup\$
    – Lynn
    Jun 24, 2016 at 20:47
  • \$\begingroup\$ @Lynn thats genius! Thanks! \$\endgroup\$
    – GamrCorps
    Jun 24, 2016 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, 2016 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, 2016 at 5:37
  • \$\begingroup\$ Why the last 55 bytes mark is struck out? Also, typo in definetely - definitely. \$\endgroup\$
    – user48538
    Jun 25, 2016 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\$
7
  • 2
    \$\begingroup\$ you don't need to do your own rounding, .format() does it for you if you do ${:,.2f} \$\endgroup\$
    – Maltysen
    Jun 24, 2016 at 18:22
  • \$\begingroup\$ @Maltysen Thanks! I did not know I could do that! :) \$\endgroup\$
    – R. Kap
    Jun 24, 2016 at 18:23
  • \$\begingroup\$ 46:0 replaces dots with NUL characters. \$\endgroup\$
    – vaultah
    Jun 25, 2016 at 7:22
  • \$\begingroup\$ @vaultah So what? It works for Euro inputs. \$\endgroup\$
    – R. Kap
    Jun 25, 2016 at 8:45
  • \$\begingroup\$ @vaultah Well, it works perfectly fine on Ideone and my computer. \$\endgroup\$
    – R. Kap
    Jun 25, 2016 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\$
2
  • \$\begingroup\$ I could only test this on Firefox. Can you give me a link to Firefoex? \$\endgroup\$ Jun 25, 2016 at 15:58
  • \$\begingroup\$ @NoOneIsHere Google "Firefoex", it will give you the correct link even if it's misspelled \$\endgroup\$
    – edc65
    Jun 25, 2016 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\$
5
  • 2
    \$\begingroup\$ char c=a.charAt(0) (all in all you don't need c at all, see my answer) \$\endgroup\$
    – edc65
    Jun 24, 2016 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, 2016 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\$ Jun 25, 2016 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, 2016 at 11:37
  • 1
    \$\begingroup\$ Just saw we don't need d anymore as it is only used once. \$\endgroup\$
    – Frozn
    Jun 25, 2016 at 14:40
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\$
2
  • \$\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\$ Jun 24, 2016 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, 2016 at 18:55
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\$
2
  • \$\begingroup\$ Why don't you delete the 0 from 1.10 to save 1 byte? \$\endgroup\$
    – Daniel
    Jun 25, 2016 at 1:15
  • \$\begingroup\$ Maybe you can skip the . in the ratios and divide by 1e4 \$\endgroup\$
    – agtoever
    Jun 25, 2016 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\$
1
  • 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\$ Jun 24, 2016 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\$
1
  • \$\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, 2016 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.