# Battle of the letters

Your task is simple: tell me who wins the battle of the letters.

# The troops

There are three different "troops" in this battle, summarized by this table.

name | health | damage
A       25       25
B      100        5
C       10       50


You may use any three unique characters to represent the the troops, but must specify if they are not these letters.

# The battle

Suppose we have a sample battle:

ABC # army 1
CBA # army 2


Each army repeatedly fires at the leftmost unit, until it is dead; then they move to the troop to the right and repeat. So army 2 attacks A in army 1 until A is dead, then move to B, then C. Army 1 attacks C first, then B, then A. Assume the armies attack at the same time, and thus troops will always fire if they were alive before the round and can kill each other at the same time. They fire in order from left to right.

The battle would play out as so:

ABC
CBA

BC # A (25 hp) killed by C (-50 hp), B (100 hp) attacked by B (-5 hp) and A (-25 hp), has 70 hp
BA # C (10 hp) killed by A (-25 hp), B (100 hp) attacked by B (-5 hp) and C (-50 hp), has 45 hp

BC # B (70 hp) attacked by B (-5 hp) and A (-25 hp), has 40 hp
A  # B (45 hp) killed by B (-5 hp) and C (-50 hp)

BC # B (40 hp) attacked by A (-25 hp), has 15 health
# A (25 hp) killed by B (-5 hp) and C (-50 hp), army 2 dead


Therefore, army 1 wins the battle!

# Input

Two strings, the first representing army 1 and the second army 2. They are not necessarily the same size (because who said it would be a fair fight?)

# Output

Any three unique, constant values to represent army 1 winning, army 2 winning, or the unlikely event of a tie. Yes, it is possible for the last troops to kill each other, ending in a tie.

# Battles

ABC
CBA
Army 1

CCCCC
CCCCC
Tie

CABCAB
ABBABBA
Army 2


Standard loopholes apply. You must submit a full program.

This is , shortest solution wins.

• "constant" Why? – CalculatorFeline Jun 1 '17 at 2:53
• Also, A beats B and C ties B and A ties C. Changing either of A's values to 20 would make it tie B. – CalculatorFeline Jun 1 '17 at 2:57
• Are we allowed to use a different input representation? Say, 012 instead of ABC? – Grimmy Jun 1 '17 at 9:19
• @Grimy: Yes, I will edit the post. – Neil A. Jun 1 '17 at 17:21

# Pyth145 97 bytes

=Y.d[,\A,25 25,\B,*TT5,\C,T*5T)Km=G@YdzJm=H@YdwW&KJMX0hG_smedH gKJ gJKI<hhK0=tK)I<hhJ0=tJ;?K1?J2Z


A little less naive than before.

Try it online!

# Explanations:

Let's cut the program in several parts.

=Y.d[,\A,25 25,\B,*TT5,\C,T*5T)

,\A,25 25                     Create this list: ['A', [25, 25]]
,\B,*TT5             Create this list: ['B', [100, 5]]
,\C,T*5T     Create this list: ['C', [10, 50]]
.d[                         )    From the three lists, create a dictionary whose keys are the letters, and values are the inner lists
=Y                                 Assign to the variable Y


The dictionary Y is: {'A': [25, 25], 'C': [10, 50], 'B': [100, 5]}. Then:

Km=G@YdzJm=H@YdwMX0hG_smedH

m=G@Ydz                           For all letters in first input string, make a copy of Y[letter]. Make a list of all those values...
K                                  ...and assign the list to the variable K
m=H@Ydw                   For all letters in second input string, make a copy of Y[letter]. Make a list of all those values...
J                          ...and assign the list to the variable J
MX0hG_smedH        Create a function g which takes two lists of couples, and subtract the sum of the second elements of the couples of the second list from the first element of the first couple of the first list


At this point, K is a list of couples that represents the first army. Each couple of this list is a letter of the army, and is (health, damage) for that letter. J is exactly the same, but for the second army. g is a function which takes two armies, and deals the damage made by the second army to the first one. Now:

W&KJ gKJ gJKI<hhK0=tK)I<hhJ0=tJ;

W&KJ                               While K not empty and J not empty
gKJ                           Call g(K,J). That computes the damages to first army
gJK                       Call g(J,K). That computes the damages to second army
I<hhK0=tK)             If the first army's first letter is dead, remove it
I<hhJ0=tJ    If the second army's first letter is dead, remove it
;   End of while loop


When the while loop is over, K and J have their final value. If they are both empty, it's a tie; otherwise the non-empty army win. That is handled by the last piece of code:

?K1?J2Z

?K1                                If K non-empty, display 1. Else...
?J2                             ...if J non-empty, display 2. Else...
Z                            ...display zero


That's it!

