title: Length of the Longest Descent

text:
# Question
Title: Length of the Longest Descent
Your task is to determine the length of the longest descent down a "mountain" represented as a grid of integer heights. A "descent" is any path from a starting cell to orthogonally adjacent cells with strictly decreasing heights (i.e. not diagonal and not to the same height). For instance, you can move from 5-4-3-1 but not 5-5-4-3-3-2-1. The length of this path is how many cell movements there are from the starting cell to the ending cell, thus 5-4-3-1 is length 3.

You will receive a rectangular grid as input and you should output an integer indicating the longest descent.

## Examples

```
1 2 3 2 2
3 4 5 5 5
3 4 6 7 4
3 3 5 6 2
1 1 2 3 1

```

The length of the longest descent down this mountain is 5. The longest path starts at the 7, moves left, up, left, up, and then left (7-6-5-4-2-1). Since there are 5 movements in this path, the path length is 5.

They might be all the same number.

```
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

```

Since this height map is flat, the longest descent is 0. (not 19, since the path sequence must be strictly descending)

Height maps can be made up of larger numbers than single-digit numbers.

```
10 12 13 14 15 15
17 14 15 15 15 16
18 20 21 15 15 15
21 14 10 11 11 15
15 15 15 15 15 15

```

The longest path here is of length 6. (21, 20, 18, 17, 14, 12, 10)

...And even bigger numbers are fine too.

```
949858 789874  57848  43758 387348
  5848 454115   4548 448545 216464
188452 484126 484216 786654 145451
189465 474566 156665 132645 456651
985464  94849 151654 151648 484364

```

The longest descent here is of length 7. (786654, 484216, 484126, 474566, 156665, 151654, 151648, 132645)

## Rules and Notes

* Grids may be taken in any convenient format. Specify your format in your answer.
* You may assume the height map is perfectly rectangular, is nonempty, and contains only positive integers in the signed 32-bit integer range.
* The longest descent path can begin and end anywhere on the grid.
* You do not need to describe the longest descent path in any way. Only its length is required.
* Shortest code wins

# Answer
> 8 votes
# JavaScript (ES7),  ~~106 103 102~~  98 bytes

```
f=(m,n=b=-1,x,y,p)=>m.map((r,Y)=>r.map((v,X)=>(x-X)**2+(y-Y)**2-1|v/p?b=n<b?b:n:f(m,n+1,X,Y,v)))|b

```

Try it online!

### Commented

```
f = (                        // f = recursive function taking:
  m,                         //   m[]  = input matrix
  n = b = -1,                //   n    = length of the current path; b = best length so far
  x, y,                      //   x, y = coordinates of the previous cell
  p                          //   p    = value of the previous cell
) =>                         //
  m.map((r, Y) =>            // for each row r[] at position Y in m[]:
    r.map((v, X) =>          //   for each value v at position X in r[]:
      (x - X) ** 2 +         //     compute the squared Euclidean distance
      (y - Y) ** 2           //     between (x, y) and (X, Y)
      - 1                    //     if A) the above result is not equal to 1
      | v / p ?              //     or B) v is greater than or equal to p:
        b = n < b ? b : n    //       end of path: update b to n if n >= b
      :                      //     else:
        f(m, n + 1, X, Y, v) //       do a recursive call
    )                        //   end of inner map()
  ) | b                      // end of outer map(); return b

```

### How?

During the first iteration, \\$x\\$, \\$y\\$ and \\$p\\$ are all *undefined* and both tests (**A** and **B** in the comments) evaluate to *NaN*, which triggers the recursive call. Therefore, all cells are considered as a possible starting point of the path.

# Answer
> 6 votes
# Jelly,  ~~23 21~~  20 bytes

-2 thanks to Erik the Outgolfer

```
ŒỤŒPạƝ§ỊẠƲƇœị⁸QƑƇṪL’

```

**Try it online!** (way too inefficient for the examples - path here is `95 94 93 83 77 40 10` so `6` is yielded)

### How?

```
ŒỤŒPạƝ§ỊẠƲƇœị⁸QƑƇṪL’ - Link: list of lists of integers, M
ŒỤ                   - multi-dimensional indices sorted by values
  ŒP                 - power-set
          Ƈ          - filter, keep those for which:
         Ʋ           -   last four links as a monad:
     Ɲ               -     for each pair of neighbours:
    ạ                -       absolute difference
      §              -     sum each
       Ị             -     insignificant?
        Ạ            -     all?
           œị        - multi-dimensional index into:
             ⁸       -   chain's left argument, M
                Ƈ    - filter, keep only those:
               Ƒ     -   unaffected by?:
              Q      -     de-duplicate
                 Ṫ   - tail
                  L  - length
                   ’ - decrement

```

# Answer
> 3 votes
# Python 2, ~~150~~ ~~147~~ ~~140~~ ~~136~~ ~~134~~ ~~132~~ ~~125~~ ~~123~~ 120 bytes

```
l=lambda g,i,j:max(0<g.get(t)<g[i,j]and-~l(g,*t)for d in(-1,1)for t in((i+d,j),(i,j+d)))
lambda g:max(l(g,*t)for t in g)

```

Try it online!

Takes input in the form of a dictionary `(x, y): value`.

-7 bytes thanks to wizzwizz4, -2 bytes thanks to Jonathan Allen, -2 bytes thanks to BMO

## Alternative, ~~123~~ 121 bytes

```
l=lambda i,j:max(0<g.get(t)<g[i,j]and-~l(*t)for d in(-1,1)for t in((i+d,j),(i,j+d)))
g=input();print max(l(*t)for t in g)

```

Try it online!

Essentially the same solution, just with the final lambda replaced by an actual program. I personally like the first one better, but this one comes close in byte count by allowing `g` to be used as a global variable.

# Answer
> 2 votes
# Clean, ~~211~~ 207 bytes

```
import StdEnv,Data.List
z=zipWith
$l=maximum[length k-1\\p<-permutations[(v,[x,y])\\y<-[0..]&u<-l,x<-[0..]&v<-u],(k,[m:n])<-map unzip(subsequences p)|and[all((>)2o sum o map abs)(z(z(-))n[m:n]):z(>)k(tl k)]]

```

Try it online!

A brute-force solution taking a list-of-lists-of-integers (`[[Int]]`).
The TIO driver takes the same format as the examples through STDIN.

It's too slow to run any of the examples on TIO and probably locally too, but works in theory.

This one does the same thing faster, can do 3x3 or 2x4 on TIO and 4x4 and 3x5 locally.

**Indented:**

```
$ l
    = maximum
        [ length k-1
        \\p <- permutations
            [ (v, [x, y])
            \\y <- [0..] & u <- l
            , x <- [0..] & v <- u
            ]
        , (k, [m: n]) <- map unzip
            (subsequences p)
        | and
            [ all
                ((>) 2 o sum o map abs)
                (zipWith (zipWith (-)) n [m:n])
                :
                zipWith (>) k (tl k)
            ]
        ]

```

# Answer
> 2 votes
# Haskell, ~~188~~ 186 bytes

Needs \\$\texttt{-XNoMonomorphismRestriction}\\$:

```
f m|c<-[0..length(m!!0)-1],r<-[0..length m-1]=h[g[(x,y)]|x<-r,y<-c,let g((x,y):p)=h[1+g(k:p)|i<-[-1,1],k@(u,v)<-[(x+i,y),(x,y+i)],u#r,v#c,m!!u!!v<m!!x!!y,not$k#p]]
(#)=elem
h=foldl max 0

```

Try it online!

Alternatively we could use `notElem` over `(not.).(#)` without the flag for \\$+4\\$ bytes:

Try it online!

## Explanation & Ungolfed

Strategy: Recursively try all feasible paths, keeping track of visited entries and maximize their length.

Let's first define some helpers.. Since we need `elem` and `notElem`, let's use `(#)` for `elem`. Also, to maximize we'll need a total function (`maximize` is not), returning \\$0\\$ when the list is empty:

```
safeMaximum = foldl max 0

```

Now we're ready to define our recursive function `fun :: [[Integer]] -> Integer`:

```
fun xs
  | c <- [0..length(m!!0)-1]             -- all possible indices of xs' columns
  , r <- [0..length m-1]                 -- all possible indices of xs' rows
  = safeMaximum                          -- maximize ..
      [ g [(x,y)]                        -- .. initially we haven't visited any others
      | x <- c, y<-r                     -- .. all possible entries
-- For the purpose of golfing we define g in the list-comprehension, it takes all visited entries (p) where (x,y) is the most recent
      , let g((x,y):p) = safeMaximum     -- maximize ..
          [ 1 + g(k:p)                   -- .. recurse, adding (x,y) to the visited nodes & increment (the next path will be 1 longer)
          | i <- [-1,1]                  -- offsets [left/up,right/down]
          , k@(u,v) <-[(x+i,y),(x,y+i)]  -- next entry-candidate
          , u#c, v#r                     -- make sure indices are in bound ..
          , m!!u!!v < m!!x!!y            -- .. , the the path is decreasing
          , not$(u,v)#p                  -- .. and we haven't already visited that element
          ]
      ]

```

# Answer
> 2 votes
# Python 3, 219 bytes

```
e,m=len,enumerate
b=lambda g,x,y:[b(g,i,j)for o in[-1,1]for i,j in[(x+o,y),(x,y+o)]if e(g)>i>=0<=j<e(g[x])and g[x][y]<g[i][j]]
l=lambda t:e(t)and 1+max(map(l,t))
d=lambda g:max(l(b(g,x,y))for x,r in m(g)for y,_ in m(r))

```

Try it online!

Grid is represented as list of lists:

```
[
    [1, 2, 3, 2, 2],
    [3, 4, 5, 5, 5],
    [3, 4, 6, 7, 4],
    [3, 3, 5, 6, 2],
    [1, 1, 2, 3, 1],
]

```

Original ungolfed code:

```
def potential_neighbours(x, y):
    return [(x-1, y), (x+1, y), (x, y-1), (x, y+1)]

def neighbours(grid, x, y):
    result = []
    for i, j in potential_neighbours(x, y):
        if 0 <= i < len(grid) and 0 <= j < len(grid[x]) and grid[x][y] < grid[i][j]:
            result += [(i, j)]
    return result

def build_tree(grid, x, y):
    return [build_tree(grid, i, j) for i, j in neighbours(grid, x, y)]

def longest_path_in_tree(tree):
    if len(tree) == 0:
        return 0
    return 1 + max(map(longest_path_in_tree, tree))

def longest_descent(grid):
    trees = [build_tree(grid, x, y) for x, row in enumerate(grid) for y, _ in enumerate(row)]
    return max(map(longest_path_in_tree, trees))

```

# Answer
> 1 votes
# Python 3, ~~263~~ 227 bytes

```
def f(m):
 p={(x,y):[c for i in[-1,1]for c in[(x,y+i),(x+i,y)]]for x,y in m};d={c:0 for c in p if not p[c]}
 while len(p)-len(d):
  for c in p:
   for b in p[c]:
    if b in d:d[c]=max(d[b]+1,d.get(c,0))
 return max(d.values())

```

Try it online!

-2 bytes thanks to BMO

Takes grids in the format `{(0, 0): 1, (1, 0): 2, ...}`. This format can be generated from the example format using the following utility function:

```
lambda s,e=enumerate:{(x,y):int(n)for y,l in e(s.split('\n'))for x,n in e(l.split())}

```

---
Tags: code-golf, grid
---


# Question
Title: Densely packed decimal (DPD) to decimal, with logic gates
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

# Answer
> 6 votes
# 45 39 NANDs (or 43 37)

39 seems to be the absolute minimum, but it is possible to reach 37 NANDs by a trick: By assuming that the largest numbers are correctly encoded.

888, 889, 898, 899, 988, 989, 998, 999 are to be encoded with the 2 MSB as 00, requiring just 37 NANDs for decoding.

However, in the specification for decoding, they are specified to be ignored, meaning they can be anything. It is a reasonable assumption that this freer specification could require even fewer gates, but the opposite is true. 39 gates are required for this. This saving could give real benefits for real circuits.

I also found circuits that were significantly more efficient and faster, containing a few more gates.

No pencil drawn image of the circuit this time. Perhaps later.

The circuit is presented in obvious Verilog code, ready for running with test included.

Verilog code:

