Silly Stock Market

Given a string with a multiple people's investment data, find out how much profit/loss they recorded.

The string only contains capital and lowercase letters, like this:

AABaBbba


Each letter represents a person - a capital letter means buy, a lowercase letter means sell. The price of the stock they are investing in (CGLF) starts at $50. After someone buys, the price goes up 5%. After someone sells the price goes down 5%. You need to figure out how much money each person who participated made/lost. Notes: • The string will always be valid, no selling without first buying. Also, everyone who buys a stock will sell it eventually. • Your calculations should be accurate to at least 6 decimal places. However, final answers should be rounded to two decimals. Test Cases: Input: AABaBbba • A: Buy -$50
• A: Buy - $52.50 • B: Buy -$55.125
• a: Sell - $57.88125 • B: Buy -$54.9871875
• b: Sell - $57.736546875 • b: Sell -$54.8497195313
• a: Sell - $52.1072335547 • Person A profit: 57.88125+52.1072335547-50-52.50=7.4884835547 • Person B profit: 57.736546875+54.8497195313-55.125-54.9871875=2.4740789063 Output: A:7.49,B:2.47 (order doesn't matter, separators not required) Input: DGdg • D: Buy -$50
• G: Buy - $52.50 • d: Sell -$55.125
• g: Sell - $52.36875 • Person D profit: 55.125-50=5.125 • Person G profit: 52.36875-52.50=-0.13125 Output: D:5.13,G:-.13 Input: ADJdja • A: Buy -$50
• D: Buy - $52.50 • J: Buy -$55.125
• d: Sell - $57.88125 • j: Sell -$54.9871875
• a: Sell - \$52.237828125
• Person A profit: 52.237828125-50=2.237828125
• Person D profit: 57.88125-52.50=5.38125
• Person J profit: 54.9871875-55.125=-0.1378125

Output: A:2.24,D:5.38,J:-.14

• @ETHproductions When you print output, it doesn't really matter what the datatype is, it just needs to convey the right information. – geokavel Jan 12 '16 at 20:50
• Can the final result be truncated instead of rounded? – Mwr247 Jan 12 '16 at 22:08
• @Mwr Sorry, you have to round. – geokavel Jan 12 '16 at 22:11
• Do we have to output the people in alphabetical order? – PurkkaKoodari Jan 13 '16 at 10:32
• Also, Python rounds stuff weirdly; 5.125 rounds to 5.12 by default. Is this accepted? – PurkkaKoodari Jan 13 '16 at 10:45

Japt, 91 84 bytes

A=[]J=50¡AhD=Xc %H(X<'_?[AgD ª0 -JJ*=1.05]:[AgD +JJ*=.95] g};A£X©[Y+I d X*L r /L]} f


Based on my JS answer. Try it online!

Java, 277 bytes

class c{public static void main(String[]a){double[]m=new double[26];double s=50;for(byte b:a[0].getBytes()){if(b>=97){m[b-97]+=s;s*=.95;}else{m[b-65]-=s;s*=1.05;}}char g=65;for(double k:m){if(k!=0){System.out.println(g+String.format(java.util.Locale.ENGLISH,"%.2f",k));}g++;}}}


Ungolfed:

class c {
public static void main(String[]a) {
double[] m = new double[26];
double s = 50;
for(byte b : a[0].getBytes()) {
if(b>=97) {
m[b-97]+=s;
s*=.95;
} else {
m[b-65]-=s;
s*=1.05;
}
}
char g=65;
for(double k:m) {
if(k!=0) {
System.out.println(g+String.format(java.util.Locale.ENGLISH,"%.2f",k));
}
g++;
}
}
}

• A lot of the formatting is unnecessary. Having a 0 before the decimal point is o.k., commas and colons are not necessary. – geokavel Jan 12 '16 at 20:47
• great this reduces my byte count significantly – ByteBit Jan 12 '16 at 20:49
• The class doesn't need to be public. – a spaghetto Jan 12 '16 at 21:43
• Is specifying the Locale necessary? I don't mind if it shows up as "3,54". – geokavel Jan 13 '16 at 16:39
• Store your money in a float, this saves bytes and might get you some extra profit ;) – RobAu Jan 13 '16 at 16:54

JavaScript (ES7), 145 142 bytes

I can't find a shorter way to round out the results...

x=>[for(c of(i=50,a={},x))(a[d=c.toUpperCase()]=a[d]||0,c<"["?(a[d]-=i,i*=1.05):(a[d]+=i,i*=.95))]&&Object.keys(a).map(k=>[k,a[k].toFixed(2)])


Fun fact: this would only be 101 bytes if not for the rounding requirement:

x=>[for(c of(i=50,a={},x))(a[d=c.toUpperCase()]=a[d]||0,c<"["?(a[d]-=i,i*=1.05):(a[d]+=i,i*=.95))]&&a

• 43 bytes seems to much..I'm sure you can find a better way! – geokavel Jan 12 '16 at 21:08

Python 3, 116 bytes

P=50
M={}
for c in input():C=c.upper();u=c>C;u+=~-u;M[C]=M.get(C,0)+P*u;P*=1-u*.05
for k in M:print(k,round(M[k],2))


Ungolfed

price = 50
profits = {}
for char in input():
upper = char.upper()
direction = 2 * (char > upper) - 1
profits[upper] = profits.get(upper, 0) + price * direction
price *= 1 - direction * .05
for key in profits:
print(key, round(profits[key], 2))

• It seems shorter to just do u=2*(c>C)-1 directly. – xnor Jan 13 '16 at 21:11