# Ruby, <s>169</s> <s>164</s> 148 bytes

<!-- language-all: lang-ruby -->

    ->a{s=eval a*?^
    c=?@
    m={}
    a.map{|x|z=x-(x^s);[$><<?-*z,x-=z,s=0]if z>0
    n=1
    eval'x&1>0?[$><<(m[n]||c.next!)*n,m[n]=!m[n]&&c*1]:0;n*=2;x/=2;'*x
    puts}}

[Try it online!](https://tio.run/##bY3vasJAEMS/31OsUKIeG71LTW2Nm/ge4QLXYKDQHGJUzvx59jSXVrDil4H9zczO8fx57Qug3o91U9H@or9B8yRjOSU7VlLTMb0o9aFpbVuT9Wc2q@ZR@hJvt4nPa7Q@1ViRUF8F1LFghiRzT6bWk7FIxuCsTI1q23xh9vY0mXODDtDEqeflXKqNiAynILLLQabcssP5VHVdX6SpRHhFCBHWSkXgOPulwWisRu9tsBHeET4QpLgP/msNyfD@Xj0pyAEGbjR82Psbu9H@Bw)

First, we initialize

 * the nim-sum with `s=eval a*?^` (which is shorter than `a.reduce:^`)
 * the variable `c`, which stores the first unused unique character
 * a map `m` that maps power-of-two lengths to characters used to represent them

Then, looping over each pile, we run the following:

    z=x-(x^s);[$><<?-*z,x-=z,s=0]if z>0

Per [Wikipedia's strategy](https://en.wikipedia.org/wiki/Nim#Mathematical_theory), if *nim-sum XOR pile* is less than *pile*, we should remove stones from that pile such that its length becomes *nim-sum XOR pile*. By storing the difference in the variable `z`, we can test to see whether this difference is positive, and if so 1.) print that many dashes, 2.) subtract it from the pile, and 3.) set the nim-sum variable to zero to prevent further stone removal.

    n=1
    eval'[...];n*=2;x/=2;'*x

Now we "loop" over each bit and keep track of their values by repeatedly dividing `x` by `2` and multiplying the accumulator `n` by `2`. The loop is actually a string evaluated `x` times, which is far greater than the `log2(x)` times it's necessary, but no harm is done (aside from inefficiency). For each bit, we run the following if the bit is 1 (`x&1>0`):

    $><<(m[n]||c.next!)*n

Print a character `n` times. If we already printed an unpaired group of this many stones, use that character; otherwise, use the next unused character (advancing `c` in-place due to the `!`).

    m[n]=!m[n]&&c*1

If `m[n]` existed (i.e. we just completed a pair), then `m[n]` is reset. Otherwise, we just started a new pair, so set `m[n]` to the character we used (`*1` is a short way to make a copy of `c`).