<pre><code>// Densely packed decimal (DPD) to decimal, circuit in Verilog.
// Made of just 39 NANDs.
//
// By Kim Øyhus 2019 (c) into (CC BY-SA 3.0.)
// This work is licensed under the Creative Commons Attribution 3.0
// Unported License. To view a copy of this license, visit
// https://creativecommons.org/licenses/by-sa/3.0/
//
// This is my entry to win this Programming Puzzle & Code Golf
// at Stack Exchange:
// https://codegolf.stackexchange.com/questions/176557/densely-packed-decimal-dpd-to-decimal-with-logic-gates
//
// TASK:
// 3 decimal digits are stored in 10 bits in the DPD format,
// and this circuit transforms them into 3 decimal digits in
// 4 bits each, BCD format.
//
// 39 gates seem to be the smallest possible NAND circuit there is
// for this task, but I can get even lower by a trick, to 37:
// I assume that the largest numbers are correctly encoded.
//   888, 889, 898, 899, 988, 989, 998, 999 are to be encoded
// with the 2 MSB as 00, requiring just 37 NANDs for decoding.
//
//   However, in the specification for decoding, they are specified
// to be ignored, meaning they can be anything. It is a reasonable
// assumption that this freer specification could require even fewer
// gates, but the opposite is true. 39 gates are required for this.
// This saving could give real benefits for real circuits.
//
//   This DPD format seems to be used a lot for storing decimal numbers
// in computers and IO for ALUs, even though it is stored as 12 bits
// per 3 digits inside the ALUs and for other calculations.
// There are many patents for these kinds of circuits, and so I am
// a little skeptical for making a free one for a competition.
// However, the point is to make it as small as possible and of just
// NAND gates, which in itself is not so commercially interesting.

module decode1000 ( in_000, in_001, in_002, in_003, in_004, in_005, in_006, in_007, in_008, in_009, out000, out001, out002, out003, out004, out005, out006, out007, out008, out009, out010, out011 );
  input  in_000, in_001, in_002, in_003, in_004, in_005, in_006, in_007, in_008, in_009;
  output out000, out001, out002, out003, out004, out005, out006, out007, out008, out009, out010, out011;
  wire   wir000, wir001, wir002, wir003, wir004, wir005, wir006, wir007, wir008, wir009, wir010, wir011, wir012, wir013, wir014, wir015, wir016, wir017, wir018, wir019, wir020, wir021, wir022, wir023, wir024, wir025, wir026, wir027, wir028, wir029, wir030, wir031, wir032;

// The 3 bits of 1s goes straight through from input to output.
  assign out000 = in_000;
  assign out004 = in_004;
  assign out008 = in_007;

  nand gate001 ( wir001, in_003, in_001 );
  nand gate002 ( wir002, in_002, in_003 );
  nand gate003 ( wir003, wir001, in_006 );
  nand gate004 ( wir004, wir002, in_001 );
  nand gate005 ( wir005, wir001, wir001 );
  nand gate006 ( wir006, in_005, in_001 );
  nand gate007 ( wir007, wir006, in_003 );
  nand gate009 ( wir008, wir004, wir007 );
  nand gate010 ( wir009, wir005, in_006 );
  nand gate011 ( wir010, wir007, wir007 );
  nand gate012 ( wir011, wir009, in_002 );
  nand gate013 ( wir012, wir011, wir009 );
  nand gate014 ( wir013, wir011, wir011 );
  nand gate015 ( wir014, in_008, wir013 );
  nand gate016 ( wir015, in_009, wir013 );
  nand gate017 ( wir016, wir010, wir014 );
  nand gate018 ( wir017, wir014, wir005 );
  nand gate019 ( wir018, wir015, wir015 );
  nand gate020 ( wir019, wir011, wir008 );
  nand gate021 ( wir020, wir019, wir006 );
  nand gate022 ( wir021, wir010, wir018 );
  nand gate023 ( wir022, wir020, wir004 );
  nand gate024 ( wir023, wir016, wir008 );
  nand gate025 ( out001, wir023, wir023 );
  nand gate026 ( out003, wir022, wir022 );
  nand gate027 ( wir024, wir005, wir008 );
  nand gate028 ( wir025, wir012, wir002 );
  nand gate029 ( wir026, wir019, in_003 );
  nand gate031 ( out007, wir024, wir009 );
  nand gate032 ( out011, wir026, wir026 );
  nand gate033 ( wir028, wir017, in_005 );
  nand gate035 ( wir030, wir026, in_008 );
  nand gate036 ( out005, wir028, wir028 );
  nand gate037 ( out009, wir030, wir030 );
  nand gate039 ( wir031, wir026, in_009 );
  nand gate041 ( out010, wir031, wir031 );
  nand gate042 ( wir032, out003, wir018 );
  nand gate043 ( out006, wir003, wir032 );
  nand gate044 ( out002, wir025, wir021 );
endmodule

module test;
   reg  [ 9:0] AB; // input DPD
   wire [11:0] C; // output BCD

  decode1000 U1 (
  .in_000 (AB[ 0]),
  .in_001 (AB[ 1]),
  .in_002 (AB[ 2]),
  .in_003 (AB[ 3]),
  .in_004 (AB[ 4]),
  .in_005 (AB[ 5]),
  .in_006 (AB[ 6]),
  .in_007 (AB[ 7]),
  .in_008 (AB[ 8]),
  .in_009 (AB[ 9]),
  .out000 ( C[ 0]),
  .out001 ( C[ 1]),
  .out002 ( C[ 2]),
  .out003 ( C[ 3]),
  .out004 ( C[ 4]),
  .out005 ( C[ 5]),
  .out006 ( C[ 6]),
  .out007 ( C[ 7]),
  .out008 ( C[ 8]),
  .out009 ( C[ 9]),
  .out010 ( C[10]),
  .out011 ( C[11])
  );

   initial  AB=0;  //unary=0;  binary=0
  always  #1  AB = AB+1;
  initial  begin
    $display("\t\ttime,\tinn 10bit   \tout 3x4bit");
    $monitor("%d,\t%b %b %b\t%b %b %b\t %d%d%d",$time, AB[9:7],AB[6:4],AB[3:0], C[11:8], C[7:4], C[3:0],  C[11:8], C[7:4], C[3:0]);
  end
  initial  #1023  $finish;
endmodule

// How I run and test it:
// iverilog -o decode1000 decode1000.v
// vvp decode1000
```
</code></pre>

# Answer
> 5 votes
## 65 62 60 58 NANDs

Taking the inputs as `i0` to `i9` and the outputs as `o0` to `o9, oa, ob` we have

```
t0 = nand(i6, i7)
t1 = nand(t0, t0)
t2 = nand(i3, i4)
o0 = nand(nand(nand(t2, i3), t1), nand(nand(t2, i8), t1))
t3 = nand(o0, o0)
t4 = nand(i0, t3)
o1 = nand(t4, t4)
t5 = nand(i1, t3)
o2 = nand(t5, t5)
o3 = i2
# Score 13 for the first decimal digit

u0 = nand(i6, i8)
u1 = nand(u0, t0)
u2 = nand(i4, t2)
o4 = nand(nand(nand(u2, u0), u2), nand(u1, t0))
u3 = nand(o4, o4)
u4 = nand(o0, i8)
u5 = nand(u4, u4)
u6 = nand(u3, nand(nand(u5, i0), nand(u4, i3)))
o5 = nand(u6, u6)
u7 = nand(u3, nand(nand(u5, i1), nand(u4, i4)))
o6 = nand(u7, u7)
o7 = i5
# Score 20 for the second decimal digit

o8 = nand(nand(nand(nand(i4, i8), o0), t1), nand(nand(i6, u1), i6))
v2 = nand(o8, o8)
v3 = nand(i6, i6)
v4 = nand(i7, i7)
v5 = nand(v2, nand(nand(i6, nand(nand(i7, i0), nand(v4, i3))), nand(v3, i7)))
o9 = nand(v5, v5)
v6 = nand(v2, nand(nand(i6, nand(nand(i7, i1), nand(v4, i4))), nand(v3, i8)))
oa = nand(v6, v6)
ob = i9
# Score 25 for the third decimal digit

```

Python test framework to validate the correctness of the construction.

---
Tags: conversion, atomic-code-golf, logic-gates
---


title: Using Symbols for Letters

text:
# Question
Title: Using Symbols for Letters
**Input:** A single word as a string (matches `[a-zA-Z]+`). If the input doesn't follow these guidelines, print "Error" (but no error should be thrown)

**Output:** The NATO pronunciation of the word. Print out a space separated list of the NATO word that matches each letter of the input word. Trailing white space is acceptable.

**Restrictions:**
Your source code must contain each ASCII character from 32 (space) to 126 (tilde) **in that order**, excluding numbers and letters. You may have anything you like mingled in between the required characters, but the required characters must be there and in order. (If `ABC` were the required characters, `YA8iBC3` or `C6ABn#C` would be valid, but `A7CRT` or `8mdB9AC` would not be).

Standard loopholes and built-ins for generating the NATO pronunciation are not allowed.

**References:**
The NATO pronunciation is as follows: ***A****lpha **B**ravo **C**harlie **D**elta **E**cho **F**oxtrot **G**olf **H**otel **I**ndia **J**uliet **K**ilo **L**ima **M**ike **N**ovember **O**scar **P**apa **Q**uebec **R**omeo **S**ierra **T**ango **U**niform **V**ictor **W**hiskey **X**ray **Y**ankee **Z**ulu*.

The required symbols (in order) are as follows: `!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~`

