Integer Percentify

Dyalog APL, 21 19 16 bytes

+\⍣¯1∘⌊100×+\÷+/

The above is a train equivalent of

{+\⍣¯1⌊100×+\⍵÷+/⍵}

Try it online.

How it works

                 ⍝ Sample input: 1 1 2 4
           +\    ⍝ Cumulative sum of input. (1 2 4 8)
              +/ ⍝ Sum of input. (8)
             ÷   ⍝ Divide the first result by the second. (0.125 0.25 0.5 1)
       100×      ⍝ Multiply each quotient by 100. (12.5 25 50 100)
      ⌊          ⍝ Round the products down to the nearest integer... (12 25 50 100)
     ∘           ⍝ and ...
  ⍣¯1            ⍝ apply the inverse of...
+\               ⍝ the cumulative sum. (12 13 25 50)

TI-BASIC, 26 23 16 bytes

For TI-83+/84+ series calculators.

ΔList(augment({0},int(cumSum(ᴇ2Ans/sum(Ans

Thanks to @Dennis for a beautiful algorithm! We take the cumulative sum of the list after converting to percents, then floor, tack a 0 onto the front, and take differences. ᴇ2 is one byte shorter than 100.

At the same byte count is:

ΔList(augment({0},int(cumSum(Ans/sum(Ans%

Fun fact: % is a two-byte token that multiplies a number by .01—but there's no way to type it into the calculator! You need to either edit the source outside or use an assembly program.

Old code:

int(ᴇ2Ans/sum(Ans
Ans+(ᴇ2-sum(Ans)≥cumSum(1 or Ans

The first line calculates all floored percents, then the second line adds 1 to the first N elements, where N is the percentage left over. cumSum( stands for "cumulative sum".

Example with {1,1,2,4}:

          sum(Ans                  ; 8
int(ᴇ2Ans/                         ; {12,12,25,50}

                        1 or Ans   ; {1,1,1,1}
                 cumSum(           ; {1,2,3,4}
     ᴇ2-sum(Ans)                   ; 1
                ≥                  ; {1,0,0,0}
Ans+                               ; {13,12,25,50}

We won't have N>dim([list], because no percentage is decreased by more than 1 in flooring.


CJam, 25 23 22 bytes

{_:e2\:+f/_:+100-Xb.+}

Thanks to @Sp3000 for 25 → 24.

Try it online.

How it works

_                   e# Push a copy of the input.
 :e2                e# Apply e2 to each integer, i.e., multiply by 100.
    \               e# Swap the result with the original.
     :+             e# Add all integers from input.
       f/           e# Divide the product by the sum. (integer division)
        _:+         e# Push the sum of copy.
           100-     e# Subtract 100. Let's call the result d.
               Xb   e# Convert to base 1, i.e., push an array of |d| 1's.
                 .+ e# Vectorized sum; increment the first |d| integers.