# User:IMalc/Punctured Elias codes

Punctured Elias Codes are a universal code developed by Peter Fenwick[1]. They are based upon Elias Gamma codes, but with some major differences. Fenwick describes two variations, P1 and P2. In variation P1 the data bits are written in reverse order, and are preceeded by a zero-terminated sequence of ones, to indicate the number of 1 bits. Zero is encoded as-is with no following bits. Unlike the Elias gamma code, it is not possible to merge the last bit of the prefix with the most significant data bit.

The feature of counting only the number of ones in the number being encoded rather than counting the total number of binary digits leads to codes that are not of strictly increasing length with respect to the number being encoded. This is most noticable when comparing the encoding of 2N-1 and 2N e.g. 15 and 16.

The P1 code begins:

``` 0 0
1 10 1
2 10 01
3 110 11
4 10 001
5 110 101
6 110 011
7 1110 111
8 10 0001
9 110 1001
10 110 0101
11 1110 110
12 110 0011
13 1110 1011
14 1110 0111
15 11110 1111
16 10 00001
17 110 10001
```

In variation P2, each number n is coded as n+1, and because there will then always be at least one bit that is a 1, the leftmost 1 of the resulting code is omitted.

The P2 code begins:

``` 0 0 1
1 0 01
2 10 11
3 0 001
4 10 101
5 10 011
6 110 111
7 0 0001
8 10 1001
9 10 0101
10 110 110
11 10 0011
12 110 1011
13 110 0111
14 1110 1111
15 0 00001
16 10 10001
```

## Encoding

To P1 encode a number:

1. If the number is zero, encode a zero and stop. Otherwise:
2. Count the number of 'one' bits in the binary representation of the number (K).
3. Output (K) one bits.
4. Append a zero bit.
5. Append the number in binary from least significant bit to least significant bit (i.e. backwards).

## Decoding

To P1 decode a Punctured Elias delta-coded integer:

1. Read and count ones from the stream until you reach the first zero. Call this count of zeroes N.
2. If there were no ones encountered before the zero, then output zero and stop. Otherwise:
3. Continue reading bits until N more 1 bits have been found. As each bit is read, prepend it to the result.

P1 Example:

```11101101
1. three leading ones found in: 1110
2. continue reading until three more one bits are found: 1101
3. store these bits in the reverse order: 1011
3. encoded number = 1011 = 1110
```