**Test cases:** (The quotation marks won't be part of input, but are included to show whitespace)

```
"a"            => Alpha
"Z"            => Zulu
"twig"         => Tango Whiskey India Golf
"PPCG"         => Papa Papa Charlie Golf
"camelCase"    => Charlie Alpha Mike Echo Lima Charlie Alpha Sierra Echo
"Quebec"       => Quebec Uniform Echo Bravo Echo Charlie
""             => Error
" "            => Error
"()"           => Error
"twig "        => Error
" PPCG"        => Error
"one+two"      => Error
"Queen bee"    => Error

```

This is a , so the shortest code in your favorite language wins!

# Answer
> 3 votes
# JavaScript (ES6), 268

An anonymous function

```
i=>[...i].every(c=>(c=parseInt(c,36))>9?o+="AlphaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJulietKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu".match(/[A-Z][^A-Z]+/g)[c-10]+' ':0,o='',!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~")?o:'Error'

```

# Answer
> 2 votes
# Ruby, 343 bytes

```
puts gets.chop.chars.map!{|c|"AlphaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJulietKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu"[/#{c.upcase}[a-z]+/]||$$%0&0}*' 'rescue(puts"Error")#*+,-./:;<=>?@[\]^_`{|}~

```

Tried incorporating as many of the required characters as possible, but after a while it was shorter to just put them in a comment at the end. For readability, here's the non-comment part with the long string taken out:

```
puts gets.chop.chars.map!{|c|"AlphaBravo..."[/#{c.upcase}[a-z]+/]||$$%0&0}*' 'rescue(puts"Error")

```

That's a space and all the characters `!"#$%&'()` in the right order without comments

# Answer
> 2 votes
# 05AB1E, ~~151~~ ~~150~~ ~~146~~ ~~145~~ ~~143~~ 135 bytes

```
!áмg_ilA”¤±Ð†vo¼¯¤œ®È¨›trotŠˆƒ‹Š™ÈŸt Kilo´àma—……ÍÐ—Žêpa¼°«Äoµ†Çâgo¸šÉµ Whiskey Xrayµ‹nkeeâ¸lu”#ð«‡ë”‰ë”q"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

```

-8 bytes implicitly thanks to *@ErikTheGolfer*'s comment here for a better compressed string (only difference is `Alpha` vs `Alfa`).

Try it online or verify all test cases.

**Explanation:**

```
!              # Take the factorial of the (implicit) input
               # (This will leave the input-string unchanged if it isn't an integer)
 áм            # Remove all letters
   g_i         # If the length of the remainder is 0:
      l        #  Make the (implicit) input lowercase
       A       #  Push the lowercase alphabet
       ”¤±Ð†vo¼¯¤œ®È¨›trotŠˆƒ‹Š™ÈŸt Kilo´àma—……ÍÐ—Žêpa¼°«Äoµ†Çâgo¸šÉµ Whiskey Xrayµ‹nkeeâ¸lu”
               #  Push string "Alpha Bravo Charlie ... Yankee Xray Zulu"
        #      #  Split the string by spaces:
               #   ["Alpha","Bravo","Charlie",...,"Yankee","Xray","Zulu"]
         ð«    #  Append each with a space:
               #   ["Alpha ","Bravo ","Charlie ",...,"Yankee ","Xray ","Zulu "]
       ‡       #  Transliterate; map all letters in the lowercase input with this
               #  list at the same indices (and output the result implicitly)
     ë         # Else:
      ”‰ë”     #  Push the dictionary word "Error"
          q    # Stop the program (and output the "Error" at the top of the stack implicitly)
           "#$%&'()*+,-./:;<=>?@[\]^_`{|}~
              "# Push the string "#$%&'()*+,-./:;<=>?@[\]^_`{|}~",
               # which is a no-op since the program has already stopped

```

See this 05AB1E tip of mine (section *How to use the dictionary?*) to understand why `”¤±Ð†vo¼¯¤œ®È¨›trotŠˆƒ‹Š™ÈŸt Kilo´àma—……ÍÐ—Žêpa¼°«Äoµ†Çâgo¸šÉµ Whiskey Xrayµ‹nkeeâ¸lu”` is `"Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform Victor Whiskey Xray Yankee Zulu"` and `”‰ë”` is `"Error"`.

# Answer
> 1 votes
# CJam, 173 bytes

```
qeu:M'[,65>:L- !{M'Af-L"{;ege& \@IQ#5~wUNxuznY_E+TLsBTC9\$8
]%9b    Y9&G~|Yedz9?7pLD&&6PNg[vXY4D}Q"127b26b'`f+'`/.+f=S*}"Error"?e#()*+,-./:;<=>?@[\]^_`{|}~

```

Contains lots of unprintable characters. Try it out here.

# Answer
> 1 votes
# PHP, 268 bytes

Same byte count as the JavaScript answer. :) I couldn't find a byte-saving way around the "penalty" of adding the special char string as is:

```
for(;$c=ucfirst($argv[1][$i++]);"!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~")preg_match("/{$c}[a-z]+/",AlphaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJulietKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu,$m)?$o.="$m[0] ":die(Error);echo$o;

```

Takes an input from command line, like:

```
$ php tango.php Word

```

---

**Ungolfed**

```
for(;$c=ucfirst($argv[1][$i++]);"!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~")
    preg_match("/{$c}[a-z]+/",AlphaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJulietKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu,$m) ?
        $o.="$m[0] " :
        die(Error);
echo$o;

```

# Answer
> 1 votes
# x86 machine code, IBM PC DOS, 274 bytes

```
a080 0032 e4fe c8be 8100 03f0 8bc8 8bd8 b805 008e c0fd ac24 dfbf 0800 51b1 a4fc
f2ae 5975 064f 57e2 eceb 07ba af00 52bb 0100 8cc0 8ed8 b409 8bcb 5acd 21ba b400
cd21 e2f6 b44c cd21 416c 7068 6124 4272 6176 6f24 4368 6172 6c69 6524 4465 6c74
6124 4563 686f 2446 6f78 7472 6f74 2447 6f6c 6624 486f 7465 6c24 496e 6469 6124
4a75 6c69 6574 244b 696c 6f24 4c69 6d61 244d 696b 6524 4e6f 7665 6d62 6572 244f
7363 6172 2450 6170 6124 5175 6562 6563 2452 6f6d 656f 2453 6965 7272 6124 5461
6e67 6f24 556e 6966 6f72 6d24 5669 6374 6f72 2457 6869 736b 6579 2458 7261 7924
5961 6e6b 6565 245a 756c 7524 2122 2345 7272 6f72 2024 2526 2728 292a 2b2c 2d2e
2f3a 3b3c 3d3e 3f40 5b5c 5d5e 5f60 7b7c 7d7e

```

Ungolfed:

```
.DATA
NATO    DB  'Alpha$Bravo$Charlie$Delta$Echo$Foxtrot$Golf$Hotel$India$'
        DB  'Juliet$Kilo$Lima$Mike$November$Oscar$Papa$Quebec$Romeo$'
        DB  'Sierra$Tango$Uniform$Victor$Whiskey$Xray$Yankee$Zulu$'
LNATO   EQU $-NATO
        DB  '!"#'           ; required string part 1
ERRSTR  DB  'Error'         ; Error string
SEPSTR  DB  ' $'             ; word separator string
        DB  '%&',"'()*+,-./:;<=>?@[\]^_`{|}~" ; required string part 2
.CODE
    MOV  AL, DS:[80H]       ; DS:80H is length of input string from command line
    XOR  AH, AH             ; clear AH
    DEC  AL                 ; command line arg length includes preceeding space
    MOV  SI, 81H            ; look in DS:82H-1 for start of string
    ADD  SI, AX             ; start at end of string
    MOV  CX, AX             ; search length of input string
    MOV  BX, AX             ; BL is length of input to search
    MOV  AX, @DATA          ; Initialize ES to CODE segment
    MOV  ES, AX             ; align ES pointer (leave DS pointing to PSP)
SEARCH:
    STD                     ; set dir flag (search backwards)
    LODSB                   ; load next char from DS:SI into AL, advance SI
    AND  AL, 0DFH           ; uppercase the input letter
    MOV  DI, OFFSET NATO    ; re-point SCASB to beginning of word data
    PUSH CX                 ; save outer loop position
    MOV  CL, LNATO          ; CL = length of NATO word data
    CLD                     ; clear dir flag (search forward)
    REPNE SCASB             ; search until key in AL is found ES:DI, advance DI
    POP  CX                 ; restore outer loop counter
    JNZ  SHORT ERROR        ; if REPNE ends without ZF, no value was found
    DEC  DI                 ; un-advance DI to start of found string
    PUSH DI                 ; save position for later output
    LOOP SEARCH
    JMP  SHORT OUTPUT
ERROR:
    MOV  DX, OFFSET ERRSTR  ; error string
    PUSH DX                 ; push to top of stack
    MOV  BX, 1              ; only output this one below
OUTPUT:
    MOV  AX, ES             ; get data segment from ES
    MOV  DS, AX             ; point DS for DOS API string output
    MOV  AH, 09H            ; display string function
    MOV  CX, BX             ; loop for number of input letters
OUT_LOOP:
    POP  DX                 ; get pointer to next word from stack
    INT  21H
    MOV  DX, OFFSET SEPSTR  ; display a space between words
    INT  21H
    LOOP OUT_LOOP
EXIT:
    MOV  AH, 4CH            ; exit to DOS
    INT  21H

```

Reads input from command line, displays output to console.

Implementation notes: In order to prevent any otherwise valid words from being displayed before the Error string, the searching and screen output are separate. The input string is searched end to beginning since the stack (LIFO) is used to hold the output words (otherwise they'd be displayed in reverse).

Output:

```
A>SYMLET a
Alpha
A>SYMLET Z
Zulu
A>SYMLET twig
Tango Whiskey India Golf
A>SYMLET PPCG
Papa Papa Charlie Golf
A>SYMLET camelCase
Charlie Alpha Mike Echo Lima Charlie Alpha Sierra Echo
A>SYMLET Quebec
Quebec Uniform Echo Bravo Echo Charlie
A>SYMLET
Error
A>SYMLET " "
Error
A>SYMLET ()
Error
A>SYMLET "twig "
Error
A>SYMLET PPCG
Error
A>SYMLET one+two
Error
A>SYMLET Queen bee
Error

```

# Answer
> 0 votes
# Japt, 188 bytes

The compressed string is littered with unprintables, so I've replaced each with a `¿`. Try it online!

```
V=Um@`Alp¿B¿voC¿r¦eDeltaE®oFoxÉ¿GolfHÇUI¿iaJªietKiloL¿aMikeNovem¼rOs¯rPapaQue¼cRo´oSi¿¿TangoUnif¿mVÅ¡rW¿skeyX¿yY¿keeZªu`fXu +"[a-z]+" +S};!Uf"[ !#$%&'()*+,-./:;<=>?@[\\]^_`\{|}~]" ?V:`Er¿r
                                                                                ^    ^  ^   ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^

```

The top line is the actual code; the bottom line points out each of the required characters. I was lucky to find a way to put every one of them to good use, especially the backslash, which would have been needed there even if it was not required.

I could save four bytes by using JS's `atob` to compress the string, instead of Japt's built-in `Oc`, but the transpiler inserts an extra parenthesis due to this bug.

```
V=Um@     }; // Set variable V to: map each character X in U to:
`...`f       //  Take the long string, decompress it, and match:
Xu +"[a-z]+" //   the uppercase version of X, followed by multiple lowercase letters.
+S           //  Take the resulting match and add a space.
             // All this results with "Alpha Bravo Charlie" for an input of "Abc", or
             // "Alpha Bravo null" for something like "Ab!".
 Uf"..."     // Match any of the characters in this string in the input.
!        ?   // If the result is null (none were matched):
V            //  output V.
:"Error      // Otherwise, output "Error".

```

# Answer
> 0 votes
# Python ~~279~~ 276 bytes

It would have been much shorter than the odd requirement.

**EDIT**: I just learned that s.split(' ')==s.split()

```
#!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
x=raw_input().lower();a=''
l="Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform Victor Whiskey Xray Yankee Zulu".split()
for i in x: a+=l[ord(i)-97]+' '
print a

```

I commented out the requirement. I used ord() to find the index position of the letter in l.

Try it here!

---
Tags: code-golf, kolmogorov-complexity, restricted-source
---


# Question
Title: Create an ASCII-to-hex table for Mark Watney
Inspired by this SciFi.SE question.

---

### Background (with minor spoiler):

> In the movie *The Martian*, protagonist Mark Watney uses an ASCII table to look up hexadecimal values of ASCII characters so he can attempt to communicate back to Earth.\*

### Challenge

With no input, output the following ASCII table exactly like this:

```
Dec Hex    Dec Hex    Dec Hex  Dec Hex  Dec Hex  Dec Hex   Dec Hex   Dec Hex
  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p
  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q
  2 02 STX  18 12 DC2  34 22 "  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r
  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s
  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t
  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u
  6 06 ACK  22 16 SYN  38 26 &  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v
  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w
  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x
  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y
 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z
 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {
 12 0C FF   28 1C FS   44 2C ,  60 3C <  76 4C L  92 5C \  108 6C l  124 7C |
 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }
 14 0E SO   30 1E RS   46 2E .  62 3E >  78 4E N  94 5E ^  110 6E n  126 7E ~
 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL

```

The final newline is optional. With the newline, the md5 of the output is `58824a1dd7264c0410eb4d727aec54e1`. Without, it is `41b6ecde6a3a1324be4836871d8354fe`.

In case it helps, this is the output from the `ascii` Linux command with the usage info at the top chopped off. You can recreate this on Ubuntu as follows:

```
sudo apt-get install ascii
ascii | tail -n+7

```

You **may not** use the `ascii` utility (or similar) in your answers.

Because ASCII characters are small Enough with this silly meme already!

---

I am aware this is similar to Print the ASCII table, but I believe the formatting of the output in this question is significantly more complex and warrants a different question.

---

\*Note, I have not yet seen this movie.

# Answer
> 19 votes
# JavaScript (ES6), 323 ~~332 353~~

**Edit** I managed to shorten this a bit
Step 1, believe it or not, using an array of 16 chars is shorter than `toString` \+ `toUpperCase`
Step 2, fiddling around to use `.map` instead of `for`, so that I can transform it all to a single expression function, avoding console.log and/or return.

**Edit 2** Moved DEL at place 0, idea borrowed from Cole Cameron

```
H=x=>(x=[...'0123456789ABCDEF']).map((d,r)=>x[S='slice'](0,8).map(c=>(o+=`   ${w=c*16+r} ${c+d} `[S](-z)+("DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".substr((w+1&127)*3,3)||String.fromCharCode(w)),z=c<5?8:9,'Dec Hex   '[S](0,c<2?z+2:z)),o+=`
`,z=7).join` `,o='')[0]+o

```

MD5: 41B6ECDE6A3A1324BE4836871D8354FE

Pixel perfect, I'd say

**LESS GOLFED**

```
H=x=>(
  x=[...'0123456789ABCDEF'],
  a="DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ",
  o='', // the string o will contain the body (16 rows)
  x.map((d,r)=> ( // main loop, r is thr row number, d is the second hex digit to print
    o+=`\n`, z=7,
    x.slice(0,8).map(c=> // loop on 8 columns, c is both column number and digit to print
      (
        // append the column to o
        o += `   ${w=c*16+r} ${c+d} `.slice(-z) + (a.substr((w+1&127)*3,3)||String.fromCharCode(w)),
        z=c<5?8:9, // adjust the column size
        'Dec Hex   '.slice(0,c<2?z+2:z) // column head, right size
      ) // the .map result is the 8 columns heading
    ).join` ` // join the heading in a single string
  ))[0] // any element of the result map is the heading
  + o // concatenate the body
)

```

**Test**

```
H=x=>(x=[...'0123456789ABCDEF']).map((d,r)=>x[S='slice'](0,8).map(c=>(o+=`   ${w=c*16+r} ${c+d} `[S](-z)+("DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".substr((w+1&127)*3,3)||String.fromCharCode(w)),z=c<5?8:9,'Dec Hex   '[S](0,c<2?z+2:z)),o+=`
`,z=7).join` `,o='')[0]+o

/* TEST */
console.log=x=>O.textContent=x

console.log(H())
```

```
<pre id=O></pre>
```

# Answer
> 11 votes
# C, ~~307~~ ~~310~~ ~~308~~ ~~307~~ 305 bytes

Finally working 100%.

```
i,j,z=127;main(){for(;j++<8;)printf("Dec Hex%*s",j<3?4:j<6||j>7?2:3,"");for(;i<143&&putchar(!i|i>z?10:32);i+=16)i=i>z?i%z:i,printf("%*d %02X ",i>95?4:3,i,i),i%z>31?putchar(i):printf("%.3s","DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US "+(i+1)%128*3);}

```

Output:

```
$ ./a.out
Dec Hex    Dec Hex    Dec Hex  Dec Hex  Dec Hex  Dec Hex   Dec Hex   Dec Hex
  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p
  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q
  2 02 STX  18 12 DC2  34 22 "  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r
  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s
  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t
  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u
  6 06 ACK  22 16 SYN  38 26 &  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v
  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w
  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x
  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y
 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z
 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {
 12 0C FF   28 1C FS   44 2C ,  60 3C <  76 4C L  92 5C \  108 6C l  124 7C |
 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }
 14 0E SO   30 1E RS   46 2E .  62 3E >  78 4E N  94 5E ^  110 6E n  126 7E ~
 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL$ ./a.out > file.txt
$ md5sum file.txt
41b6ecde6a3a1324be4836871d8354fe  file.txt

```

Ungolfed:

```
/* some variables for the trip */
i,j,z=127;

main()
{
    /* print header row */
    for(;j++<8;)
            printf("Dec Hex%*s", j<3?4:j<6||j>7?2:3, "");

    /* Iterate through ASCII values, print a space after every column, newline after every 8th value */
    for(;i<143 && putchar(!i|i>z ? 10 : 32); i+=16)
    {
            /* print dec/hex value */
            printf("%*d %02X ", i>95?4:3, i, i=i>z?i%z:i);

            /* print character or friendly name for non-printable characters */
            i%z>31
                    ? putchar(i)
                    : printf("%.3s", "DELNULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US "+(i+1)%128*3);
    }
}

```

Try it on Ideone.

Edit: 2 more bytes. Many thanks to Dan Allen and Digital Trauma.

# Answer
> 7 votes
# Bubblegum, 535 bytes

```
0000000: e0 05 2f 02 0f 5d 00 22 19 48 62 01 d3 1f 78 e2  ../..].".Hb...x.
0000010: 9a a0 8e 4e 5d d1 b4 c1 77 aa 32 58 ca 97 55 7e  ...N]...w.2X..U~
0000020: a8 01 87 7d db e4 00 55 8f c0 49 67 b6 56 02 5e  ...}...U..Ig.V.^
0000030: ae b2 4d e2 a9 f4 7f 99 a8 56 9e b7 4c 60 a4 79  ..M......V..L`.y
0000040: 6a 76 54 11 90 72 d6 b7 19 df 2f 57 39 2d 21 c0  jvT..r..../W9-!.
0000050: d1 4c 5e d6 21 29 c8 ed 7c a9 7b 8c 85 dc 62 a1  .L^.!)..|.{...b.
0000060: 65 98 e1 0b a7 36 83 c8 ca 88 0c 57 22 f6 56 1e  e....6.....W".V.
0000070: 45 03 b6 74 21 a8 39 52 e9 71 b4 98 ed 71 38 9f  E..t!.9R.q...q8.
0000080: 2d dc 21 d7 bf 60 41 cc bb bd a7 cb 0b 17 8d 65  -.!..`A........e
0000090: 05 13 04 0f 6c bb 67 62 aa c7 ad 6b be 9e 46 77  ....l.gb...k..Fw
00000a0: 35 b9 91 85 f5 47 31 2f c7 ec da c0 00 0e a6 48  5....G1/.......H
00000b0: 01 ba 8b cd b0 34 81 c4 74 9f 4e 3b c3 d0 f7 10  .....4..t.N;....
00000c0: 46 a0 55 8d 49 5d b7 b0 c9 79 ac e5 5f ef 49 f2  F.U.I]...y.._.I.
00000d0: b0 1b 71 3a e1 30 7a fc ce a7 a8 d5 c3 9a 35 1a  ..q:.0z.......5.
00000e0: 4e 27 92 40 4b b5 9b c4 0d 5c e8 cd 71 00 bd c1  N'.@K....\..q...
00000f0: ca aa d2 05 dc e1 0f d9 19 1d 6f 14 87 b3 e4 e8  ..........o.....
0000100: 9e 82 64 d8 e4 76 e7 24 0a 0e 88 72 a1 12 44 95  ..d..v.$...r..D.
0000110: d4 78 82 bd da 71 f3 fb 03 00 d1 4b c8 80 cb 49  .x...q.....K...I
0000120: 0b 98 be 26 ba 3e e8 82 e2 14 9b ba 1a cf bf bc  ...&.>..........
0000130: 30 4e c4 e8 7e b4 d5 46 e6 bc 73 97 c5 ed a6 e2  0N..~..F..s.....
0000140: 06 02 e7 1b 74 4d da 73 fb 15 68 50 c0 ed 32 9b  ....tM.s..hP..2.
0000150: 0d d7 49 d5 c1 a2 e9 07 2c 77 81 6c d3 8d 59 26  ..I.....,w.l..Y&
0000160: 1c 35 ec 2b 7e cb 3a f1 cc 45 a9 e5 6d 3e 33 ca  .5.+~.:..E..m>3.
0000170: 56 3c 8a 8d f6 13 e9 59 d4 52 07 44 ab 5e bc f4  V<.....Y.R.D.^..
0000180: 1f ed f8 9c 8b 48 e1 c4 6c fd 47 d5 04 cc 6e aa  .....H..l.G...n.
0000190: 3f 54 b8 cc cd 09 01 6d 20 3c 42 c9 44 da b1 c1  ?T.....m <B.D...
00001a0: 69 80 12 26 6b 65 e1 4d 1c c3 48 36 2b 14 00 61  i..&ke.M..H6+..a
00001b0: 04 6b 9a 59 2a 53 e3 64 a7 4f dd cc be 2c 20 5e  .k.Y*S.d.O..., ^
00001c0: f7 c7 64 34 e6 12 a6 44 c1 69 35 76 05 db 13 ab  ..d4...D.i5v....
00001d0: 52 10 b5 8e da 8e c5 3c 4c d0 69 0b 19 18 67 ef  R......<L.i...g.
00001e0: 44 1c 7b 70 63 98 95 40 28 6e 3d e7 44 cb 24 83  D.{pc..@(n=.D.$.
00001f0: 88 62 63 3c 02 1c e7 db db 02 56 ae cd 9c e0 9c  .bc<......V.....
0000200: 1c a1 c1 ae d1 dd 7b b7 e6 bd 5b 38 ee 75 c5 6c  ......{...[8.u.l
0000210: 06 16 6c b2 fb 00 00                             ..l....

```

This above program uses LZMA compression. Try it online!

# Answer
> 3 votes
# JavaScript ES6 ~~432~~ ~~405~~ ~~398~~ 385

```
o="Dec Hex  "
o=`${o}  ${o}  ${o+o+o+o} ${o} ${o}\n`
for(i=0;i<16;i++){for(j=0;j<8;j++){k=i+j*16
o+=k>9&&k<16?' ':k<96||k>99?'  ':'   '
o+=k+" "+(k<16?0:'')+k.toString(16).toUpperCase()+" "
o+=k>31?String.fromCharCode(k):"NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".substr(k*3,3)
}o+="\n"}
console.log(o.substr(0,o.length-2)+'DEL')

```

# Answer
> 3 votes
## C, ~~385~~ ~~384~~ 358 bytes

```
i,n,j;char a[100]="NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US DEL";z(o){printf("%3d %02X %.*s ",j,j,3,a+o);}main(){for(;i<8;i++){printf("%3s %3s   ","Dec","HEX ");}printf("\n");for(;n<16;n++){for(j=n;j<=n+112;j+=16){if(j==127)z(96);else j<32?z(j*3):printf("%3d %02X %c   ",j,j,j);}printf("\n");}return 0;}

```

The guy above beat me to the punch but I still wanted to submit because I enjoyed this one.

De-golfed:

```
#include<stdio.h>
i,n,j;
char a[100] = "NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US DEL";
z(o){printf("%3d %02X %.*s ",j,j,3,a+o);}
main(){
   for(;i<8;i++){printf("%3s %3s   ","Dec","HEX ");}printf("\n");
   for(;n<16;n++){
      for(j=n;j<=n+112;j+=16){
         if(j==127)z(96);
         else j<32?z(j*3):printf("%3d %02X %c   ",j,j,j);
      }
      printf("\n");
   }
   return 0;
}

```

UPDATE : replaced a var with j. Saved a byte ;)
UPDATE2: Trimmed a few extra thingys and functionized a print thingy to save some bytes.

