13

Inspired by recent popularity of nandgame on TNB, and my own previous challenge.

## Background

Densely packed decimal (DPD) is a way to efficiently store decimal digits in binary. It stores three decimal digits (000 to 999) in 10 bits, which is much more efficient than naive BCD (which stores one digit in 4 bits).

### Conversion table

DPD is designed to easily convert between the bits and the digits by simple pattern matching from top to bottom. Each bit pattern defines how many high digits (8-9) the number has, where they are, and how to move the bits to form the decimal representation.

The following is the conversion table from 10 bits of DPD to three decimal digits. Each decimal digit is represented as 4-bit binary (BCD). Both sides are written left to right from the most significant digit to the least.

```
Bits => Decimal (Digit range)
a b c d e f
```**0** g h i => 0abc 0def 0ghi (0-7) (0-7) (0-7)
a b c d e f **1 0 0** i => 0abc 0def **100i** (0–7) (0–7) **(8–9)**
a b c g h f **1 0 1** i => 0abc **100f** 0ghi (0–7) **(8–9)** (0–7)
g h c d e f **1 1 0** i => **100c** 0def 0ghi **(8–9)** (0–7) (0–7)
g h c **0 0** f **1 1 1** i => **100c 100f** 0ghi **(8–9) (8–9)** (0–7)
d e c **0 1** f **1 1 1** i => **100c** 0def **100i** **(8–9)** (0–7) **(8–9)**
a b c **1 0** f **1 1 1** i => 0abc **100f 100i** (0–7) **(8–9) (8–9)**
x x c **1 1** f **1 1 1** i => **100c 100f 100i (8–9) (8–9) (8–9)**

### Notations

- The lowercase letters
`a`

to`i`

are the bits that are copied to the decimal representation. `0`

and`1`

are the exact bits in the input or output bit patterns.`x`

bits are ignored in the conversion.

## Task

Build a logical circuit using **two-input NAND gates** to convert 10 bits of DPD to 12 bits of BCD.

## Examples

Emphasized bits are the pattern-matching bits.

```
DPD Decimal BCD
0 0 0 0 0 0
```**0** 1 0 1 005 0000 0000 0101
^
0 0 0 1 1 0 **0** 0 1 1 063 0000 0110 0011
^
0 0 0 1 1 1 **1 0 0** 1 079 0000 0111 1001
^ ^ ^
0 0 0 0 0 1 **1 0 1** 0 090 0000 1001 0000
^ ^ ^
0 0 0 **1 0** 1 **1 1 1** 0 098 0000 1001 1000
^ ^ ^ ^ ^
1 0 1 0 1 1 **1 0 1** 0 592 0101 1001 0010
^ ^ ^
0 0 1 1 0 0 **1 1 0** 1 941 1001 0100 0001
^ ^ ^
1 1 0 **0 1** 1 **1 1 1** 1 879 1000 0111 1001
^ ^ ^ ^ ^
1 1 1 **0 0** 0 **1 1 1** 0 986 1001 1000 0110
^ ^ ^ ^ ^
0 0 1 **1 1** 1 **1 1 1** 1 999 1001 1001 1001
^ ^ ^ ^ ^
1 1 1 **1 1** 1 **1 1 1** 1 999 1001 1001 1001
^ ^ ^ ^ ^

## Scoring & winning criterion

The score is the number of **two-input NAND gates** used in your circuit. The lowest score wins.

You may define small components in terms of two-input NAND gates, and then use them in your final construction. If a component `X`

includes `N`

two-input NAND gates, each usage of `X`

adds `N`

to your score. For basic logic gates, this means:

- NOT: +1
- 2-input AND: +2
- 2-input OR: +3
- 2-input XOR: +4

Rolled back Luis' edit because atomic-code-golf is a winning criterion tag and [tag:code-challenge] is for questions which have a winning criterion not covered by other tags.

– Peter Taylor – 2018-11-26T15:12:06.943This is still unclear to me. I think there needs to be further description of what the letters

`a`

to`i`

mean and the process of converting. Go through the steps, rather than just showing examples and hoping we understand from that. – mbomb007 – 2018-11-26T20:59:38.033@mbomb007, maybe it's just clear to me because one of my languages is SML. That first code block is virtually a reference implementation in a pattern-matching language (although it works better in SMLNJ, which echos the result of each statement, than in MLton).

– Peter Taylor – 2018-11-26T22:36:55.900@mbomb007 I tried to clarify the pattern-matching nature of the conversion table. Does it help? – Bubbler – 2018-11-27T00:04:12.383

1@Bubbler Yeah, that's helpful – mbomb007 – 2018-11-27T15:00:49.603