a!b=(t<$>a)?(t<$>b)
m=sum.map snd
f=filter((>0).fst)
[]?[]=0
[]?_=2
_?[]=1
a@((c,d):e)?b@((h,i):j)=f((c-m b,d):e)?f((h-m a,i):j)


Try it online!

Small trick: divided all the army stats by 5.

# C#, 446 Bytes

using System.Linq;(c,d)=>{int z=c.Length,v=d.Length,j=0,k=0,l=0,m=0,q=0;int[]e=(c+d).Select(x=>x!='A'?x=='B'?100:10:25).ToArray(),f=e.Skip(z).ToArray();e=e.Take(z).ToArray();int[]g=(c+d).Select(x=>x!='A'?x=='B'?5:100:25).ToArray(),h=g.Skip(z).ToArray();g=g.Take(z).ToArray();try{for(;;){for(q=l;q<z;q++){if(e[j]<=0)j++;e[j]-=h[q];}for(q=k;q<v;q++){if(f[m]<=0)m++;f[m]-=g[q];}if(e[k]<=0)k++;if(f[l]<=0)l++;}}catch{}return k-z>=l-v?k-z>l-v?0:2:1;};


Formatted version:

         (c, d) => {
int z = c.Length, v = d.Length, j = 0, k = 0, l = 0, m = 0, q = 0;

int[] e = (c + d).Select(x => x != 'A' ? x == 'B' ? 100 : 10 : 25).ToArray(), f = e.Skip(z).ToArray();
e = e.Take(z).ToArray();

int[] g = (c + d).Select(x => x != 'A' ? x == 'B' ? 5 : 100 : 25).ToArray(), h = g.Skip(z).ToArray();
g = g.Take(z).ToArray();

try {
for (;;) {
for (q = l; q < z; q++) {
if (e[j] <= 0) j++; e[j] -= h[q];
}
for (q = k; q < v; q++) {
if (f[m] <= 0) m++; f[m] -= g[q];
}
if (e[k] <= 0) k++; if (f[l] <= 0) l++;
}
}
catch {
}

return k - z >= l - v ? k - z > l - v ? 0 : 2 : 1;
};


Outputs 1 if army1 wins , 2 for army2 and 0 for tie

• Can you add a formatted/expanded version? 446 bytes is high even for C# I'm sure there will be some improvements. – TheLethalCoder Jun 1 '17 at 13:34
• For starters you have multiple lines declaring int[] I think you can combine them, <=0 is the same as <1 surely? Do you need the try-catch? – TheLethalCoder Jun 2 '17 at 8:15

# Javascript (ES6) - 316 269 Bytes

I'm sure this can be golfed like hell, but this is what I've come up with :) I managed to shave off 47 bytes though!

Outputs 0 for tie, 1 for Team 1 and 2 for Team 2.

l=(d,f)=>{for(t=[d,f].map(g=>g.split.map(k=>[[25,100,10],[25,5,50]].map(m=>m[k.charCodeAt()-65])));(w=t.map(g=>g.some(k=>0<k)))&&w;)t.forEach((g,k,m)=>m[k].sort(o=>0>o)-=m[+!k].filter(o=>0<o).reduce((o,p)=>o+p,0));return w||w?w?1:2:0}


function ltt(a,b){
t=[a,b].map(x=>x.split.map(c=>[[25,100,10],[25,5,50]].map(e=>e[c.charCodeAt()-65])))
while((w=t.map(_=>_.some(x=>x>0)))&&w){
t.forEach((y,i,n)=>n[i].sort(j=>j<0)-=n[+!i].filter(x=>x>0).reduce((h,v)=>h+v,0))
}
return(!w&&!w)?0:(w)?1:2
}


Demo:

l=(d,f)=>{for(t=[d,f].map(g=>g.split.map(k=>[[25,100,10],[25,5,50]].map(m=>m[k.charCodeAt()-65])));(w=t.map(g=>g.some(k=>0<k)))&&w;)t.forEach((g,k,m)=>m[k].sort(o=>0>o)-=m[+!k].filter(o=>0<o).reduce((o,p)=>o+p,0));return w||w?w?1:2:0}

var prnt=(g,h)=>{
n=l(g,h);
return(n==0)?"Tie!":Team \${n} wins!
}

console.log("ABCB - ABC: " + prnt("ABCB","ABC"));
console.log("BAAA - BBC: " + prnt("BAAA","BBC"));
console.log("AAAA - BBC: " + prnt("AAAA","BBC"));
console.log("ABC - BBC: " + prnt("ABC","BBC"));
console.log("ABC - CBA: " + prnt("ABC","CBA"));`

• Just noticed that current version can't evaluate ties, which the 316 byte version could. I'll look into it – Hankrecords Jun 5 '17 at 10:53