# Answer
> 3 votes
# Python 2.7, 389 Bytes

Probably not going to try and trim this down anymore, but it was fun to get it this far.

```
r=range
c='NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US '
h=''
p=['']*16
o=[11,11,9,9,9,10,10,9]
e=['%3s '%str(i)+('%02X ')%(i)+('DEL',c[i*3:i*3+3].strip() if i<32 else chr(i))[i<127] for i in r(128)]
for i in r(8):
    l=e[i*16:(i+1)*16]
    h+='Dec Hex'.ljust(o[i])
    p=[p[j]+l[j].ljust((0,o[i])[i<7]) for j in r(16)]
print h+'\n'+'\n'.join(p)

```

# Answer
> 3 votes
# Golfscript, 225 bytes

```
"\x04\x04\x02\x02\x02\x03\x03\x02"{"Dec Hex"" ":s@*}%n[128,{3s*\+-4>s+.~.96<@>\256+16base{10,"ABCDEF"1/+=}%1>{+}/}%"\x1f\xbb\x89\xbc\xaf\x82=F\xd7U%\x80\x8a\xf6\xc7U\xa6al)A\xf6\x19\xfe\x03\x83\xef-\x9f\xe7m\xeb\x82h\xf3\xbfEm6V\x1fD\x8c\xd7~\xcb\x95&(\x1e/:\x8e\xc5\xb0\x0b\xd6\xd4\xd09\xdd""\xff\x1e"{base}/{90,65>1342s++1/=}%3/32/"\x7f"{,32>}%1/*]zip{s*}%16/zip{s*n}%

```

# Answer
> 3 votes
# Python 3.4, 216 Bytes

Also valid Python 2.7. Used FryAmTheEggman's idea/suggestion about curses.ascii.controlnames, which saves almost 100 bytes.

```
import curses.ascii as a
o=''
w=4,4,2,2,2,3,3,1
for x in w:o+='Dec Hex'+' '*x
o+=' '
for n in range(16):
 o+='\n'
 for x in w:o+='%3d %02X %-*s'%(n,n,x,n>31and[chr(n),'DEL'][n>126]or a.controlnames[n]);n+=16
print(o)

```

---

```
$ python ascii.py | md5
58824a1dd7264c0410eb4d727aec54e1

```

# Answer
> 2 votes
# Ruby (2.2.2p95), 277 ~~295 306 331 364~~

```
a='Dec Hex  ';puts"#{a}  "*2+a*4+" #{a}"*2,16.times.map{|i|8.times.map{|j|(k=i+j*16;k==127?'  127 7F DEL':"#{k} #{'%.2X'%k} #{'NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US  '[k*3..k*3+2]||k.chr}").rjust(j<2?10+j :9+j/6)}.join}

```

ungolfed

