# Alice and Bob have a fight

## Python 3, 131 bytes

```
x,y="AB"
from random import*
X=Y=10
p=print
while X>0:p(x,"a",y);d=randint(1,6);p(x,"r",d);Y-=d;p(y,"h",Y);x,y,X,Y=y,x,Y,X
p(y,"w")
```

Try it online!

-8 bytes thanks to officialaimm

-2 bytes thanks to ChooJeremy

## Python 3, 127 bytes

*This is an improvement on @HyperNeutrino answer that wouldn't fit in a comment. See the explanation below.*

```
x,y="AB"
s=id(0)
X=Y=10
p=print
while X>0:p(x,"a",y);s=s**7%~-2**67;d=s%6+1;p(x,"r",d);Y-=d;p(y,"h",Y);x,y,X,Y=y,x,Y,X
p(y,"w")
```

Try it online!

### An epic quest for a shorter python dice roll

**TL;DR: It's possible to shave 4 bytes off the standard python dice roll by using RSA encryption.**

I wanted to see if the standard python dice roll (**32 bytes**) could be shortened a bit:

```
from random import*;randint(1,6)
```

In particular, `id(x)`

is quite convenient to bring some non-deterministic value into the program. My idea then was to somehow hash this value to create some actual randomness. I tried a few approaches, and one of them paid off: RSA encryption.

RSA encryption, due to its simplicity, only requires a few bytes: `m**e%n`

. The next random value can then be created by encrypting the previous one. Assuming the `(e,n)`

key is available, the dice roll can be written with **22 bytes**:

```
s=id(0);s=s**e%n;s%6+1
```

That means we have about 10 bytes to define a valid RSA key. Here I got lucky. During my experiments, I started to use the Mersenne prime **M67** only to realize later on that Mersenne made a mistake including **M67** in his list. It turns out to be the product of `p=193707721`

and `q=761838257287`

. I had found my modulus:

```
n=~-2**67
```

Now, the exponent and the Charmichael totient `lcm(p-1,q-1)`

need to be coprime. Luckily again, the first prime number that do not divide the totient of n is only one digit long: 7. The dice roll can then be written using **28 bytes** (4 bytes less than the standard approach):

```
s=id(0);s=s**7%~-2**67;s%6+1
```

One good thing with **M67** is that the random value generated has 66 bits, which is more than the usual 64 bits RNG. Also, the use of RSA makes it possible to go back in time by decrypting the current value multiple times. Here are the encrypting and decrypting keys:

```
Encryption: (7, 147573952589676412927)
Decryption: (42163986236469842263, 147573952589676412927)
```

I'm definitely not an expert in statistics or cryptography, so I can't really tell whether or not this RNG checks the criteria for "good randomness". I did write a small benchmark that compares the standard deviation of the occurrences of the 1 to 6 dice rolls using different RNGs. It seems like the proposed solution works just like other ones.

## C (gcc), ~~146~~ 141 bytes

```
f(A,B,r,t,a,b){for(A=B=10;r=1+clock()%6,A*B>0;t=!t)printf("%c a %c\n%c r %u\n%c h %i\n",a=65+t,b=66-t,a,r,b,t?A-=r:(B-=r));printf("%c w",a);}
```

Try it online!

De-golf:

```
f(A,B,r,t,a,b){
for(A=B=10; //Initialize HP
r=1+clock()%6, // Get the number of processor cycles the program has consumed. This is relatively random, so I call it good enough.
A*B>0;t=!t) // Flip t for change of turns
printf("%c a %c\n%c r %u\n%c h %i\n", // Print the turn
a=65+t,b=65+!t,a,r,b, // 65 is ASCII for 'A', 66 for 'B'
t?A-=r:(B-=r)); // Deduct the damage.
printf("%c w",a); // Print the winner
}
```