```
s = "Dec Hex    " * 2 + "Dec Hex  " * 4 + " Dec Hex  " * 2
a = 127.times.map { |i|
  "#{i} #{'%.2X'%i} #{'NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US  '[i*3..i*3+2]||i.chr}"
}
a << '  127 7F DEL'
x = 16.times.map { |i|
  8.times.map { |j|
    a[i + j * 16].rjust(j < 2 ? 10 + j : 9 + j / 6)
  }.join
}.join "\n"
puts s, x

```

# Answer
> 1 votes
# Microscript II, 1314 bytes

Probably far from optimal.

```
"Dec Hex    "pp"Dec Hex  "ppps"Dec Hex   "ppoP"  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p\n  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q\n  2 02 STX  18 12 DC2  34 22 \"  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r\n  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s\n  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t\n  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u\n  6 06 ACK  22 16 SYN  38 26 &  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v\n  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w\n  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x\n  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y\n 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z\n 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {\n 12 0C FF   28 1C FS   44 2C ,  60 3C <  76 4C L  92 5C \\  108 6C l  124 7C |\n 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }\n 14 0E SO   30 1E RS   46 2E .  62 3E >  78 4E N  94 5E ^  110 6E n  126 7E ~\n 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL"

```

# Answer
> 1 votes
## JavaScript, ~~415~~ ~~413~~ ~~4231~~ ~~411~~ ~~406~~ ~~402~~ ~~4142~~ 412 bytes

```
x=>eval('a=`${d="Dec Hex  "}  `[r="repeat"](2)+d[r](3)+`${d} `[r](2)+d+`
`;z="NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".match(/.{3}/g);z[127]="DEL";for(j=i=0;i<128;i++){a+=("  "+((b=i%8*16)+j)).slice(-3)+" "+(0+(c=b+j).toString(16).toUpperCase()).slice(-2)+" "+(c<32||i==127?z[c]:String.fromCharCode(c))+(b==112?`
`:(b < 80 ? " " : "  "));if(b==112)j++}a')

```

I couldn't figure out how to print the chars prior to char code 32, so just listed them as a string.

The hash I've got seems to match (`41b6ecde6a3a1324be4836871d8354fe`).

Demo + Ungolfed:

```
function t() {
  a = `${d="Dec Hex  "}  `.repeat(2) + d.repeat(3) + `${d} `.repeat(2) + d + "\n";
  z = "NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ".match(/.{3}/g);
  z[127] = "DEL";
  for (j = i = 0; i < 128; i++) {
    a += ("  " + ((b = i % 8 * 16) + j)).slice(-3) + " " + (0 + (c = b + j).toString(16).toUpperCase()).slice(-2) + " " + (c < 32 || i == 127 ? z[c] : String.fromCharCode(c)) + (b==112?"\n":(b < 80 ? " " : "  "));
    if(b==112)j++;
  }
  return a
}
document.write("<pre>" + t() + "</pre>")
```

---

1 - fixed spacing
2 - again fixed spacing

# Answer
> 1 votes
# MATLAB, 363 bytes

Not as small as C but comparable...

```
h='';s=@sprintf;for i=[4 4 2 2 2 3 3 2]h=s([h 'Dec Hex%*s'],i,'');end
h=[h 10];a='NULDLESOHDC1STXDC2ETXDC3EOTDC4ENQNAKACKSYNBELETBBS CANHT EM LF SUBVT ESCFF FS CR GS SO RS SI US ';for i=0:15for j=0:7k=i+16*j;if j<2b=1+6*i+3*j;h=[h s('%3d %02X %-3s ',k,k,a(b:b+2))];else
h=[h s('%*d %02X %c ',3+(j>5),k,k,k)];end
end
h=[h(1:end-1) 10];end
disp([h(1:end-2) 'DEL']);

```

# Answer
> 1 votes
# ///, 998 bytes

```
//\/\////  /Dec Hex/ 0/ 1/ 2/ 3/ 4/ 5/ 6	/ 7/ 8/ 9/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /A /B /C /D /E /F /
 /  NUL 6DL280 4@ 0P6` 12	pSOH 7DC3! 91 51Q7a 13	qSTX 8DC4" 02 62R8b 14	rETX 9DC5# 13 73S9c 15	sEOT 0DC6$ 24 84T 00d 16	tENQ 1NAK 7% 35 95U 01e 17	uACK 2SYN 8& 46 	06V 02f 18	v	BEL 3ET9' 57	 	1G 7W 03g 19	wBS4CAN 0( 68 	2H 8X 04h 20	xHT5EM1) 79 	3I 9Y 05i 21	y
0L 6SU2* 8: 	4J 0Z 06j 22	z
1VT7ES3+ 9; 	5K 1[ 07k 23	{
2F 8FS4, 0< 	6L 2\\ 08l 24	|
3CR9GS5- 1= 	7M 3] 09m 25	}
4SO0RS6. 2> 	8N 4^ 10n 26	~
5SI1US7\/ 3? 	9O 5_ 11o 27	DEL

```

Try it online!

# Answer
> 1 votes
# PHP, ~~330~~ 321 bytes

```
$a=[NUL,SOH,STX,ETX,EOT,ENQ,ACK,BEL,BS,HT,LF,VT,FF,CR,SO,SI,DLE,DC1,DC2,DC3,DC4,NAK,SYN,ETB,CAN,EM,SUB,ESC,FS,GS,RS,US,127=>DEL];foreach($t=[3,3,1,1,1,2,2,0]as$i)echo'Dec Hex ',str_repeat(' ',$i);echo"
";for($x=0;$x<16;)for($y=$x++;$y<128;$y+=16)printf("% 3d %1$02X % -".$t[$y/16].s.($y<112?' ':"
"),$y,$a[$y]?:chr($y));

```

Try it online!

Less golfy:

```
$a=[NUL,SOH,STX,ETX,EOT,ENQ,ACK,BEL,BS,HT,LF,VT,FF,CR,SO,SI,DLE,
DC1,DC2,DC3,DC4,NAK,SYN,ETB,CAN,EM,SUB,ESC,FS,GS,RS,US,127=>DEL];

$t=[3,3,1,1,1,2,2,0];

foreach( $t as $i )
    echo 'Dec Hex ', str_repeat( ' ', $i );

echo" \n";

for( $x=0; $x<16; ) {
    for( $y=$x++; $y<128; $y+=16 ) {
        printf( "% 3d %1$02X % -" . $t[$y/16] . 's' . ( $y<112 ?' ' : "\n" ),
            $y, $a[$y] ?: chr($y) );
    }
}

```

# Answer
> 0 votes
## Common Lisp (SBCL), 309

```
(progn(format t"~{~v,0TDec Hex  ~}"#1='(0 11 22 31 40 49 59 69))(dotimes(y 16)(fresh-line)(loop for x from 0 for k in #1#for i =(+(* 16 x)y)do(format t"~v,0T~3d ~2,'0x ~a"k i i(if(graphic-char-p #2=(code-char i))#2#(case i(8"BS")(9"HT")(10"LF")(12"FF")(13"CR")(127"DEL")(t(string-upcase(char-name #2#)))))))))

```

A script to be run which outputs the following to standard output, ie. the version without a final newline (md5: 41b6ecde6a3a1324be4836871d8354fe).

```
Dec Hex    Dec Hex    Dec Hex  Dec Hex  Dec Hex  Dec Hex   Dec Hex   Dec Hex
  0 00 NUL  16 10 DLE  32 20    48 30 0  64 40 @  80 50 P   96 60 `  112 70 p
  1 01 SOH  17 11 DC1  33 21 !  49 31 1  65 41 A  81 51 Q   97 61 a  113 71 q
  2 02 STX  18 12 DC2  34 22 "  50 32 2  66 42 B  82 52 R   98 62 b  114 72 r
  3 03 ETX  19 13 DC3  35 23 #  51 33 3  67 43 C  83 53 S   99 63 c  115 73 s
  4 04 EOT  20 14 DC4  36 24 $  52 34 4  68 44 D  84 54 T  100 64 d  116 74 t
  5 05 ENQ  21 15 NAK  37 25 %  53 35 5  69 45 E  85 55 U  101 65 e  117 75 u
  6 06 ACK  22 16 SYN  38 26 &  54 36 6  70 46 F  86 56 V  102 66 f  118 76 v
  7 07 BEL  23 17 ETB  39 27 '  55 37 7  71 47 G  87 57 W  103 67 g  119 77 w
  8 08 BS   24 18 CAN  40 28 (  56 38 8  72 48 H  88 58 X  104 68 h  120 78 x
  9 09 HT   25 19 EM   41 29 )  57 39 9  73 49 I  89 59 Y  105 69 i  121 79 y
 10 0A LF   26 1A SUB  42 2A *  58 3A :  74 4A J  90 5A Z  106 6A j  122 7A z
 11 0B VT   27 1B ESC  43 2B +  59 3B ;  75 4B K  91 5B [  107 6B k  123 7B {
 12 0C FF   28 1C FS   44 2C ,  60 3C <  76 4C L  92 5C \  108 6C l  124 7C |
 13 0D CR   29 1D GS   45 2D -  61 3D =  77 4D M  93 5D ]  109 6D m  125 7D }
 14 0E SO   30 1E RS   46 2E .  62 3E >  78 4E N  94 5E ^  110 6E n  126 7E ~
 15 0F SI   31 1F US   47 2F /  63 3F ?  79 4F O  95 5F _  111 6F o  127 7F DEL

```

### Details

* `(0 11 22 31 40 49 59 69)` contains the position of each column in a line, as obtained by inspecting the desired output. There were many corner cases that are simply better handled by hard-coding the exact position for each column and letting the `~T` format directive tabulate as needed.
* Since names of characters are implementation-dependent, this code targets only the SBCL interpreter (I tested with CCL, which uses other names). I rely on `char-name` for most non-graphic characters, but some of them have explicit mappings to the expected output.

### Ungolfed

```
(progn
  (format t"~{~v,0TDec Hex  ~}" '(0 11 22 31 40 49 59 69))
  (dotimes(y 16)
    (fresh-line)
    (loop for x from 0
          for k in '(0 11 22 31 40 49 59 69)
          for i = (+ (* 16 x) y)
          for c = (code-char i)
          do (format t
                     "~v,0T~3d ~2,'0x ~a"
                     k
                     i
                     i
                     (if (graphic-char-p c)
                         c
                         (case i
                           (8"BS")
                           (9"HT")
                           (10"LF")
                           (12"FF")
                           (13"CR")
                           (127"DEL")
                           (t (string-upcase (char-name c)))))))))

```

---
Tags: code-golf, kolmogorov-complexity
---


title: Draw this diamond pattern

text:
# Question
Title: Draw this diamond pattern
The below pattern will form the basis of this challenge.

```
     /\
     \/
     /\
    /  \
   /    \
/\/      \/\
\/\      /\/
   \    /
    \  /
     \/
     /\
     \/

```

Given an input width and height, each `>=1`, output the above ASCII art pattern repeated that many times, joining (and overlapping) at the small diamonds.

For example, here is an input with `width = 2` and `height = 1`:

```
     /\        /\
     \/        \/
     /\        /\
    /  \      /  \
   /    \    /    \
/\/      \/\/      \/\
\/\      /\/\      /\/
   \    /    \    /
    \  /      \  /
     \/        \/
     /\        /\
     \/        \/

```

Here is an input `width = 3` and `height = 2`:

```
     /\        /\        /\
     \/        \/        \/
     /\        /\        /\
    /  \      /  \      /  \
   /    \    /    \    /    \
/\/      \/\/      \/\/      \/\
\/\      /\/\      /\/\      /\/
   \    /    \    /    \    /
    \  /      \  /      \  /
     \/        \/        \/
     /\        /\        /\
     \/        \/        \/
     /\        /\        /\
    /  \      /  \      /  \
   /    \    /    \    /    \
/\/      \/\/      \/\/      \/\
\/\      /\/\      /\/\      /\/
   \    /    \    /    \    /
    \  /      \  /      \  /
     \/        \/        \/
     /\        /\        /\
     \/        \/        \/

```

### Rules and I/O

* Input and output can be given by any convenient method.
* You can print it to STDOUT or return it as a function result.
* Either a full program or a function are acceptable.
* Any amount of extraneous whitespace is acceptable, so long as the characters line up appropriately.
* Standard loopholes are forbidden.
* This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

# Answer
> 10 votes
# Canvas, ~~26~~ ~~25~~ ~~24~~ ~~21~~ 18 bytes

```
４／╬/╬⁰ｒ：⤢ｎ↷⁸｛Ａ×├ｍ↷

```

Try it here!

-3 bytes by fixing  not repeating canvas

Explanation:

```
4/╬                 quad-palindromize a 4-long diagonal - big inner diamond
   /╬               quad-palindromize "/" - small diamond
     ⁰r             join the two vertically, centered
       :⤢n          overlap with transpose
           ↷        and rotate the thing clockwise
            ⁸{      for each input
              A×      times 10
                ├     plus 2
                 m    mold the canvas to that width
                  ↷   and rotate clockwise, setting up for the next iteration

```

# Answer
> 6 votes
# JavaScript (ES8), ~~167~~ ~~161~~ 159 bytes

<sup>*NB: This is encoding the pattern. See my other answer for a shorter mathematical approach.*</sup>

Takes input as `(width)(height)`.

```
w=>h=>(g=h=>h?g(--h)+`
`+([4106,4016,31305,21504,17010]['0102344320'[h%=10]]+'').replace(/./g,c=>'\\/'[c^h>5]||''.padEnd(c-1)).repeat(w+1).slice(8):'')(h*10+2)

```

Try it online!

### How?

We encode the upper half of the pattern with digits:

* \\$0\\$ means `\`
* \\$1\\$ means `/`
* \\$n=2\\$ to \\$7\\$ means \\$n-1\\$ spaces

This gives:

```
0  ···/\·····  -->  [3 spaces] [/] [\] [5 spaces]             -->  4106
1  ···\/·····  -->  [3 spaces] [\] [/] [5 spaces]             -->  4016
0  ···/\·····  -->  [3 spaces] [/] [\] [5 spaces]             -->  4106
2  ··/··\····  -->  [2 spaces] [/] [2 spaces] [\] [4 spaces]  -->  31305
3  ·/····\···  -->  [1 space] [/] [4 spaces] [\] [3 spaces]   -->  21504
4  /······\/\  -->  [/] [6 spaces] [\] [/] [\]                -->  17010

```

For the lower half, we use the rows \\$4,3,2,0\\$ with `/` and `\` inverted.

# Answer
> 6 votes
# JavaScript (ES6), 139 bytes

This is using quite a different approach from my initial answer, so I'm posting this separately.

Takes input as `(width)(height)`.

```
w=>h=>(g=x=>y>8?` /\\
`[a=(x+y*9)%10,d=(x+y)%10,x?(y%10>3&&2*(a==8)|d==5)|(y%10<6&&2*(a==6)|d==7):3]+g(x--?x:--y&&w):'')(w=w*10+2,y=-~h*10)

```

Try it online!

### How?

Given the width \\$w\\$ and the height \\$h\\$, we draw the output character by character over a grid which is:

* \\$10w+3\\$ characters wide
* \\$10h+2\\$ characters high

with \\$x\\$ going from \\$10w+2\\$ to \\$0\\$ (left to right) and \\$y\\$ going from \\$10h+10\\$ to \\$9\\$ (top to bottom).

Example for \\$w=3\\$ and \\$h=2\\$:

$$\begin{matrix}(32,30)&(31,30)&\dots&(0,30)\\ (32,29)&(31,29)&&(0,29)\\ \vdots&&\ddots&\vdots\\ (32,9)&(31,9)&\dots&(0,9)\end{matrix}$$

The rightmost cells (at \\$x=0\\$) are simply filled with linefeeds.

For all other cells, we compute:

* \\$a=(x-y)\bmod 10\\$ (constant over anti-diagonals)
* \\$d=(x+y)\bmod 10\\$ (constant over diagonals)

We draw a `"/"` if:

$$((y\bmod 10)\>3\text{ and }d=5)\text{ or }((y\bmod 10)\<6\text{ and }d=7)$$

```
 y  | y % 10 | output (w = 3, h = 1)
----+--------+----------------------------------
 20 |    0   | ...../........./........./......
 19 |    9   | ....../........./........./.....
 18 |    8   | ...../........./........./......
 17 |    7   | ..../........./........./.......
 16 |    6   | .../........./........./........
 15 |    5   | /./......././......././......./.
 14 |    4   | ./......././......././......././
 13 |    3   | ......../........./........./...
 12 |    2   | ......./........./........./....
 11 |    1   | ....../........./........./.....
 10 |    0   | ...../........./........./......
  9 |    9   | ....../........./........./.....

```

We draw a `"\"` if:

$$((y\bmod 10)\>3\text{ and }a=8)\text{ or }((y\bmod 10)\<6\text{ and }a=6)$$

```
 y  | y % 10 | output (w = 3, h = 1)
----+--------+----------------------------------
 20 |    0   | ......\.........\.........\.....
 19 |    9   | .....\.........\.........\......
 18 |    8   | ......\.........\.........\.....
 17 |    7   | .......\.........\.........\....
 16 |    6   | ........\.........\.........\...
 15 |    5   | .\.......\.\.......\.\.......\.\
 14 |    4   | \.\.......\.\.......\.\.......\.
 13 |    3   | ...\.........\.........\........
 12 |    2   | ....\.........\.........\.......
 11 |    1   | .....\.........\.........\......
 10 |    0   | ......\.........\.........\.....
  9 |    9   | .....\.........\.........\......

```

Or we draw a space if none of these conditions is fulfilled.

# Answer
> 6 votes
# C++ (gcc), 137 bytes

```
#include<cstdio>
auto p(int x,int y){int n=10,t=x=++x*n;for(++y*=n;y>8;)t>7?putchar(t<9?y--,n:t%n-y%n+4&7?t%n+y%n-5&7?32:47:92),t--:t=x;}

```

Try it online!

*Explanation*

```
_______________________________
   098765432109876....
   9    \/    .     factor =y%10 - x10
   8    /\    .     if factor = -4 || 4. Print --> '\'  47
   7   /  \   .
   6  /    \  .     factor =x%10+y%10;
   5\/      \/*-.   if factor = 5 || 13 --> /  92
   4/\      /\   `.
   3  \    /       `->  * is 9,5 => \
   2   \  /
   1    \/
   0    /\
   9

```

# Answer
> 4 votes
# Haskell, 179 bytes

```
k '\\'='/'
k '/'='\\'
k x=x
f x=take(10*x+2)
w#h=map(f w.cycle).f h.drop 9.cycle$(++).reverse=<<map(map k)$["\\/\\      /","   \\    / ","    \\  /  ","     \\/   ","     /\\   "]

```

Try it online!

---

# Haskell, 181 bytes

```
k '\\'='/'
k '/'='\\'
k x=x
f x=take(10*x+2)
w#h=map(f w.cycle).f h.drop 9.cycle$(++).reverse=<<map(map k)$map t[49200,36058,31630,30010,29038]
t 0=""
t n="\\ /"!!mod n 3:t(div n 3)

```

Try it online!

# Answer
> 3 votes
# Charcoal, ~~24~~ ~~22~~ 20 bytes

```
\/↘²‖Ｍ↘LＦ⊖ＮＣχ⁰Ｆ⊖ＮＣ⁰χ

```

Try it online! Link is to verbose version of code. Explanation:

```
´\/↘²

```

Draw one eighth of the original pattern.

```
‖Ｍ↘L

```

Duplicate it three times to complete the original pattern.

```
Ｆ⊖ＮＣχ⁰

```

Copy the required number of times horizontally.

```
Ｆ⊖ＮＣ⁰χ

```

Copy the required number of times vertically.

# Answer
> 3 votes
# Powershell, 146 bytes

```
param($w,$h)0..9*$h+0,1|%{$y=$_
-join(0..9*$w+0,1|%{('3  /\33  \/33  /\33 /  \3  /3 \ /\/33\\/\33/3\3 /3  \  /33 \/3'-replace3,'   ')[$y*10+$_]})}

```

## Explanation

The pattern is 10x10 chars array:

```
     /\
     \/
     /\
    /  \
   /    \
/\/      \
\/\      /
   \    /
    \  /
     \/

```

The script:

* repeats the pattern;
* appends columns \[0,1\] to the end of each line;
* appends lines \[0,1\] to the end of the output.

Two things for golf:

1. The pattern array mapped to string with length 100 bytes;
2. The string reduced by simple `replace`.

# Answer
> 2 votes
# Perl 5 `-p`, 148 bytes

```
$_='3A3'x$_.$/.'3B3
3A3
2/2\\2
1/4\\1
A6A
B6B
1\\4/1
2\\2/2
3B3
3A3
'=~s/^.*$/$&x$_/mger x<>.'3B3'x$_;s|A+|/\\|g;s|B+|\\/|g;s/\d/$"x$&/ge;s|^ |  |gm

```

Try it online!

# Answer
> 1 votes
# PHP, 159 bytes

pattern taken from mazzy; translated to 1-2-3, converted to base26 -\> decoded by the program

```
while($y<$argv[2]*10+2)echo str_pad("",$argv[1]*10+2,strtr(base_convert([jng1,jnnb,jng1,jofn,k333,"1h4p5",23814,k94d,k02h,jnnb][$y++%10],26,4),312,"\ /")),"
";

```

requires PHP 5.5 or later. Run with `-nr` or try it online.

calculating may be shorter (as it was for Arnauld). I may look into that.

# Answer
> 1 votes
# Kotlin, ~~196~~ 135 bytes

Saved 61 bytes thanks to ASCII-only's suggestion to use AZTECCO's C++ algorithm.

```
{h,w->var r=""
for(l in 9..h*10+10){for(c in 9..w*10+10){r+=when{(l%10+c%10)%8==5->'/'
(l%10-c%10+8)%8==4->'\\'
else->' '}}
r+='\n'}
r}

```

Try it online!

# Answer
> 1 votes
# Python 3, ~~194~~ ~~192~~ ~~187~~ 127 bytes

@ASCII-only's solution:

```
lambda w,h,n=10:"\n".join("".join([" /","\\"][(j%n-i%n)%8==4][(j%n+i%n)%8==5]for i in range(-1,w*n+1))for j in range(-1,h*n+1))

```

Try it online!

---

Original Solution

```
n="\n"
def f(w,h):a=[r"     /\   "*w,r"     \/   "*w,r"    \  /  "*w,r"   \    / "*w,r"\/\      /"*w+r"\/"];return a[0]+n+n.join(([i.translate({47:92,92:47})for i in a]+a[::-1])*h)+n+a[1]

```

Try it online!

-2 bytes thanks to @Black Owl Kai showing that the tops and bottoms can be accessed from the generated array instead of in separate variables.

-5 more bytes thanks to @Black Owl Kai using a more creative way to store the diamonds

Generates this portion of each diamond:

```
     /\
     \/
    \  /
   \    /
\/\      /\/

```

A `/\` added at the end of each row to complete it. Then, the `/`s and `\`s are swapped to form the top of each diamond, and the order of the lines is reversed to form the bottom half. Finally, it adds in the very top row of `/\`s and the very bottom row of `\/`s to complete the image.

---
Tags: code-golf, ascii-art
---


title: Ionic Compound Golf

text:
# Question
Title: Ionic Compound Golf
## Challenge

Given two inputs, a positive ion and a negative ion, you must output the formula for the ionic compound which would be made from the two ions. This basically means balancing out the charges so they equal zero.

Do not bother with formatting the formula with subscript numbers, but you must have brackets for the multi-atom ions (such as `NO3`).

You do not have to account for any errors (for example, if someone inputs two negative ions, you can just let the program fail).

**Note:** Take Fe to have a charge of 3+

## Ions

All of the ions which need to be accounted for are found along with their charges on the second part of the AQA GCSE Chemistry Data Sheet.

### Positive ions

* H+
* Na+
* Ag+
* K+
* Li+
* NH4+
* Ba2+
* Ca2+
* Cu2+
* Mg2+
* Zn2+
* Pb2+
* Fe3+
* Al3+

### Negative ions

* Cl-
* Br-
* F-
* I-
* OH-
* NO3-
* O2-
* S2-
* SO42-
* CO32-

## Examples

Some examples:

**H** and **O** returns:- `H2O`

**Ca** and **CO3** returns:- `CaCO3`

**Al** and **SO4** returns:- `Al2(SO4)3`

Note the following case that you must account for:

**H** and **OH** returns:- `H2O` *not* `H(OH)`

# Answer
> 0 votes
# CJam, 176 bytes

```
"O S SO4 CO3 ""Cl Br F I OH NO3 """"H Na Ag K Li NH4 ""Ba Ca Cu Mg Zn Pb ""Fe Al "]_2{r\1$S+f#Wf=0#((z@}*_2$*_4=2*-_@/\@/@\]2/{~_({1$1>_el={'(@@')\}|0}&;}/]s"HOHH"1$#){;"H2O"}&

```

Try it online

This was somewhat painful, particularly with all the special cases for parentheses, showing counts, the H2O, etc.

The data is not in a super compact format. It could be trimmed more, but the code needed to interpret it would probably compensate for the savings. So I went with an array of strings, where each string contains the atoms with the same charge, ordered from -2 to +3 (where the string for 0 is empty).

Explanation:

```
[..]  Data, as explained above.
_     Duplicate data, will need it for both inputs.
2{    Loop over two inputs.
  r     Get input.
  \     Swap data to top.
  1$    Copy input to top (keep original for later).
  S+    Add a space to avoid ambiguity when searching in data.
  f#    Search for name in all strings of data.
  Wf=   Convert search results to truth values by comparing them to -1.
  0#    Find the 0 entry, which gives the index of the matching string.
  ((    Subtract 2, to get charge in range [-2, 3] from index.
  z     Absolute value, we don't really care about sign of charge.
  @     Swap second copy of data table to proper position for next input.
}*    End loop over two inputs.
_2$*  Multiply the two charges.
_4=   We need the LCM. But for the values here, only product 4 is not the LCM.
2*-   So change it to 2.
_@/   Divide LCM by first charge to get first count.
\@/   Divide LCM by second charge to get second count.
@\]2/ Make pairs of name/count for both ions...
{     ... and loop over the pairs.
  ~     Unpack the pair.
  _(    Check if count is > 1.
  {       Handle count > 1.
    1$    Get copy of name to top of stack.
    1>    Slice off first character to check if rest contains upper case.
    _el   Create lower case copy.
    =     If they are different, there are upper case letters.
    {       Handle case where parentheses are needed.
      '(    Opening parentheses.
      @@    Some stack shuffling to get values in place.
      ')    Closing parentheses.
      \     And one more swap to place count after parentheses.
    }|    End parentheses handling.
    0     Push dummy value to match stack layout of other branch.
  }&    End count handling.
  ;     Pop unused count off stack.
}/    End loop over name/count pairs.
]s    Pack stack content into single string, for H2O handling.
"HOHH"  String that contains both HOH and OHH, which need to be H2O.
1$#)  Check if output is in that string.
{     If yes, replace with H2O.
  ;     Drop old value.
  "H2O" And make it H2O instead.
}&    End of H2O handling.

```

# Answer
> 2 votes
# Lua, ~~174~~ 242 bytes

I forgot the brackets '-\_-, that got me up to 242. Oh well, it was a fun enough challenge at least.

```
i,c,a={Ba=2,Ca=2,Cu=2,Mg=2,Zn=2,Pb=2,Fe=3,Al=3,O=2,S=2,SO4=2,CO3=2},io.read(),io.read()
p,d=i[c]~=i[a],{SO4=1,NO3=1,OH=1,CO3=1}
k,m=p and i[c]or'',p and i[a]or''
a=k==m and a or (d[a]and'('..a..')'or a)
print(c..a=='HOH'and'H2O'or c..m..a..k)

```

Try it online!

Old version:

```
i,c,a={Ba=2,Ca=2,Cu=2,Mg=2,Zn=2,Pb=2,Fe=3,Al=3,O=2,S=2,SO4=2,CO3=2},io.read(),io.read()
p=i[c]~=i[a]
k,m=p and i[c]or'',p and i[a]or''
print(c..a=='HOH'and'H2O'or c..m..a..k)

```

Abusing Lua's tendency to initialize everything with a nil value we can cut down on storage costs. Still, Lua is still a bit clunky :(

# Answer
> 1 votes
# Java (~~619~~ ~~647~~ 667 bytes)

\[Fixed\] Update: H + OH returns HOH even though I hard coded it not to.... working on it

\[Fixed\] Update: Sometimes Parenthesis appear when they shouldn't

**Code**

```
String f(String[]a){if(Arrays.equals(a,new String[]{"H","OH"})|Arrays.equals(a,new String[]{"OH","H"}))return "H2O";List<String>b=Arrays.asList(new String[]{"H","Na","Ag","K","Li","NH4","Ba","Ca","Cu","Mg","Zn","Pb","Fe","Al","Cl","Br","F","I","OH","NO3","O","S","SO4","CO3"});Integer[]c={1,1,1,1,1,1,2,2,2,2,2,2,3,3,1,1,1,1,1,1,2,2,2,2},d={5,18,19,22,23};List<Integer>j=Arrays.asList(d);int e=b.indexOf(a[0]),f=b.indexOf(a[1]),g=c[e],h=c[f],i;if(f<e){String p=a[0];a[0]=a[1];a[1]=p;i=g;g=h;h=i;i=e;e=f;f=i;}boolean k=j.contains(e),l=j.contains(f),m=g==h,n=g==1,o=h==1;return (k&!m&!o?"("+a[0]+")":a[0])+(m?"":h==1?"":h)+(l&!m&!n?"("+a[1]+")":a[1])+(m?"":g==1?"":g);}

```

I wasn't sure how to do this without hard coding every ions charge, so it ended up being long. Lucky cause all the charges are 1, 2, or 3 so finding the amount of each ion is easy.

**Expanded**

```
import java.util.Arrays;
import java.util.List;
public class Compound {
    public static void main(String[]a){
        //System.out.println(f(a));
        String[] pos = new String[]{"H","Na","Ag","K","Li","NH4","Ba","Ca","Cu","Mg","Zn","Pb","Fe","Al"};
        String[] neg = new String[]{"Cl","Br","F","I","OH","NO3","O","S","SO4","CO3"};
        for(int i = 0; i < pos.length; i++){
            for(int j = 0; j < neg.length; j++){
                System.out.println(pos[i] + " + " + neg[j] + " = " + f(new String[]{pos[i],neg[j]}));
                System.out.println(neg[j] + " + " + pos[i] + " = " + f(new String[]{neg[j],pos[i]}));
            }
        }
    }
    static String f(String[]a){
        if(Arrays.equals(a,new String[]{"H","OH"})|Arrays.equals(a,new String[]{"OH","H"}))
            return "H2O";
        List<String>b=Arrays.asList(new String[]{"H","Na","Ag","K","Li","NH4","Ba","Ca","Cu","Mg","Zn","Pb","Fe","Al","Cl","Br","F","I","OH","NO3","O","S","SO4","CO3"});
        Integer[]c={1,1,1,1,1,1,2,2,2,2,2,2,3,3,1,1,1,1,1,1,2,2,2,2},d={5,18,19,22,23};
        List<Integer>j=Arrays.asList(d);
        int e=b.indexOf(a[0]),f=b.indexOf(a[1]),g=c[e],h=c[f],i;
        if(f<e){String p=a[0];a[0]=a[1];a[1]=p;i=g;g=h;h=i;i=e;e=f;f=i;}
        boolean k=j.contains(e),l=j.contains(f),m=g==h,n=g==1,o=h==1;
        return (k&!m&!o?"("+a[0]+")":a[0])+(m?"":o?"":h)+(l&!m&!n?"("+a[1]+")":a[1])+(m?"":n?"":g);
    }
}

```

Try it here

**Data**

Let me know if any of them are wrong

```
H + Cl = HCl
Cl + H = HCl
H + Br = HBr
Br + H = HBr
H + F = HF
F + H = HF
H + I = HI
I + H = HI
H + OH = H2O
OH + H = H2O
H + NO3 = HNO3
NO3 + H = HNO3
H + O = H2O
O + H = H2O
H + S = H2S
S + H = H2S
H + SO4 = H2SO4
SO4 + H = H2SO4
H + CO3 = H2CO3
CO3 + H = H2CO3
Na + Cl = NaCl
Cl + Na = NaCl
Na + Br = NaBr
Br + Na = NaBr
Na + F = NaF
F + Na = NaF
Na + I = NaI
I + Na = NaI
Na + OH = NaOH
OH + Na = NaOH
Na + NO3 = NaNO3
NO3 + Na = NaNO3
Na + O = Na2O
O + Na = Na2O
Na + S = Na2S
S + Na = Na2S
Na + SO4 = Na2SO4
SO4 + Na = Na2SO4
Na + CO3 = Na2CO3
CO3 + Na = Na2CO3
Ag + Cl = AgCl
Cl + Ag = AgCl
Ag + Br = AgBr
Br + Ag = AgBr
Ag + F = AgF
F + Ag = AgF
Ag + I = AgI
I + Ag = AgI
Ag + OH = AgOH
OH + Ag = AgOH
Ag + NO3 = AgNO3
NO3 + Ag = AgNO3
Ag + O = Ag2O
O + Ag = Ag2O
Ag + S = Ag2S
S + Ag = Ag2S
Ag + SO4 = Ag2SO4
SO4 + Ag = Ag2SO4
Ag + CO3 = Ag2CO3
CO3 + Ag = Ag2CO3
K + Cl = KCl
Cl + K = KCl
K + Br = KBr
Br + K = KBr
K + F = KF
F + K = KF
K + I = KI
I + K = KI
K + OH = KOH
OH + K = KOH
K + NO3 = KNO3
NO3 + K = KNO3
K + O = K2O
O + K = K2O
K + S = K2S
S + K = K2S
K + SO4 = K2SO4
SO4 + K = K2SO4
K + CO3 = K2CO3
CO3 + K = K2CO3
Li + Cl = LiCl
Cl + Li = LiCl
Li + Br = LiBr
Br + Li = LiBr
Li + F = LiF
F + Li = LiF
Li + I = LiI
I + Li = LiI
Li + OH = LiOH
OH + Li = LiOH
Li + NO3 = LiNO3
NO3 + Li = LiNO3
Li + O = Li2O
O + Li = Li2O
Li + S = Li2S
S + Li = Li2S
Li + SO4 = Li2SO4
SO4 + Li = Li2SO4
Li + CO3 = Li2CO3
CO3 + Li = Li2CO3
NH4 + Cl = NH4Cl
Cl + NH4 = NH4Cl
NH4 + Br = NH4Br
Br + NH4 = NH4Br
NH4 + F = NH4F
F + NH4 = NH4F
NH4 + I = NH4I
I + NH4 = NH4I
NH4 + OH = NH4OH
OH + NH4 = NH4OH
NH4 + NO3 = NH4NO3
NO3 + NH4 = NH4NO3
NH4 + O = (NH4)2O
O + NH4 = (NH4)2O
NH4 + S = (NH4)2S
S + NH4 = (NH4)2S
NH4 + SO4 = (NH4)2SO4
SO4 + NH4 = (NH4)2SO4
NH4 + CO3 = (NH4)2CO3
CO3 + NH4 = (NH4)2CO3
Ba + Cl = BaCl2
Cl + Ba = BaCl2
Ba + Br = BaBr2
Br + Ba = BaBr2
Ba + F = BaF2
F + Ba = BaF2
Ba + I = BaI2
I + Ba = BaI2
Ba + OH = Ba(OH)2
OH + Ba = Ba(OH)2
Ba + NO3 = Ba(NO3)2
NO3 + Ba = Ba(NO3)2
Ba + O = BaO
O + Ba = BaO
Ba + S = BaS
S + Ba = BaS
Ba + SO4 = BaSO4
SO4 + Ba = BaSO4
Ba + CO3 = BaCO3
CO3 + Ba = BaCO3
Ca + Cl = CaCl2
Cl + Ca = CaCl2
Ca + Br = CaBr2
Br + Ca = CaBr2
Ca + F = CaF2
F + Ca = CaF2
Ca + I = CaI2
I + Ca = CaI2
Ca + OH = Ca(OH)2
OH + Ca = Ca(OH)2
Ca + NO3 = Ca(NO3)2
NO3 + Ca = Ca(NO3)2
Ca + O = CaO
O + Ca = CaO
Ca + S = CaS
S + Ca = CaS
Ca + SO4 = CaSO4
SO4 + Ca = CaSO4
Ca + CO3 = CaCO3
CO3 + Ca = CaCO3
Cu + Cl = CuCl2
Cl + Cu = CuCl2
Cu + Br = CuBr2
Br + Cu = CuBr2
Cu + F = CuF2
F + Cu = CuF2
Cu + I = CuI2
I + Cu = CuI2
Cu + OH = Cu(OH)2
OH + Cu = Cu(OH)2
Cu + NO3 = Cu(NO3)2
NO3 + Cu = Cu(NO3)2
Cu + O = CuO
O + Cu = CuO
Cu + S = CuS
S + Cu = CuS
Cu + SO4 = CuSO4
SO4 + Cu = CuSO4
Cu + CO3 = CuCO3
CO3 + Cu = CuCO3
Mg + Cl = MgCl2
Cl + Mg = MgCl2
Mg + Br = MgBr2
Br + Mg = MgBr2
Mg + F = MgF2
F + Mg = MgF2
Mg + I = MgI2
I + Mg = MgI2
Mg + OH = Mg(OH)2
OH + Mg = Mg(OH)2
Mg + NO3 = Mg(NO3)2
NO3 + Mg = Mg(NO3)2
Mg + O = MgO
O + Mg = MgO
Mg + S = MgS
S + Mg = MgS
Mg + SO4 = MgSO4
SO4 + Mg = MgSO4
Mg + CO3 = MgCO3
CO3 + Mg = MgCO3
Zn + Cl = ZnCl2
Cl + Zn = ZnCl2
Zn + Br = ZnBr2
Br + Zn = ZnBr2
Zn + F = ZnF2
F + Zn = ZnF2
Zn + I = ZnI2
I + Zn = ZnI2
Zn + OH = Zn(OH)2
OH + Zn = Zn(OH)2
Zn + NO3 = Zn(NO3)2
NO3 + Zn = Zn(NO3)2
Zn + O = ZnO
O + Zn = ZnO
Zn + S = ZnS
S + Zn = ZnS
Zn + SO4 = ZnSO4
SO4 + Zn = ZnSO4
Zn + CO3 = ZnCO3
CO3 + Zn = ZnCO3
Pb + Cl = PbCl2
Cl + Pb = PbCl2
Pb + Br = PbBr2
Br + Pb = PbBr2
Pb + F = PbF2
F + Pb = PbF2
Pb + I = PbI2
I + Pb = PbI2
Pb + OH = Pb(OH)2
OH + Pb = Pb(OH)2
Pb + NO3 = Pb(NO3)2
NO3 + Pb = Pb(NO3)2
Pb + O = PbO
O + Pb = PbO
Pb + S = PbS
S + Pb = PbS
Pb + SO4 = PbSO4
SO4 + Pb = PbSO4
Pb + CO3 = PbCO3
CO3 + Pb = PbCO3
Fe + Cl = FeCl3
Cl + Fe = FeCl3
Fe + Br = FeBr3
Br + Fe = FeBr3
Fe + F = FeF3
F + Fe = FeF3
Fe + I = FeI3
I + Fe = FeI3
Fe + OH = Fe(OH)3
OH + Fe = Fe(OH)3
Fe + NO3 = Fe(NO3)3
NO3 + Fe = Fe(NO3)3
Fe + O = Fe2O3
O + Fe = Fe2O3
Fe + S = Fe2S3
S + Fe = Fe2S3
Fe + SO4 = Fe2(SO4)3
SO4 + Fe = Fe2(SO4)3
Fe + CO3 = Fe2(CO3)3
CO3 + Fe = Fe2(CO3)3
Al + Cl = AlCl3
Cl + Al = AlCl3
Al + Br = AlBr3
Br + Al = AlBr3
Al + F = AlF3
F + Al = AlF3
Al + I = AlI3
I + Al = AlI3
Al + OH = Al(OH)3
OH + Al = Al(OH)3
Al + NO3 = Al(NO3)3
NO3 + Al = Al(NO3)3
Al + O = Al2O3
O + Al = Al2O3
Al + S = Al2S3
S + Al = Al2S3
Al + SO4 = Al2(SO4)3
SO4 + Al = Al2(SO4)3
Al + CO3 = Al2(CO3)3
CO3 + Al = Al2(CO3)3

```

**Note**

I started in Pyth, but then I got annoyed with the order and the parenthesis, here is what I had if anyone wants to finish it.

```
=G["H" "Na" "Ag" "K" "Li" "NH4" "Ba" "Ca" "Cu" "Mg" "Zn" "Pb" "Fe" "Al" "Cl" "Br" "F" "I" "OH" "NO3" "O" "S" "SO4" "CO3" 1 1 1 1 1 1 2 2 2 2 2 2 3 3 1 1 1 1 1 1 2 2 2 2)J@G+24xG@QZK@G+24xG@Q1@QZ?kqJKK@Q1?kqJKJ

```

# Answer
> 0 votes
## CoffeeScript, ~~371~~ 333 bytes

This count includes newlines (some newlines can be replaced with semicolons but that wouldn't affect character count)

```
f=(x,y)->(i='indexOf';d='~NH4KNaAgLiBa~CaCuMgZnPbFeAlSO4CO3ClBrFIOHNO3';k=d[i] x;r=-1+Math.ceil k/11;l=d[i] y;a=if k<28then x else y
b=if k<28then y else x
s=if b=='F'then 0else 32>l
r=s=0if r==s;a='(NH4)'if'NH4'==a&&s;b='('+b+')'if/[A-Z]{2}/.test(b)&&r;if'H'==a&&b=='OH'then'H2O'else a+(if!s then''else 1+s)+b+(if!r then''else 1+r))

```

---

```
# Original attempt, 371 bytes
p={H:1,Na:1,Ag:1,K:1,Li:1,NH4:1,Ba:2,Ca:2,Cu:2,Mg:2,Zn:2,Pb:2,Fe:3,Al:3}
n={Cl:1,Br:1,F:1,I:1,OH:1,NO3:1,O:2,S:2,SO4:2,CO3:2}
f=(x,y)->(a=if p[x]then x else y
b=if p[x]then y else x
z=p[a]==n[b]==2;r=+z||n[b];s=+z||p[a];if--r&&a=='NH4'then a='(NH4)'
if--s&&/[A-Z]{2}/.test(b)then b='('+b+')'
if'H'==a&&b=='OH'then'H2O'else a+(if!r then''else r+1)+b+(if!s then''else s+1))

```

# Answer
> 0 votes
## JavaScript (ES6), ~~316~~ 277 bytes

~~I've globalized the `p` and `n` variables (just like I did in CoffeeScript) for easier testing. Localizing the variables would not make a difference in character count.~~

```
f=(x,y)=>{i='indexOf',d='~NH4KNaAgLiBa~CaCuMgZnPbFeAlSO4CO3ClBrFIOHNO3',k=d[i](x),l=d[i](y),a=k<28?x:y,b=k<28?y:x,r=Math.ceil(k/11)-1,s=b=='F'?0:l<32;if(r==s)r=s=0;a=s&&a=='NH4'?'(NH4)':a;b=r&&/[A-Z]{2}/.test(b)?`(${b})`:b;return'H'==a&&b=='OH'?'H2O':a+(s?s+1:'')+b+(r?r+1:'')}

// Original attempt, 316 bytes
p={H:1,Na:1,Ag:1,K:1,Li:1,NH4:1,Ba:2,Ca:2,Cu:2,Mg:2,Zn:2,Pb:2,Fe:3,Al:3},n={Cl:1,Br:1,F:1,I:1,OH:1,NO3:1,O:2,S:2,SO4:2,CO3:2},f=(x,y)=>{a=p[x]?x:y,b=p[x]?y:x,z=p[a]==2&&n[b]==2,r=+z||n[b],s=+z||p[a];a=--r&&a=='NH4'?'(NH4)':a;b=--s&&/[A-Z]{2}/.test(b)?`(${b})`:b;return'H'==a&&b=='OH'?'H2O':a+(r?r+1:'')+b+(s?s+1:'')}

```

### ES5 variant, ~~323~~ 284 bytes

Not much changes apart from getting rid of the arrow function and template string:

```
f=function(x,y){i='indexOf',d='~NH4KNaAgLiBa~CaCuMgZnPbFeAlSO4CO3ClBrFIOHNO3',k=d[i](x),l=d[i](y),a=k<28?x:y,b=k<28?y:x,r=Math.ceil(k/11)-1,s=b=='F'?0:l<32;if(r==s)r=s=0;a=s&&a=='NH4'?'(NH4)':a;b=r&&/[A-Z]{2}/.test(b)?'('+b+')':b;return'H'==a&&b=='OH'?'H2O':a+(s?s+1:'')+b+(r?r+1:'')}

// Original attempt, 323 bytes
p={H:1,Na:1,Ag:1,K:1,Li:1,NH4:1,Ba:2,Ca:2,Cu:2,Mg:2,Zn:2,Pb:2,Fe:3,Al:3},n={Cl:1,Br:1,F:1,I:1,OH:1,NO3:1,O:2,S:2,SO4:2,CO3:2},f=function(x,y){a=p[x]?x:y,b=p[x]?y:x,z=p[a]==2&&n[b]==2,r=+z||n[b],s=+z||p[a];a=--r&&a=='NH4'?'(NH4)':a;b=--s&&/[A-Z]{2}/.test(b)?'('+b+')':b;return'H'==a&&b=='OH'?'H2O':a+(r?r+1:'')+b+(s?s+1:'')}

```

```
f=function(x,y){i='indexOf',d='~NH4KNaAgLiBa~CaCuMgZnPbFeAlSO4CO3ClBrFIOHNO3',k=d[i](x),l=d[i](y),a=k<28?x:y,b=k<28?y:x,r=Math.ceil(k/11)-1,s=b=='F'?0:l<32;if(r==s)r=s=0;a=s&&a=='NH4'?'(NH4)':a;b=r&&/[A-Z]{2}/.test(b)?'('+b+')':b;return'H'==a&&b =='OH'?'H2O':a+(s?s+1:'')+b+(r?r+1:'')}

;['H', 'Na', 'Ag', 'K', 'Li', 'NH4', 'Ba', 'Ca', 'Cu', 'Mg', 'Zn', 'Pb', 'Fe', 'Al'].forEach(function (q) {
    ['Cl', 'Br', 'F', 'I', 'OH', 'NO3', 'O', 'S', 'SO4', 'CO3'].forEach(function (w) {
        document.body.innerHTML += '<p>' + q + ' + ' + w + ' = ' + f(q, w);
    });
});
```

# Answer
> 0 votes
## CJam (137 bytes)

```
{{"SO4CO3ClBrFINO3OHNaAgKLiNH4BaCaCuMgZnPbFeAl":I\#~}$_s"HOH"="HO"1/@?_{I\#G-_0<B*-B/_W>+z}%_~1$=\1?f/W%[.{:T1>{_{'a<},,1>{'(\')}*T}*}]s}

```

This is an anonymous block (function) which takes two ions as strings wrapped in a list, and returns a string.

Online demo.

### Dissection

```
{                        e# Begin a block
  {                      e#   Sort the input list
    "SO4...Al"           e#     Ions in ascending order of charge
    :I                   e#     Stored as I for future reuse
    \#~                  e#     Index and bit-invert to sort descending
  }$

  _s"HOH"="HO"1/@?       e#   Special case for water: replace ["H" "OH"] with ["H" "O"]

  _{I\#G-_0<B*-B/_W>+z}% e#   Copy the list and hash index in I to find the charges
  _~1$=\1?f/             e#   Replace [2 2] by [1 1]
  W%                     e#   Reverse the charges
  [                      e#   Gather in an array
    .{                   e#   Pairwise for each ion and its opponent's reduced charge...
      :T1>{              e#     If the charge (copied to T) is greater than 1
        _{'a<},,         e#       Count the characters in the ion which are before 'a'
        1>{'(\')}*       e#       If there's more than one, add some parentheses
        T                e#       Append T
      }*
    }
  ]
  s                      e#   Flatten the list to a single string
}

```

# Answer
> 0 votes
# Python 3, 364 bytes

Stores the ions by the absolute value of their charges as `index+1` in a 2-D array (0-index elements have +- 1 charge, etc.). Uses string.split() to save a few characters there. Handles the special case of `H + OH = H2O` first, then it calculates how many ions are needed of each sort as the LCM of their two charges divided by its charge. Then adds in parentheses if needed as well as the actual number of ions.

```
from math import*
o=["NH4 NO3 H Na Ag K Li OH I F Br Cl".split(),"CO3 SO4 Ba Ca Cu Mg Zn Pb S O".split(),["Fe","Al"]]
p=["H","OH"]
def c(i):
 for h,k in enumerate(o):
  if i in k:return-~h
def b(x,y):
 if x in p and y in p:return"H20"
 i,j=c(x),c(y);g=gcd(i,j);i//=g;j//=g;return((x,"(%s)"%x)[x[-1]in"34"]+str(j),x)[j==1]+((y,"(%s)"%y)[y[-1]in"34"]+str(i),y)[i==1]

```

Try it online!

---
Tags: code-golf, chemistry
---