title: Consonance or dissonance?

text:
# Question
Title: Consonance or dissonance?
Given two note names, you are to write a program that determines if the interval formed by these two notes is consonant or dissonant.

# Introduction

In Western music, there are only 12 "different" tones. Their names, sorted from lowest to highest, are these: `C, C#, D, D#, E, F, F#, G, G#, A, A#, B`. The sequence is cyclical, i. e. it continues with another `C` after the `B`, infinitely.

The distance between two tones is called an *interval*. The interval between any two notes that are adjacent in the series above (e. g. `C — C#` or `E — F`) is called a *semitone*. The interval between more distant notes is defined as the number of semitone steps needed to get from the first to the second (while possibly wrapping around the sequence). Some examples: `D to E` = 2 semitones, `C to G` = 7 semitones, `B to D#` = 4 semitones (this wraps around the sequence).1

Now, these intervals are divided into two categories: *consonant* (pleasantly sounding if you play the two notes at once) and *dissonant* (not so much).

Let's define the consonant intervals to be: 0, 3, 4, 5, 7, 8 and 9 semitones.

The rest of them is dissonant, namely: 1, 2, 6, 10 and 11 semitones.

# The Challenge

Write a "program" (in the usual broad sense of the word: a function is perfectly OK) to do the following:

* Take two note names (strings from the sequence above) as an input. You may take them however you like (from stdin, as arguments, separated by whatever you want, even feel free to take them as a list of characters (e. g. `["C","#"]`). However, you may not assign any other names to the notes (especially you may not number them from 0 to 11 and use the numbers).
* For you music geeks out there, the notes will be specified without the octave. In this case, it also does not matter in which order the notes come and which is lower and which is higher. Finally, you don't need to handle any names not in the list above. No other enharmonics like `E#`, no flats, double-alterations and so on.
* Pick any two different values. Your program must output one of them whenever the interval formed by the two notes in the input is consonant, and the other if they are not. (Could be `True` and `False`, but even π and e if you want :))
* This is a code-golf. The shortest program in bytes in each language wins. Have fun!

# Examples and Test Cases

```
Note 1    Note 2    Output    Interval [semitones]
  C          D     Dissonant   2
  A#         A#    Consonant   0
  G          D     Consonant   7 (wraparound)
  D#         A     Dissonant   6
  F          E     Dissonant   11
  A          C     Consonant   3

```

I don't add more of them since there aren't any particularly treacherous cases in this.

This is a first challenge of mine, so any constructive criticism is warmly welcome :—). If you find the theory explanation sloppy, feel free to ask questions. Finally, please do not tell me that this is a dupe of this or this. I made sure it's not. (The latter is quite similar but more complex. I thought that putting up a little simpler challenge will make it easier for people to join.)

---

1: I tried to simplify this explanation as far as I could. There's a lot more theory around intervals. Please don't bash me for leaving it out.

# Answer
> 12 votes
# Jelly, 21 bytes

Takes input as a list of two strings. Returns `0` for dissonant or `1` for consonant.

```
OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ

```

Try it online!

```
OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ   - main link
         µ€             - for each note             e.g. ["A#", "C"]
O                       -   convert to ASCII codes  -->  [[65, 35], 67]
 Ḣ                      -   keep the first element  -->  [65, 67]
  6×                    -   multiply by 6           -->  [390, 402]
    %21                 -   modulo 21               -->  [12, 3]
       _L               -   subtract the length     -->  [12, 3] - [2, 1] = [10, 2]
           IA           - absolute difference       -->  8
             “¬ɠṘ’      - the integer 540205
                  æ»    - right-shift               -->  540205 >> 8 = 2110
                    Ḃ   - isolate the LSB           -->  2110 & 1 = 0

```

### Making-of

We first should note that the function **F** that we're looking for is commutative: for any pair of notes **(A, B)**, we have **F(A, B) = F(B, A)**.

Since there are not too many possible inputs and only 2 possible outputs to deal with, it must be possible to find a rather simple hash function **H**, such that **|H(A) - H(B)|** produces a limited range of values and is collision-free for all possible pairs of notes **(A, B)** with respect to the expected output.

We're going to test the set of functions **H(mul, mod)**, which are defined as:

```
H(mul, mod)(s) = ((ORD(s[0]) * mul) MOD mod) - LEN(s)

```

Where `ORD(s[0])` is the ASCII code of the first character of the note and `LEN(s)` is the length of the note (**2** if there's a `'#'` and **1** if not).

Below is a commented version of the JS code that was used to find a couple of valid pairs ***(mul, mod)*** and the resulting bitmasks. There are many possible solutions, but `* 6 % 21` is the shortest one with this method.

```
// all 12 notes
note = ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];

// reference implementation that takes 2 notes
// and returns 0 for dissonant or 1 for consonant
F = (a, b) =>
  +!~[1, 2, 6, 10, 11].indexOf((note.indexOf(a) - note.indexOf(b) + 12) % 12)

for(mul = 1; mul < 100; mul++) {
  for(mod = 1; mod < 31; mod++) {
    // hash function
    H = s => s.charCodeAt() * mul % mod - s.length;

    table = {};

    // for all possible pairs of notes (a, b)
    if(note.every(a => note.every(b => {
      // compute the table index
      idx = Math.abs(H(a) - H(b));

      // and the expected result
      res = F(a, b);

      // if the slot is empty, store the correct value
      if(table[idx] === undefined) {
        table[idx] = res;
        return 1;
      }
      // else, make sure that the correct value is already there
      return table[idx] == res;
    }))) {
      // if all tests pass: translate the table into a binary mask
      for(n = 0, msk = 0; n < 31; n++) {
        msk |= (table[n] || 0) << n;
      }
      // and display the result
      console.log('mul ' + mul + ', mod ' + mod + ' --> ' + msk);
    }
  }
}
```

# Answer
> 9 votes
# APL (Dyalog), ~~62~~ 39 bytes

Uses `⎕IO←0`; 0 is consonant, 1 is dissonant. Takes list of base note chars as left argument and list of sharps as right argument.

```
{⎕A[|-/('C D EF G A '⍳⍺)+⍵=⍕#]∊'BCGKL'}

```

Try it online!

`{``}` anonymous function where  is the left argument and  is the right argument

`⎕A[``]∊'BCGKL'` is the **A**lphabet, indexed by the following, a member of the string?

`⍕#` format the root namespace (yields the sharp character)

`⍵=` are the right argument chars (the sharps) equal to that?

`(``)+` add the following:

`'C D EF G A '⍳⍺` indices of the left argument chars in the string

`-/` difference between those

`|` absolute value

# Answer
> 9 votes
# MATL, ~~30~~ ~~27~~ 26 bytes

```
,j'DJEFPGIALBC'&mQs]ZP7Mdm

```

Inputs the two notes in different lines. Outputs `0` for consonant, `1` for dissonant.

Try it online! Or verify all test cases.

### Explanation

The 11-character string

```
DJEFPGIALBC

```

encodes both the notes and the dissonant intervals, as follows.

The program first *finds the 1-based indices of the input characters* in the above string. A non-sharp input like `D` will give `1`, `E` will give `3`, ..., `C` will give `11`. These numbers can also be considered 1×1 numeric arrays. A sharp input like `C#` will give the 1×2 array `[11 0]`, meaning that `C` was found at position `11` and `#` was not found.

Observe that letters `JPIL` will never be present in the input. For now they are only used as placeholders, so that for example note `E` is *two* semitones above `D`. But they will also be useful to define dissonant intervals.

The numbers in the first entry of the 1×1 or 1×2 array correspond to note pitch in semitones, not counting sharp symbols (yet). Observe that the scale defined by these numbers doesn't start at `C`; but that doesn't matter because we only want intervals, that is, *differences* between notes. Subtracting the obtained numbers would give either the interval or 12 minus the interval. But first we need to consider the sharp symbol.

To consider sharp notes, a golfy way (in MATL) is to add `1` to each entry of the 1×1 or 1×2 array obtained previously and then sum the array (2 bytes). Thus non-sharp notes are increased by `1` and sharp notes by `2`. This makes sharp notes 1 semitone higher than non-sharp notes, as required. We are also adding an extra semitone to all notes, but that doesn't change the intervals between them. So now note `D` will give pitch number `2`, `D#` will give `3`, ..., `C` will give `12`, `C#` will give `13`.

Dissonant intervals are `1`, `2`, `6`, `10`, or `11`. These have a *modulo-12 symmetry*: an interval between two notes is dissonant if and only if the interval with the notes in reverse order, modulo 12, is dissonant.

If we compute the consecutive differences of the string `'DJEFPGIALBC'` we get the numeric vector

```
6 -5 1 10 -9 2 -8 11 -10 1

```

which contains precisely the dissonant intervals, in addition to some negative values, which will be neither useful nor harmful. Observe that it is the choice of additional letters `JPIL` in the string `'DJEFPGIALBC'` that defines (via consecutive differences) the dissonant intervals.

To see if the two input notes are dissonant we take the *absolute difference* of their pitch numbers. For example, `C` and `D#` will give numbers `12` and `3` respectively, and the absolute difference is `9`. The actual difference would be `-9`, and the actual interval would be `3` (obtained as `-9` modulo 12). But thanks to the symmetry referred to above, we can consider `9` instead of `3`. Since `9` is not present in the vector of consecutive differences, the notes are consonant.

# Answer
> 8 votes
# JavaScript (ES6), ~~68~~ 64 bytes

Takes the notes as two strings in currying syntax `(a)(b)`. Returns `0` for dissonant or `1` for consonant.

```
a=>b=>488055>>(g=s=>'C D EF G A'.search(s[0])-!s[1])(a)-g(b)+9&1

```

### Test cases

```
let f =

a=>b=>488055>>(g=s=>'C D EF G A'.search(s[0])-!s[1])(a)-g(b)+9&1

console.log(f('C' )('D' )) // 0 (Dissonant)
console.log(f('A#')('A#')) // 1 (Consonant)
console.log(f('G' )('D' )) // 1 (Consonant)
console.log(f('D#')('A' )) // 0 (Dissonant)
console.log(f('F' )('E' )) // 0 (Dissonant)
console.log(f('A' )('C' )) // 1 (Consonant)
```

### Formatted and commented

```
a => b =>                       // given the two notes 'a' and 'b'
  488055 >>                     // 19-bit lookup bitmask: 1110111001001110111
    (g = s =>                   // we use g() to convert a note 's' into a semitone index
      'C D EF G A'.search(s[0]) // position of the note: -1 for 'B' (not found) to 9 for 'A'
      - !s[1]                   // subtract 1 semitone if the '#' is not there
    )(a)                        // compute the result for 'a'  --> [ -2 ...  9]
    - g(b)                      // subtract the result for 'b' --> [-11 ... 11]
    + 9                         // add 9                       --> [ -2 ... 20]
  & 1                           // test the bitmask at this position (0 if negative or > 18)

```

# Answer
> 7 votes
# Jelly, 26 bytes

```
i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ

```

A monadic link taking a list of the two notes (as lists of characters) and returning `0` for consonant and `1` for dissonant.

**Try it online!** or see all inputs in the test-suite.

### How?

```
i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ - Link: list of lists of characters, notes
              µ€           - for €ach note in notes: (call the resulting list x)
   ØA                      -   yield the uppercase alphabet
i@€                        -   first index of c in ^ for €ach character, c
                           -     ...note '#' is not there so yields 0 (A->1, B->2,...)
      .                    -   literal one half
     o                     -   or (vectorised)  - e.g. "C#" -> [3, 0] -> [3, 0.5]
       S                   -   sum
        Ḥ                  -   double - that is ...  C C#  D D#  E  F F#  G G#  A A#  B
                                                 ->  6  7  8  9 10 12 13 14 15  2  3  4
         ’                 -   decrement         ->  5  6  7  8  9 11 12 13 14  1  2  3
           5               -   literal five
          d                -   divmod                (e.g. 9 -> [1,4] or 11 -> [2,1])
             4             -   literal four
            ḅ              -   convert from base     (e.g. [1,4] -> 8 or [2,1] -> 9)
                                                 ->  4  5  6  7  8  9 10 11 12  1  2  3
                 /         - reduce x with:
                ạ          -   absolute difference   (e.g. ["G#", "A"] -> [12, 1] -> 11)
                  “¢£©½¿‘  - code-page indices = [1, 2, 6, 10, 11]
                         ċ - count occurrences (1 if in the list, 0 if not)

```

# Answer
> 5 votes
# Jelly, 31 bytes

```
O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤

```

Try it online!

wheeeeee 32 bytes too long

# Explanation

```
O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤  Main link
O                                Cast each character to an int using Python `ord`
 _65                             Subtract 65 (A is 0, G is 7)
     “¢[ḋṃ’b⁴¤                   [2, 3, 5, 7, 9, 10, 0]
     “¢[ḋṃ’                      37058720
           b                     Digits in base
            ⁴                    16
    ị                            Index into this list; this creates the gaps for sharps
                 €               For each sublist
              +L$                Add the length to each element (Sharpens sharp notes)
              +                  Add
               L                 Length
                   €             For each sublist
                  Ḣ              Take the first element
                    ạ/           Absolute difference between the two (unoctaved) pitches # It's convenient that every interval's inverse (?) has the same consonance/dissonance
                      e          Is the semitone difference in
                       “cṾ’b12¤  [1, 2, 6, 10, 11]?
                       “cṾ’      25178
                           b     base
                            12   12

```

# Answer
> 4 votes
# Mathematica, 55 bytes

```
function                                                  arguments        bytes

FreeQ[1|2|6|10|11]@Abs[#-#2&@@Sound`PitchToNumber/@#]&    [{"C","F#"}]     55

```

Map the internal built-in `Sound`PitchToNumber` on the input (list of two strings), take the absolute difference, then pattern match for dissonant interval numbers.

---

## Just for fun (non-competing)

Here are some shorter functions that violate the restriction “you may not assign any other names to the notes.” The rudimentary `Music`` package has predefined note constants (like `A4 = 440.`) and the function `HertzToCents` (which can be golfed). Instead of strings, we will use the note constants as arguments, but given in a different format for each function.

```
FreeQ[1|2|6|10|11]@Abs@@Round[.01HertzToCents@#]&         [{C3,Fsharp3}]   50+9=59
FreeQ[1|2|6|10|11]@Abs@Round[17Log[#2/#]]&                [C3,Fsharp3]     43+9=52
FreeQ[1|2|6|10|11]@Abs@Round[17Log@#]&                    [C3/Fsharp3]     39+9=48

```

The package import `<<Music`;` takes 9 bytes.

This function converts a string (like `"F#"`) into a note constant (like `Fsharp3`):

```
Symbol[StringReplace[#,"#"->"sharp"]<>"3"]&                                44

```

To accept intervals larger than an octave, replace `Abs[…]` with `Mod[…,12]`.

---

Why are some intervals considered dissonant? An interval is a ratio of two frequencies. If the ratio has a “simple” numerator and denominator, it tends to be more consonant. In 5-limit tuning, ratios can be factored into integer powers of only prime numbers less than or equal to 5. No interval in equal temperament, besides the octave, is a just interval; they are merely close approximations using powers of the 12th root of 2.

Instead of hard-coding which interval numbers are dissonant, we can find a rational approximation of the interval and then determine if its numerator and denominator are “simple” (meaning that the denominator is less than 5 and the ratio does not divide 7).

This table shows each of the steps in that process.

```
Table[
  Module[{compoundInterval,simpleInterval,rationalApprox,denomLeq5,div7,consonant},
    compoundInterval = Power[2, i/12];
    simpleInterval   = 2^Mod[Log2[compoundInterval], 1];
    rationalApprox   = Rationalize[N@simpleInterval, 1/17];
    denomLeq5        = Denominator[rationalApprox]<=5;
    div7             = Denominator[rationalApprox]>1 && rationalApprox\[Divides]7;
    consonant        = FreeQ[1|2|6|10|11][Mod[i,12]];

    InputForm/@{
      i, simpleInterval, rationalApprox,
      denomLeq5, div7, denomLeq5 && !div7,
      consonant
    }
  ], {i, 0, 12}
]

i   sInterval  ratio   denomLeq5  div7       den&&!div  | consonant?

0   1          1       True       False      True       | True
1   2^(1/12)   17/16   False      False      False      | False
2   2^(1/6)    9/8     False      False      False      | False
3   2^(1/4)    6/5     True       False      True       | True
4   2^(1/3)    5/4     True       False      True       | True
5   2^(5/12)   4/3     True       False      True       | True
6   Sqrt[2]    7/5     True       True       False      | False
7   2^(7/12)   3/2     True       False      True       | True
8   2^(2/3)    8/5     True       False      True       | True
9   2^(3/4)    5/3     True       False      True       | True
10  2^(5/6)    7/4     True       True       False      | False
11  2^(11/12)  11/6    False      False      False      | False
12  1          1       True       False      True       | True

```

The rational approximation lies within `1/17` of the interval because that is the largest threshold that distinguishes between all 12 equal tempered intervals. We match rational numbers with the pattern `Rational[a_,b_]` (or just `a_~_~b_`) first, and then match integers with only `_`.

This culminates in the following rather short function that determines if an arbitrary frequency ratio (greater than 1) is consonant or dissonant.

```
Rationalize[#,1/17]/.{a_~_~b_:>b<=5&&!a∣7,_->True}&       [Fsharp3/C3]     51+9=60

```

# Answer
> 3 votes
# Mathematica, 118 bytes

```
FreeQ[{1,2,6,10,11},Min@Mod[Differences[Min@Position["C|C#|D|D#|E|F|F#|G|G#|A|A#|B"~StringSplit~"|",#]&/@{#,#2}],12]]&

```

**Input form**

> \["A#","D"\]

**Outputs**

```
True->Consonant
False->Dissonant

```

thanks @JonathanFrech -16 bytes

# Answer
> 3 votes
# Charcoal, 30 bytes

```
≔B#A#G#FE#D#Cζ§”o∧⌈ς”⁻⌕ζ⮌θ⌕ζ⮌η

```

Try it online! Link is to verbose version of code. Outputs 1 for consonant, 0 for dissonant. Explanation:

```
≔B#A#G#FE#D#Cζ                  Store reversed note names in z
                        θ       First input
                       ⮌        Reversed
                     ⌕ζ         Find index in z
                            η   Second input
                           ⮌    Reversed
                         ⌕ζ     Find index in z
                     ⁻          Subtract
               ”o∧⌈ς”           Compressed string 100111011100
              §                 Circularly index
                                Implicitly print

```

# Answer
> 2 votes
# J, 68 bytes

```
[:e.&1 2 6 10 11[:(12| -~/)(<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

```

## explanation

A straightforward, not super golfed implementation in J:

* Input is given as boxed itemized notes (produced using cut), in order.
* Find their indexes in the range of notes: `(<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]`
* Subtract the first from the second: `-~/`
* Take the remainder when divided by 12: `12|`
* Check if it's one of the dissonant notes: `e.&1 2 6 10 11`

Try it online!

# Answer
> 2 votes
# ///, ~~90~~ 88 bytes

```
/^/"\///^\/\///C^D/##"E/DD"F/E#"G/FD"A/GD"B/AD"#,#/,"B#^B/#"A#/#"A^G#^G^F#/#"F^E^D#^D/#/

```

Try it online! (all test cases at once)

* Put the input after the code.
* Separate the note names with `,B#` in each test case.
* The output is `,` for consonant, `,#` for dissonant.
* Support for double-alterations (`##`) or `E#` in some particular cases. Otherwise the output is `,` for consonant, `#,` for dissonant (thanks to modulo 12 symmetry)
* Can handle multiple test cases at once (if separated reasonably)
* Lowercase characters are printed exactly.

# Answer
> 2 votes
# C (gcc), 91 bytes

```
g(char*s){return (s[1]&1|2**s&15)*4/5;}f(char*x,char*y){return (1952220<<g(x)>>g(y))&2048;}

```

call: `f("A#", "D")`

Return value:

* Consonant: 2048
* Dissonant: 0

Bonus: The function is case insensitive.

Try it online!

# Answer
> 1 votes
# Python 2, ~~125 117 83 78~~ 77 bytes

```
a,b=map("C C#D D#E F F#G G#A A#B".index,input())
print chr(abs(a-b))in""

```

Where the `""` at the end actually contains the characters `"\x02\x04\x0c\x14\x16"`

Try it Online!

(+3 because I forgot 11 or 22 in the list to begin with)

-8 bytes from Jonathan Frech and switching to Python *2*.

-34 bytes with suggestions from Jonathan Frech and using `str`'s index instead of `list`'s.

-4 bytes from inlining `i` and Neil's reversing the string suggestion (only -2 really, as i forgot `()` around a generator)

-5 bytes from un-inlining `i` & changing the input format

-1 bytes from Jonathan Frech with `map()` and unprintables.

Takes input in one line of stdin in the format:

```
'C','C#'

```

`True` is dissonant, `False` is consonant.

Old Explanation:

```
i='C C#D D#E F F#G G#A A#B'.index
a,b=input()
print abs(i(a)-i(b))in[2,4,12,20]

```

Python `str.index` returns the lowest (positive) starting index of a matching substring, so `"ABACABA".index("A") == 0` and `"ABACABA".index("BA") == 1`. Because of this, we can put the note names evenly spaced in a string, and as long as (for example) `A` comes before `A#`, the shared `A` won't be a problem.

```
i='C C#D D#E F F#G G#A A#B'.index

```

`i` is now a function that returns the index in `'C C#D D#E F F#G G#A A#B'` its argument (a note name) is, which is 2 * (the number of semitones that note is up from `C`)

```
a,b=input()

```

Python 2's `input()` is (mostly) equivalent to `eval(input())` in Python3, so with a valid input of the format `'C#','F'` (for example), `a='C#'` and `b='F'`

```
print abs(i(a)-i(b))in[2,4,12,20]

```

If the disttance between the first note and the second note in the string is not 2, 4, 12, or 20 (since the note names are represented in 2 characters), then the interval is dissonant, print True, else it is consonant, print False.

# Answer
> 1 votes
# C (gcc), 115 ~~117~~ ~~120~~ bytes

```
g(char*a){a=*a-65+!!a[1]*(7-*a/70-*a/67);}f(x,y)char*x,*y;{x="(pP$HL<lt<X"[g(x)]*32+"=ZukW-^h1F6"[g(x)]>>g(y)&1;}

```

Try it online!

Return 1/0 for consonat and dissonat. It is always interesting to do string manipulation with pure C. Take input as `f("A#", "C")`

# Answer
> 0 votes
# PowerShell, 107 bytes

```
param($a,$b)[math]::abs(($x=-split'C C# D D# E F F# G G# A A# B').indexof($b)-$x.indexof($a))-in1,2,6,10,11

```

Try it online!

Outputs `True` for dissonant and `False` for consonant.

Takes input `$a` and `$b`, the two notes, as strings. Performs a `-split` operation on the scale, which splits on whitespace, to create an array of the notes, stores that into `$x`. Finds the `.indexof` `$b` in that array, subtracts the index of `$a`, and then takes the `abs`olute value thereof. Checks whether that number is `-in` the dissonant ranges.

# Answer
> 0 votes
# Python 2, 68 bytes

```
lambda a,b,f='C C#D D#E F F#G G#A A#B'.find:3142>>(f(a)-f(b))/2%12&1

```

Try it online!

Outputs: `1` is dissonant, `0` is consonant.

# Answer
> 0 votes
# SQL, 582 bytes

SQL Fiddle

I still have some golfing to do on it, but I wanted to get it down here before I end up breaking it completely.

If the input is in a letter format, then putting those letters in a table with values is okay, right?

```
CREATE TABLE N(N char(2),v int)
Insert Into N values('A',1),('A#',2),('B',3),('C',4),('C#',5),('D',6),('D#',7),('E',8),('F',9),('F#',10),('G',11),('G#',12);
CREATE TABLE D(D char(9),v int)
Insert Into D values('C',0),('D',1),('D',2),('C',3),('C',4),('C',5),('D',6);
CREATE FUNCTION I(@A char(2),@B char(2))
RETURNS char(9) as
BEGIN
DECLARE @E int=(SELECT v from N where n=@A),@F int=(SELECT v from N where n=@B)
DECLARE @C char(9) = (SELECT case D when 'D' then 'Dissonant' when 'C' then 'Consonant' END from D where v in(abs(@e-@f),12-abs(@e-@f)))
RETURN isnull(@C,'NotANote')
END

```

# Answer
> 0 votes
# Perl 5, 106 bytes

```
("C,C#,D,D#,E,F,F#,G,G#,A,A#,B,"x2)=~/$F[0],(.*?)$F[1],/;$r=(1+($1=~y/,//))%12;say(grep/$r/,(0,3..5,7..9))

```

Try it online!

Returns false for dissonant, true for consonant.

---
Tags: code-golf, music
---


title: Visualize Nicomachus's Theorem

text:
# Question
Title: Visualize Nicomachus's Theorem
Nichomachus's Theorem relates the square of a sum to the sum of cubes:

and has a beautiful geometric visualization:

## Challenge: Create the 2d part of this visualization in ascii.

You will need to ensure that all visual demarcations are upheld by your diagram. This is simplest to do with four "colors," though it's possible to achieve with only three (see last example below for how). With four colors, you use two to distinguish between regions within a "strip" (ie, the different parts that make up a single cube), and two to distinguish between adjacent strips. You may also use more than four colors if you like. If any of this is confusing, the example output below should clarify.

## Input / Output

Input is a single integer greater than 0. Output is an ascii grid similar to the examples below, corresponding to the flattened grid for that input number in the image above. Leading and trailing whitespace are ok.

This is code golf, with standard rules.

## Sample outputs

N = 1

```
#

```

N = 2

```
#oo
o@@
o@@

```

N = 3

```
#oo+++
o@@+++
o@@+++
+++###
+++###
+++###

```

N = 4

```
#oo+++oooo
o@@+++oooo
o@@+++@@@@
+++###@@@@
+++###@@@@
+++###@@@@
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo

```

N = 5

```
#oo+++oooo+++++
o@@+++oooo+++++
o@@+++@@@@+++++
+++###@@@@+++++
+++###@@@@+++++
+++###@@@@#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++

```

Three color version for N = 4, thanks to @BruceForte:

```
#oo+++oooo
o##+++oooo
o##+++####
+++ooo####
+++ooo####
+++ooo####
oo####++++
oo####++++
oo####++++
oo####++++

```

# Answer
> 19 votes
# MATL, ~~30~~ ~~28~~ 27 bytes

```
t:P"@:s:@/Xk&+@+8MPt&(]30+c

```

Try it online!

Bonus features:

* For **26 bytes**, the following modified version produces **graphical output**:

```
 t:P"@:s:@/Xk&+@+8MPt&(]1YG

```

Try it at MATL Online!

* The image is begging for some **colour**, and it only costs 7 bytes:

```
 t:P"@:s:@/Xk&+@+8MPt&(]1YG59Y02ZG

```

Try it at MATL Online!

* Or use a longer version (37 bytes) to see how the character matrix is **gradually built**:

```
 t:P"@:s:@/Xk&+@+8MPt&(t30+cD9&Xx]30+c

```

Try it at MATL Online!

## Example outputs

For input is `8`, the following shows the basic version, graphical output, and colour graphical output.

## Explanation

### General procedure

A numeric matrix is built from outer to inner layers in `N` steps, where `N` is the input. Each step overwrittes an inner (upper-left) part of the previous matrix. At the end, the numbers in the obtained matrix are changed to characters.

### Example

For input `4` the first matrix is

```
10 10  9  9  9  9  8  8  8  8
10 10  9  9  9  9  8  8  8  8
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6

```

As a second step, the matrix

```
7 7 7 6 6 6
7 7 7 6 6 6
7 7 7 6 6 6
6 6 6 5 5 5
6 6 6 5 5 5
6 6 6 5 5 5

```

is overwritten into the upper half of the latter. Then the same is done with

```
6 5 5
5 4 4
5 4 4

```

and finally with

```
3

```

The resulting matrix is

```
3 5 5 6 6 6 8 8 8 8
5 4 4 6 6 6 8 8 8 8
5 4 4 6 6 6 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6

```

Lastly, `30` is added to each entry and the resulting numbers are interpreted as codepoints and converted to characters (thus starting at `33`, corresponding to `!`).

### Construction of the intermediate matrices

For input `N`, consider decreasing values of `k` from `N` to `1`. For each `k`, a vector of integers from `1` to `k*(k+1)` is generated, and then each entry is divided by `k` and rounded up. As an example, for `k=4` this gives (all blocks have size `k` except the last):

```
1 1 1 1 2 2 2 2 3 3

```

whereas for `k=3` the result would be (all blocks have size `k`):

```
1 1 1 2 2 2

```

This vector is added, element-wise with broadcast, to a transposed copy of itself; and then `k` is added to each entry. For `k=4` this gives

```
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
8  8  8  8  9  9  9  9 10 10
8  8  8  8  9  9  9  9 10 10

```

This is one of the intermediate matrices shown above, except that it is flipped horizontally and vertically. So all that remains is to flip this matrix and write it into the upper-left corner of the "accumulated" matrix so far, initiallized to an empty matrix for the first (`k=N`) step.

### Code

```
t       % Implicitly input N. Duplicate. The first copy of N serves as the
        % initial state of the "accumulated" matrix (size 1×1). This will be
        % extended to size N*(N+1)/2 × N*(N+1)/2 in the first iteration
 :P     % Range and flip: generates vector [N, N-1, ..., 1]
"       % For each k in that vector
  @:    %   Push vector [1, 2, ..., k]
  s     %   Sum of this vector. This gives 1+2+···+k = k*(k+1)/2
  :     %   Range: gives vector [1, 2, ..., k*(k+1)/2]
  @/    %   Divide each entry by k
  Xk    %   Round up
  &+    %   Add vector to itself transposed, element-wise with broadcast. Gives
        %   a square matrix of size k*(k+1)/2 × k*(k+1)/2
  @+    %   Add k to each entry of the this matrix. This is the flipped
        %   intermediate matrix
  8M    %   Push vector [1, 2, ..., k*(k+1)/2] again
  Pt    %   Flip and duplicate. The two resulting, equal vectors are the row and
        %   column indices where the generated matrix will be written. Note that
        %   flipping the indices has the same effect as flipping the matrix
        %   horizontally and vertically (but it's shorter)
  &(    %   Write the (flipped) intermediate matrix into the upper-left
        %   corner of the accumulated matrix, as given by the two (flipped)
        %   index vectors
]       % End
30+     % Add 30 to each entry of the final accumulated matrix
c       % Convert to char. Implicitly display

```

# Answer
> 7 votes
# Python 2, ~~187~~ ~~178~~ ~~164~~ ~~162~~ 152 bytes

-8 bytes thanks to Mr.Xcoder
-1 byte thanks to Stephen
-10 bytes thanks to Jonathan Frech

```
g=lambda y:y>1and[l+y*f(y,i)for i,l in enumerate(g(y-1))]+y*[''.join(f(y,i)for i in range(y*-~y/2))]or['#']
f=lambda y,i:'0@+#'[(y*~-y/2%y+i)/y%2+y%2*2]

```

Try it online!

# Answer
> 7 votes
# Charcoal, ~~50~~ 46 bytes

```
Ｆ⮌…·¹Ｎ«≔⊘×ι⊕ιθＦ⊕⊘ι«Ｆ§#+@⁺ικ«ＵＯ⁻θ×ικθλＵＯθ⁻θ×ικλ

```

Try it online! Link is to verbose version of code. Previous 50-byte version with explanation: Try it online!

```
Ｆ⮌…·¹Ｎ«≔÷×ι⁺¹ι²θＦ⁺¹÷ι²«Ｆ§#+@⁺ικ«ＵＯ⁻θ×ικθλＵＯθ⁻θ×ικλ

Ｆ     «     Loop over
  …·¹       Inclusive range from 1 to
     Ｎ      Input as a number
 ⮌          Reversed

   ι⁺¹        Add 1 to current index
  ×   ι       Multiply by current index
 ÷     ²      Divide by 2
≔       θ     Assign to q

Ｆ     «      Loop over
             Implicit range from 0 to
   ÷ι²       Half the current index
 ⁺¹          Plus 1

Ｆ       «    Loop over
  #+@        Literal string
 §           Circularly indexed by
     ⁺ικ     Sum of outer and inner index

    ×ικ     Multiply outer and inner index
  ⁻θ        Subtract from q
ＵＯ     θλ   Draw an oblong (q-ik, q) using that character

ＵＯθ⁻θ×ικλ   Draw an oblong (q, q-ik) using that character

```

Note: I loop over the character rather than trying to assign the character directly to `l` because you can't directly assign the result of indexing a string to a variable as it's an ambiguous construct in Charcoal. Fortunately the byte count is the same.

# Answer
> 5 votes
# C (gcc), ~~135~~ ~~128~~ 120 bytes

```
f(n,m,i,x,y,k){for(m=n*-~n/2,i=m*m;i--;printf("\n%d"+!!(~i%m),(x/k+y/k+k)%3))for(x=i%m,y=i/m,k=n;x>=k&y>=k;x-=k--)y-=k;}

```

Try it online!

Uses only three colors.

Conceptually, works on a grid rotated by 180 degrees:

```
000111
000111
000111
111220
111220
111001

```

And computes colors according to the formula:

```
c(x,y,n) = c(x-n,y-n,n-1)                   if x >= n and y >= n
         = (x div n + y div n + n) mod 3    otherwise

```

# Answer
> 2 votes
# , ~~131~~ ~~126~~ 123 bytes

*3 bytes saved thanks to @Giuseppe*

```
function(n){l=w=sum(1:n)
m=matrix(,l,l)
for(i in n:1){m[l:1,l:1]=outer(x<-(1:l-1)%/%i,x,`+`)+i
l=l-i}
write(m%%4,"",w,,"")}

```

Try it online!

This uses the same algorithm as @LuisMendo 's MATL answer. The only difference is that rather than converting to characters, the matrix is output with all of the values mod4 to ensure that each element is a single ascii character.

# Answer
> 2 votes
# Python 2, ~~176~~ 175 bytes

```
n=input()
R,J=range,''.join;r=[]
for i in R(n+1):
 S=sum(R(i));c='AxBo'[i%2::2]
 for j in R(S):r[~j]+=c[j/i%2]*i
 r+=[J(c[-j/i%2]for j in R(S+i,0,-1))]*i
for l in r:print J(l)

```

Try it online!

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


title: Is the question undeleted?

text:
# Question
Title: Is the question undeleted?
# Challenge

Given a positive integer, determine whether that number is currently being used to represent a question on PPCG.

The question must not have been removed, but may be open or closed.

The number is the one being used in the URL of the question, such as:

> https://codegolf.stackexchange.com/questions/\[input\]

Note that this questions is tagged , but you may not need this to complete the challenge.

# Examples

> 1: Truthy (represents Just Another Perl Hacker)
>
> 3: Falsey (was once Solve the Tower of Hanoi, but was removed by a moderator.
>
> 127030: Falsey (was once Helping Danny to Maximize his Score, but was removed by the author.)
>
> 127147: Truthy (Fastest algorithm to take the product of all subsets)

# Scoring

This is , so the shortest answer in each language wins.

# Answer
> 3 votes
## bash, 52 bytes

```
curl -IL codegolf.stackexchange.com/q/$1|grep 2\ 200

```

Takes input as a command line argument, and outputs in the form of exit code: `0` or "success" (truthy) for an undeleted question, and `1` or "failure" (falsy) for a nonexistent or deleted question.

It also prints a bunch of junk to STDERR and potentially STDOUT, but this is allowed to be ignored as per meta.

As an explanation, the `-I` flag to `curl` sends an HTTP HEAD request (fetch only the headers), and `-L` will follow redirects (http to https, and then /q to /questions). The full output from the `curl` command will look something like this:

```
HTTP/1.1 301 Moved Permanently
Location: https://codegolf.stackexchange.com/q/127030
X-Request-Guid: 1a0b6059-057c-448c-bfc9-a96f1b373abf
Content-Length: 160
Accept-Ranges: bytes
Date: Tue, 20 Jun 2017 04:07:30 GMT
Via: 1.1 varnish
Age: 503
Connection: keep-alive
X-Served-By: cache-itm7423-ITM
X-Cache: HIT
X-Cache-Hits: 1
X-Timer: S1497931651.709631,VS0,VE0
Vary: Fastly-SSL
X-DNS-Prefetch-Control: off
Set-Cookie: prov=933ae4b0-81b0-2b37-e26e-59a0fbb6991a; domain=.stackexchange.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly

HTTP/2 302
date: Tue, 20 Jun 2017 04:07:31 GMT
content-type: text/html; charset=utf-8
location: https://codegolf.stackexchange.com/questions/127030/helping-danny-to-maximize-his-score
x-frame-options: SAMEORIGIN
x-request-guid: fdcaf556-7ae6-4240-89a1-ace7625f8821
strict-transport-security: max-age=15552000
accept-ranges: bytes
via: 1.1 varnish
age: 0
x-served-by: cache-nrt6132-NRT
x-cache: MISS
x-cache-hits: 0
x-timer: S1497931651.085546,VS0,VE166
vary: Fastly-SSL
x-dns-prefetch-control: off
set-cookie: prov=5e314a4f-0c50-08ef-afa2-9388b37e3b7a; domain=.stackexchange.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
cache-control: private
content-length: 204

HTTP/2 404
date: Tue, 20 Jun 2017 04:07:31 GMT
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-request-guid: 3f72afb7-81e8-4e69-a8ad-474534f2abe6
strict-transport-security: max-age=15552000
accept-ranges: bytes
via: 1.1 varnish
age: 0
x-served-by: cache-nrt6132-NRT
x-cache: MISS
x-cache-hits: 0
x-timer: S1497931651.323339,VS0,VE189
vary: Fastly-SSL
x-dns-prefetch-control: off
set-cookie: prov=cede4119-eba5-d799-e376-848e4e457f07; domain=.stackexchange.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
cache-control: private
content-length: 42158

```

Note that the `2\ 200` (equivalent to `'2 200'`) will match the line `HTTP/2 200` if it exists (HTTP OK), and it will not match `HTTP/2 404` (Not Found) for questions that do not exist. (The inclusion of the `2` is necessary to avoid false positives if some of the other headers happen to contain the sequence `200`.)

# Answer
> 1 votes
# Python 2 \+ Requests, 112 bytes

Takes input as a string or integer and outputs 1 for truthy and 0 for falsy.

```
lambda n:len(get('http://api.stackexchange.com/posts/%s?site=codegolf'%n).json()['items'])
from requests import*

```

# Answer
> 1 votes
# Python 3 + Requests, ~~107~~ ~~99~~ ~~98~~ ~~92~~ 79 bytes

```
lambda m:get("http://codegolf.stackexchange.com/q/"+m).ok
from requests import*

```

<sub>-8 bytes by changing `question` to `q`
-1 byte by changing `!=` to `<`, since `200 OK` is less than `404 NOT FOUND`.
-1 byte by changing `https` to `http`
-6 bytes by changing to a `lambda`
-13 bytes using the `ok` attribute</sub>

# Answer
> 1 votes
# Mathematica, 70 bytes

Takes input as a string and outputs 1 for truthy and 0 for falsy.

```
Check[Import["https://codegolf.stackexchange.com/questions/"<>#];1,0]&

```

# Answer
> 1 votes
# JavaScript (ES6), ~~104~~ 102 bytes

Returns a Promise containing a JSON object for truthy or `undefined` for falsey.

```
n=>fetch(`//api.stackexchange.com/questions/${n}?site=codegolf`).then(r=>r.json()).then(j=>j.items[0])

```

---

## Try it

```
f=
n=>fetch(`//api.stackexchange.com/questions/${n}?site=codegolf`).then(r=>r.json()).then(j=>j.items[0])
oninput=_=>f(+i.value).then(console.log);f(i.value=1).then(console.log)
```

```
<input id=i type=number>
```

# Answer
> 0 votes
# Stratos, 16 bytes

```
f"¹⁵s/%²"r"⁷s"
l

```

Explanation (decompressed:

```
f"api.stackexchange.com/questions/%?site=codegolf"         Replace % with the input, and get from this URL
                                                  r"items" Get the JSON array named "items"
l                                                          Length

```

Prints 1 for truthy, and 0 for falsy.

Try it!

---
Tags: code-golf, stack-exchange-api
---


title: 2 plus 2 equals fish!

text:
# Question
Title: 2 plus 2 equals fish!
Thank you for you help fixing my calculator's multiply function, but I've found another critical error all calculators seem to share. None of them understand that 2+2=fish. So now I need code to properly add 2 numbers.

Challenge

* Take 2 numbers as input (Type doesn't matter, but only 2 items will be passed. This is addition, so order obviously doesn't matter.)
* Output sum of both numbers except if they are both 2, then output `fish` (case insensitive)
    + PS. I never was really good with counting, so I think only Integers from 0 to 99 are real numbers (Type used doesn't matter)
* Fewest bytes per language wins!

(NOTE: The key difference between this challenge and the previous, is that order is now irrelevant, and the return type is not restricted to int, which has major implications for type safe languages like Java. You can also see in the answers already here that in non type strict languages like Python, this rule set can dramatically change the answer code.)

# Answer
# Python 2, 33 bytes

```
lambda x,y:x==y==2and"fish"or x+y

```

Try it online!
> 1 votes

# Answer
# C (gcc), 30 bytes

```
f(x,y){x=x^y&&x^2?x+y:"fish";}

```

Try it online!
> 1 votes

---
Tags: code-golf, arithmetic
---


title: The Take-back counting algorithm

text:
# Question
Title: The Take-back counting algorithm
Kids who are learning how to count often know runs of numbers, but can't seem to put those runs together properly.

For example, they might say:

```
1,2,3,4,7,8,9,10

```

Sometimes kids will realize that they skipped some numbers, and go back:

```
1,2,3,4,7,8,5,6,7,8,9,10

```

This is clearly the superior pattern. We need to identify them.

To identify these lists:

1. We identify the minimum `M` and the maximum `N` of the list
2. We step through the list. If the current number is greater than or equal to any member of the list to its right, then we remove the current number.
3. Iff the remaining list contains all numbers from `M` to `N`, then we return a truthy value.

You can assume your input list will contain at least 1 element. You can assume that all integers will be non-negative.

## Test cases:

Truthy:

```
0
10
0 0 0
1 0 1
0 1 2 3 4 5 6 7 8 9 10
0 1 2 3 0 1 2 3
0 1 2 3 4 5 5
0 1 1 2 2 3
0 3 6 1 4 7 2 5 8 3 4 5 6 7 8
1 3 5 7 2 3 4 5 6 7
5 6 0 1 2 3 6 7 4 5 6 7
5 6 7 8
5 5 6 7 8
4 6 7 8 3 4 5 6 7 8

```

Falsy:

```
1 0
4 3 2 1
1 2 3 7 8 9
0 1 2 3 1 3
0 1 2 3 1 3 4
0 1 2 3 1 3 2 4
0 1 2 3 1 3 2 4 3
1 3 5 7 2 4 6 8
0 1 2 1 3 4 5 6
4 5 6 3 4 5

```

This is , so make your answers as short as possible!

# Answer
# 05AB1E, 5 bytes

I am not 100% certain this works, but it passes all test cases and I couldn't find any situation where it fails.

```
Ú¥1QP

```

Try it online!

```
Ú¥1QP   Main link. Argument a
Ú       Reverse uniquify a, keeps only last occurence of each element
 ¥      Get all deltas - all 1 if ascending list
  1Q    Compare all deltas to 1
    P   Product of all results

```
> 6 votes

# Answer
# Jelly, ~~10~~ 9 bytes

```
ṀrṂɓṚ«\Q⁼

```

Try it online!

### How it works

```
ṀrṂɓṚ«\Q⁼  Main link. Argument: A (array)

Ṁ          Yield the maximum of A.
  Ṃ        Yield the minimum of A.
 r         Yield R := [max(A), ... min(A).
   ɓ       Begin a new chain. Left argument: A. Right argument: R
    Ṛ      Reverse A.
     «\    Take the cumulative minimum.
       Q   Unique; deduplicate the results.
        ⁼  Compare the result with R.

```
> 2 votes

# Answer
# Ruby, ~~59 54~~ 41 bytes

```
->a{a.reverse|[]==[*a.max.downto(a.min)]}

```

Try it online!
> 2 votes

# Answer
# Python 2, 81 bytes

```
x=input();r=m=[]
for n in x[::-1]:r=[n][:n<m]+r;m=r[0]
print r==range(m,max(x)+1)

```

Try it online!
> 1 votes

# Answer
# PHP, 148 130 bytes

-18 bytes, thanks @Christoph

```
$a=explode(' ',$argn);$b=range(min($a),max($a));foreach($a as$i=>&$k)for(;++$i<count($a);)$k<$a[$i]?:$k=-1;echo!array_diff($b,$a);

```

Try it online!
> 1 votes

# Answer
# Java 8, ~~264~~ 262 bytes

```
import java.util.*;l->{int m=Collections.max(l),n=Collections.min(l),i=0,q;for(;i<(q=l.size());i++)if(l.subList(i+1,q).size()>0&&l.get(i)>=Collections.min(l.subList(i+1,q)))l.remove(i--);for(i=0;n<=m;)if(i<l.size()&&l.get(i++)==n)n++;else return 0>1;return 1>0;}

```

**Explanation:**

Try it here.

```
import java.util.*;                 // Import for Collections

l->{                                // Method with integer-ArrayList parameter and boolean return-type
  int m=Collections.max(l),         //  Max of the list
      n=Collections.min(l),         //  Min of the list
      i=0,q;                        //  Two temp integers
  for(;i<(q=l.size());i++)          //  Loop (1) over the list
    if(l.subList(i+1,q).size()>0    //   If the sublist right of the current item is not empty
    &&l.get(i)>=Collections.min(l.subList(i+1,q)))
                                    //   and if the current item is larger or equal to the lowest value of this sublist
      l.remove(i--);                //    Remove the current item from the main list
                                    //  End of loop (1) (implicit / single-line body)
  for(i=0;n<=m;)                    //  Loop (2) from min to max
    if(i<l.size()                   //   If the current item doesn't exceed the list's size
    &&l.get(i++)==n)                //   and the items are in order so far
      n++;                          //    Go to the next item
    else                            //   Else:
      return 0>1;//false            //    Return false
                                    //  End of loop (2) (implicit / single-line body)
  return 1>0;//true                 //  Return true
}                                   // End of method

```
> 1 votes

# Answer
# R, ~~88~~ 85 bytes

```
y=NULL;for(i in x<-scan())if(all(i<x[-(1:(F<-F+1))]))y=c(y,i);all(min(x):max(x)%in%y)

```

This can probably be golfed down further. Loops over the elements of `x`, checks if all upcoming values are bigger, and only then keeps that element. After the loop it creates a sequence from `min(x)` to `max(x)`, and checks with `%in%` if all values are included in the pruned version of `x`.
> 1 votes

# Answer
## JavaScript (ES6), 60 bytes

```
s=>(o={},s.reverse().every((n,i)=>!i|o[n+1]|o[n]&&(o[n]=1)))

```

**Ungolfed:**

```
s=>(
  o={},
  s.reverse().every((n,i)=>
    !i|o[n+1]|o[n]&&(o[n]=1)
  )
)

```

This is a simpler algorithm:

Iterate the array in reverse, and make sure each number (except the first) is one less than or equal to a number already seen.

**Snippet:**

```
f=

s=>(o={},s.reverse().every((n,i)=>!i|o[n+1]|o[n]&&(o[n]=1)))

console.log('Truthy');
console.log(f([0]))
console.log(f([10]))
console.log(f([0,0,0]))
console.log(f([1,0,1]))
console.log(f([0,1,2,3,4,5,6,7,8,9,10]))
console.log(f([0,1,2,3,0,1,2,3]))
console.log(f([0,1,2,3,4,5,5]))
console.log(f([0,1,1,2,2,3]))
console.log(f([0,3,6,1,4,7,2,5,8,3,4,5,6,7,8]))
console.log(f([1,3,5,7,2,3,4,5,6,7]))
console.log(f([5,6,0,1,2,3,6,7,4,5,6,7]))
console.log(f([5,6,7,8]))
console.log(f([5,5,6,7,8]))
console.log(f([4,6,7,8,3,4,5,6,7,8]))

console.log('Falsy');
console.log(f([1,0]))
console.log(f([4,3,2,1]))
console.log(f([1,2,3,7,8,9]))
console.log(f([0,1,2,3,1,3]))
console.log(f([0,1,2,3,1,3,4]))
console.log(f([0,1,2,3,1,3,2,4]))
console.log(f([0,1,2,3,1,3,2,4,3]))
console.log(f([1,3,5,7,2,4,6,8]))
console.log(f([0,1,2,1,3,4,5,6]))
console.log(f([4,5,6,3,4,5]))
```
> 1 votes

# Answer
## Haskell, 62 bytes

```
g(a:b)=[a|all(a<)b]++g b
g a=a
f x=g x==[minimum x..maximum x]

```

Try it online!

A direct implementation of the definition where `g` removes the elements if they are \>= than the the elements to its right.
> 1 votes

# Answer
# C#, 69 bytes

```
s=>s.Where((e,i)=>s.Skip(i+1).All(r=>e<r)).Count()==s.Max()-s.Min()+1

```

In short:
s = input (s)equence
take from s element where all items after this one (skip (I)ndex + 1 items), current value is higher
count these, and see if the amount left is equal to the amount expected ((max)imum value minus (min)imum) amount of numbers

Try it online!
> 1 votes

# Answer
## JavaScript (ES6), ~~82~~ ~~73~~ ~~72~~ 70 bytes

Returns a boolean.

```
a=>a.filter((x,i)=>k-=a.every(y=>~i--<0|y>x,m=x>m?x:m),m=k=0)[0]+~m==k

```

### How?

We iterate on each element ***x*** of the input array ***a***, keeping track of the maximum encountered value ***m*** and the number ***-k*** of values that are not greater than or equal to any member to their right. By definition, valid values appear in strictly ascending order.

We use `filter()` rather than `map()`, so that all elements get filtered out until ***k*** turns negative. This allows us to isolate the first valid element, which is also guaranteed to be the minimum value of the array.

Finally, we test whether `minimum - (maximum + 1) == -number_of_valid_elements`:

```
a.filter(...)[0] + ~m == k

```

### Test cases

```
let f =

a=>a.filter((x,i)=>k-=a.every(y=>~i--<0|y>x,m=x>m?x:m),m=k=0)[0]+~m==k

console.log('[Truthy]');
console.log(f([0]));
console.log(f([10]));
console.log(f([0,0,0,]));
console.log(f([1,0,1]));
console.log(f([0,1,2,3,4,5,6,7,8,9,10]));
console.log(f([0,1,2,3,0,1,2,3]));
console.log(f([0,1,2,3,4,5,5]));
console.log(f([0,1,1,2,2,3]));
console.log(f([0,3,6,1,4,7,2,5,8,3,4,5,6,7,8]));
console.log(f([1,3,5,7,2,3,4,5,6,7]));
console.log(f([5,6,0,1,2,3,6,7,4,5,6,7]));
console.log(f([5,6,7,8]));
console.log(f([5,5,6,7,8]));
console.log(f([4,6,7,8,3,4,5,6,7,8]));

console.log('[Falsy]');
console.log(f([1,0]));
console.log(f([4,3,2,1]));
console.log(f([1,2,3,7,8,9]));
console.log(f([0,1,2,3,1,3]));
console.log(f([0,1,2,3,1,3,4]));
console.log(f([0,1,2,3,1,3,2,4]));
console.log(f([0,1,2,3,1,3,2,4,3]));
console.log(f([1,3,5,7,2,4,6,8]));
console.log(f([0,1,2,1,3,4,5,6]));
console.log(f([4,5,6,3,4,5]));
```
> 0 votes

---
Tags: code-golf, sequence
---


# Question
Title: How do I ask a teller for money at the bank?
I need to go to the bank and withdraw some money. I need to withdraw $30, $22 to pay my roommate for the internet and $8 for laundry. Since neither of these can make change, I need my $30 to be split into two partitions of the two sizes. That means when the teller asks me how I want my $30 I am going to have to make a request. I could tell them I want it in a twenty, a fiver, and five ones. But I want to make my request as simple as possible as to avoid having to repeat myself. To make my request simpler I could ask that my cash contain a twenty and at least 2 ones because the 8 is implied by the total, but better yet I could simply request that one of the bills I receive be a one dollar bill (If you are not convinced of this just try to make 29 dollars without making 8).

So that's all fine and dandy but I need to do this calculation every time I go to the bank so I thought I would write a program to do this (have you write a program to do this for me).

Your program or function should take a list of integers representing all the payments I need to make and a set of integers representing the denominations of bills available at the bank, and you must output the smallest list of denominations such that every way to make the total that includes that list of denominations can be cleanly divided into the list of payments.

**Extra rules**

* You may assume that the denomination list will always contain a `1` or you may add it to each list yourself.
* Some inputs will have multiple minimal solutions. In these cases you may output either one.

This is so answers will be scored in bytes with less bytes being better.

### Test Cases

```
Payments, denominations    -> requests
{22,8}    {1,2,5,10,20,50} -> {1} or {2}
{2,1,2}   {1,5}            -> {1}
{20,10}   {1,2,5,10,20,50} -> {}
{1,1,1,1} {1,2}            -> {1,1,1}
{20,6}    {1,4,5}          -> {1}
{2,6}     {1,2,7}          -> {2}
{22, 11}  {1, 3, 30, 50}   -> {1, 3}
{44, 22}  {1, 3, 30, 50}   -> {1, 3, 3, 30}

```

# Answer
> 5 votes
# JavaScript (ES6), ~~485~~ 476 bytes

Alright ... this is a monster. :-(
But it's a rather fast monster that solves all test cases almost instantly.

I may attempt some more advanced golfing later, but I've already spent far too much time on it.

```
f=(b,a,L=[...a])=>L.reduce((a,x)=>[...a,...a.map(y=>[x,...y])],[[]]).sort((a,b)=>a[b.length]||-1).find(L=>(Y=G(U(b)-U(L),L.sort((a,b)=>a-b)),Y[0]&&!Y.some(a=>P(b.map(a=>G(a,[]))).every(b=>b+''!=a))),U=a=>~~eval(a.join`+`),P=(e,C=[],R=[])=>e[0].map(v=>R=(c=v.map((x,i)=>x+(C[i]|0)),e[1])?[...P(e.slice(1),c),...R]:[c,...R])&&R,G=(n,l)=>(S=[],g=(n,l)=>n?a.map(x=>x<l[0]|x>n||g(n-x,[x,...l])):S=[l.map(v=>s[a.indexOf(v)]++,s=[...a].fill(0))&&s,...S])(n,l)&&S)||f(b,a,[...a,...L])

```

### Test cases

```
f=(b,a,L=[...a])=>L.reduce((a,x)=>[...a,...a.map(y=>[x,...y])],[[]]).sort((a,b)=>a[b.length]||-1).find(L=>(Y=G(U(b)-U(L),L.sort((a,b)=>a-b)),Y[0]&&!Y.some(a=>P(b.map(a=>G(a,[]))).every(b=>b+''!=a))),U=a=>~~eval(a.join`+`),P=(e,C=[],R=[])=>e[0].map(v=>R=(c=v.map((x,i)=>x+(C[i]|0)),e[1])?[...P(e.slice(1),c),...R]:[c,...R])&&R,G=(n,l)=>(S=[],g=(n,l)=>n?a.map(x=>x<l[0]|x>n||g(n-x,[x,...l])):S=[l.map(v=>s[a.indexOf(v)]++,s=[...a].fill(0))&&s,...S])(n,l)&&S)||f(b,a,[...a,...L])

console.log(JSON.stringify(f([22,8], [1,2,5,10,20,50])))
console.log(JSON.stringify(f([2,1,2], [1,5])))
console.log(JSON.stringify(f([20,10], [1,2,5,10,20,50])))
console.log(JSON.stringify(f([1,1,1,1], [1,2])))
console.log(JSON.stringify(f([20,6], [1,4,5])))
console.log(JSON.stringify(f([2,6], [1,2,7])))
console.log(JSON.stringify(f([22,11], [1,3,30,50])))
console.log(JSON.stringify(f([44,22], [1,3,30,50])))
```

### How?

*NB: This is not matching the current version anymore, but is much easier to read that way.*

```
// b = list of payments, a = list of bills,
// L = list from which the requested bills are chosen
f = (b, a, L = [...a]) => (
  // U = helper function that computes the sum of an array
  U = a => ~~eval(a.join`+`),

  // P = function that computes the summed Cartesian products of arrays of integers
  // e.g. P([[[1,2],[3,4]], [[10,20],[30,40]]]) --> [[33,44], [13,24], [31,42], [11,22]]
  P = (e, C = [], R = []) => e[0].map(v => R =
    (c = v.map((x, i) => x + (C[i] | 0)), e[1]) ? [...P(e.slice(1), c), ...R] : [c, ...R]
  ) && R,

  // G = function that takes a target amount and a list of requested bills and returns
  // all combinations that contain the requested bills and add up to this amount;
  // each combination is translated into a list of number of bills such as [2,0,0,1,0]
  G = (n, l) => (
    S = [],
    g = (n, l) => n ?
      a.map(x => x < l[0] | x > n || g(n - x, [x, ...l])) :
      S = [l.map(v => s[a.indexOf(v)]++, s = [...a].fill(0)) && s, ...S]
  )(n, l) && S,

  // compute X = list of possible bill combinations to process all payments
  X = P(b.map(a => G(a, []))),

  // compute the powerset of L and sort it from shortest to longest list
  L.reduce((a, x) => [...a, ...a.map(y => [x, ...y])], [[]])
  .sort((a, b) => a[b.length] || -1)

  .find(L => (
    // compute Y = list of possible combinations to reach the total amount,
    // using the requested bills
    Y = G(U(b) - U(L), L.sort((a, b) => a - b)),

    // exit if Y is not empty and all combinations in Y allow to generate all payments
    Y[0] && !Y.some(a => X.every(b => b + '' != a)))
  )

  // if no solution was found, enlarge the set of requested bills and try again
  || f(b, a, [...a, ...L])
)

```

# Answer
> 4 votes
# Python 2, 456 455 bytes

**Extremely, extremely, extremely slow!!!!** Should work correctly on all the input examples given enough time

**Edit:** Saved 1 byte thanks to @Jonathan Frech

```
def F(p,d):v=sum(p);E=enumerate;l=lambda x,y:y[1:]and(x>=y[-1]and[k+[y[-1]]for k in l(x-y[-1],y)]+l(x,y[:-1])or l(x,y[:-1]))or[[1]*x];Q=l(v,d);m=lambda x,y=[0]*len(p):x and max(m(x[1:],[a+x[0]*(i==j)for i,a in E(y)])for j,_ in E(y))or y==p;f=lambda x,h=[]:x and min([S for i,s in E(x)for S in h+[s],f(x[:i]+x[i+1:],h+[s])if all(map(m,filter(lambda k:all(k.count(j)>=S.count(j)for j in S),Q)))],key=len)or[1]*v;print-(all(map(m,Q))-1)*min(map(f,Q),key=len)

```

Try it online!

## Explanation

```
p,d=input() # Read input
v=sum(p) # Save a byte by keeping track of the total money withdrawn
E=enumerate # We use enumerate a lot
# Generates the possible combinations of denominators that add up to the withdrawn amount
l=lambda x,y:y[1:]and(x>=y[-1]and[k+[y[-1]]for k in l(x-y[-1],y)]+l(x,y[:-1])or l(x,y[:-1]))or[[1]*x]
# We use the list generated by l quite a few times
Q=l(v,d)
# Checks if we can divide a list of denominators x in such a way that we get the wished division of the money
m=lambda x,y=[0]*len(p):x and max(m(x[1:],[a+x[0]*(i==j)for i,a in E(y)])for j,_ in E(y))or y==p
# For a list of denominators, it tries all possible combinations of the denominators as input to the teller, selecting the one with minimum length
f=lambda x,h=[]:x and min([S for i,s in E(x)for S in h+[s],f(x[:i]+x[i+1:],h+[s])if all(map(m,filter(lambda k:all(k.count(j)>=S.count(j)for j in S),Q)))],key=len)or[1]*v
# Call f with all possible lists of denominators, and check if saying nothing to the teller will work
print-(all(map(m,Q))-1)*min(map(f,Q),key=len)

```

---
Tags: code-golf, math
---


title: Use an editor to write "Hello, World"

text:
# Question
Title: Use an editor to write "Hello, World"
# Objective

Use any editor or IDE (vim, emacs, IntelliJ, etc) to write a valid "Hello, World" program in any C-like language. The "!" is optional, but you get style points if you use it. You may use publicly available plugins, a publicly available vimrc, etc, but you may not write or make modifications to them specifically for this challenge.

# Winning

Fewest key presses and mouse clicks and touchscreen taps :P wins (only counted when the key is pressed down).

# Submission:

A valid submission requires the number of key presses, the editor used, the language used, a list of the keystrokes pressed, and the important parts of any vimrc, a list of plugins, or anything else required to replicate your result.

# Answer
> 4 votes
# Vim with Ultisnips in C (gcc), 30 keystrokes

`i``ma``Tab``Tab``puts("Hello, World!");``Esc``:``x`

### Explanation

To use the above you'll need the mentioned Plugin installed and `g:UltiSnipsExpandTrigger` and `g:UltiSnipsJumpForwardTrigger` bound to `Tab`, further you'll need this snippet in your `g:UltiSnipsDir`. This also makes the assumption that you opened a file which sets `filetype=c`:

* `i``ma`: Change to Insert mode and enter `ma`
* `Tab``Tab`: Select and expand the `main <snip>`
* `puts("Hello, World!");`: Insert the remaining characters
* `Esc`: Change to Normal mode
* `:``x`: Write the file and exit

The resulting file looks like this:

```
int main(int argc, char *argv[])
{
  puts("Hello, World!");
  return 0;
}

```

**Note**: I couldn't just now find a complete `vimrc` but here's a StackOverflow post that mentions the relevant parts.

# Answer
> 3 votes
# Notepad++, 17 keystrokes, R

```
cat("Hello, World")

```

19 keystrokes with `!`

```
cat("Hello, World!

```

# Answer
> 1 votes
# WebStorm in ECMAScript, 16 keystrokes

al`Enter`"Hello, World

---
Tags: hello-world, vim
---


title: All Aboard the ASCII Train

text:
# Question
Title: All Aboard the ASCII Train
# All Aboard the ASCII Train!

```
    o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___
   o       | C |   | O |   | D |   | E |   |   |   | G |   | O |   | L |   | F |
  TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
 {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

```

You best be prepared to ride the train, because you're about to build the train you'll be riding on. Given a string `s`, output a fully formed train as depicted above. The first thing output is always the engine that'll be tugging your string along, as depicted alone below:

```
    o O O
   o
  TS__[O]
 {======|
./o--000'

```

Following the locomotive are rail-cars containing each character of your precious cargo. To save confusion when unloading, your company has tasked you with labeling the outside of these cars. The cars in question will always look like this:

```
   ___
  | # |
  |___|
_|"""""|
"`-0-0-'

```

Where the `#` is representative of the character that is inside the "cargo" hold. Chaining the engine to each car is also part of your job, as you've been tasked with overseeing the fluidity and success of this entire shipment. So, once you've labeled all the cars and got the engine on the tracks, you must ensure that the train is assembled and ready to roll.

# Rules

* The only input your program should take is a single string.
* The engine must always be output, even if your shipment is empty.
* Each car can only hold one character, don't push your luck you may damage the goods.
* You need only support the following printable ASCII characters: `_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
If you end up doing more, that's fine too, but this is the bare minimum.
* 1-2 trailing spaces are acceptable, as is a single trailing newline.
* This is , shortest byte-count wins.

# Answer
> 4 votes
# 05AB1E, ~~101~~ 99 bytes

Naive first attempt.

```
"    o O O   o"ð7×"TS__[O] {======|./o--000'"J5ä¹v… _ €ÐJy“ | ÿ |   |___| _|"""""|"`-0-0-'“«5ä})øJ»

```

Try it online!

# Answer
> 39 votes
# JavaScript (ES6), ~~149~~ 144 bytes

```
s=>`    o O Oa   ___
   o     a  | $& |
  TS__[O]a  |___|
 {======|a_|"""""|
./o--000'a"\`-0-0-'`.replace(/a(.*)/g,(_,c)=>s.replace(/./g,c))

```

I don't think the engine itself can be compressed, but perhaps it's possible.

### Test snippet

```
let f =

s=>`    o O Oa   ___
   o     a  | $& |
  TS__[O]a  |___|
 {======|a_|"""""|
./o--000'a"\`-0-0-'`.replace(/a(.*)/g,(_,c)=>s.replace(/./g,c))

O.innerHTML = f("CODE GOLF")
```

```
<input value="CODE GOLF" oninput="O.innerHTML=f(this.value.replace(/\n/g,'<br>'))"><br>
<pre id=O></pre>
```

# Answer
> 6 votes
# PHP, ~~218 211 204 187~~ 183 bytes

```
    o O O<?for(;$y<5;print"\n".["   o     ","  TS__[O]"," {======|","./o--000'"][+$y++])for($p=0;$c=a&$argn[$p++];)echo["   ___  ","  | $c | ","  |___| ",'_|"""""|',"\"`-0-0-'"][+$y];

```

Takes input from STDIN; run with `-nR`.

Compressing the engine or wagon would require more code to decompress than it saves on storage.
I see no more potential here.

# Answer
> 6 votes
# Befunge, ~~276~~ 270 bytes

p1p~:7>7+#:`#~_$:v
>#p0p10:p00:+1g00_v#:
v"!!```!!!"v>0p01g\-0g1+53p
v"!}!#!}!!"v0 p115<
v"!}```}!!"v^:-1<
v"}#####}`">00g:|
>"(.1.1.a#"^+<v1<
v"P!P!p!!! "v5>g00p
v"!!!!!p!!!"v6
v"^P\``TU!!"vp
v"}>>>>>>|!"v+
>"(111..p0/"v6
v-1:g110">>"<g
>:11p!#v_p011^
#-:#1_@>$$$$>,#

Try it online!

**Explanation**

The car and engine are encoded as two sets of five strings on lines 3 to 12. The character values are off by 1 so as to avoid having to deal with the double quotes which can't be used in a Befunge string.

The code works by building up the full set of characters needed to render the train on the stack. For each line of output, an appropriate car string is first added to the stack, repeated as many times as necessary for the cargo, and then one copy of the appropriate engine string.

After each line has been constructed, a pair of the down arrows to left of the strings is replaced with a right arrow, so the next iteration of the loop follows a different path through the code, using a different pair of strings for the car and engine.

Once all the data has been built up on the stack, there's a final rendering loop which writes out the characters, subtracting 1 each time to account for the initial encoding.

~~As a bonus, the source is designed in the shape of a gun turret, in case the train comes under attack.~~ Golfers destroyed my gun turret.

# Answer
> 4 votes
## Python 2, 176 bytes

```
lambda i:'\n'.join(map(''.join,zip(*[["    o O O","   o     ","  TS__[O]"," {======|","./o--000'"]]+[["   ___  ",'  | '+x+' | ',"  |___| ",'_|"""""|',"\"`-0-0-'"]for x in i])))

```

Example:

```
print f('Python')

```

gives

```
    o O O   ___     ___     ___     ___     ___     ___
   o       | P |   | y |   | t |   | h |   | o |   | n |
  TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|
 {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

```

# Answer
> 4 votes
## Powershell, ~~167~~ 166 Bytes

```
$l=($a=$args[0]).Length;"    o O O"+"   ___  "*$l;"   o     "+($a[0..$l]|%{"  | $_ |"});"  TS__[O]"+"  |___| "*$l;" {======|"+'_|"""""|'*$l;"./o--000'"+'"`-0-0-'''*$l

```

Example:

```
.\train.ps1 "PowerShell!"
    o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___
   o       | P |   | o |   | w |   | e |   | r |   | S |   | h |   | e |   | l |   | l |   | ! |
  TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
 {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

```

Possibly Invalid! If run with no args at all it will try and print one empty string, and look like:

```
    o O O
   o       |  |
  TS__[O]
 {======|
./o--000'

```

If run with an empty input string it will return correctly however:

```
.\train.ps1 ""
    o O O
   o
  TS__[O]
 {======|
./o--000'

```

(kinda) Ungolfed:

```
$l=($a=$args[0]).Length
"    o O O"+"   ___  "*$l
"   o     "+($a[0..$l]|%{"  | $_ |"})
"  TS__[O]"+"  |___| "*$l
" {======|"+'_|"""""|'*$l
"./o--000'"+'"`-0-0-'''*$l

```

shortest compression in Powershell is going to be `+'c'*x` where c is the char and x is the number of repetitions, and that's only for trailing or leading repetitions, any center-string repetitions will require an extra `+` and an extra `"` \- so there's no point in this where I can see compression saving any space, and the only repeated char set is `___` which is only 3 chars.

Explanation:

`$l=($a=$args[0]).Length` Take the first arg, put it into $a, then take the length of $a and put it into $l, these are the only variables you need.

`" o O O"+" ___ "*$l` most of the other bits follow this format of the left-part and then the right part times the number of required chars.

`" o "+([char[]]$a|%{" | $_ |"})` loop (`|%{}`) through $a as a char array, so `foreach (char $_ in $a)` for a non-pipeline version, then put the char into the text.

this is an extremely simple approach, but because I can't find a good way to compress the strings past this it seems like the most useful.

saved 1 Byte thanks to briantist! and here I was thinking this wouldn't get any shorter..

# Answer
> 2 votes
# Java, 361 bytes

```
class C {static void main(String[]v){Scanner q = new Scanner(System.in);String i = q.nextLine();String[] t = {"    o O O   ", "   o       ", "  TS__[O]  ", " {======|", "./o--000'",};for (char c: i.toCharArray()) {t[0]+="___     ";t[1]+="| # |   ".replace('#',c);t[2]+="|___|   ";t[3]+="_|\"\"\"\"\"|";t[4]+="\"`-0-0-'";}for(String p:t) System.out.println(p);}}

```

```
class C {
    static void main(String[]v)  {
        Scanner q = new Scanner(System.in);
        String i = q.nextLine();
        String[] t = {
                "    o O O   ",
                "   o       ",
                "  TS__[O]  ",
                " {======|",
                "./o--000'",
        };
        for (char c: i.toCharArray()) {
            t[0]+="___     ";
            t[1]+="| # |   ".replace('#',c);
            t[2]+="|___|   ";
            t[3]+="_|\"\"\"\"\"|";
            t[4]+="\"`-0-0-'";
        }
        for(String p:t)
            System.out.println(p);

    }
}

```

Example

```
java
    o O O   ___     ___     ___     ___
   o       | j |   | a |   | v |   | a |
  TS__[O]  |___|   |___|   |___|   |___|
 {======|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

```

# Answer
> 2 votes
## Perl, 137 bytes

132 bytes of code + 5 bytes for`-pF` flags.

`ascii_train.pl`:

```
#!/usr/bin/perl -apF
s/./  | $& | /g;$_="    o O O!   ___
   o     $_
  TS__[0]!  |___|
 {======|!".'_|"""""|'."
./o--000'!\"`-0-0-'";s/!(.*)/$1x@F/ge

```

*Note that I added `-a` flag in the code, but it's only because old versions of Perl require `-a` when `-F` is used.*

To run it:

```
echo -n "code-golf" | perl ascii_train.pl

```

The input must be supplied without a final newline (with `echo -n` for instance).

**Explanations:**
From what I've seen, it's roughly the same idea as ETHProduction's JavaScript answer.
There isn't a lot going on: sadly the patterns are a bit to short to make `x` operator worth being used.
First, `s/./ | $& | /g` surrounds each character of the input with `|` (and spaces) to form the second level of the train.
Then inside that long string, everything between a `!` and a newline is a pattern we wish to repeat to construct the cars. That repetition is done thanks to the regex `s/!(.*)/$1x@F/ge`. (I used `!` because the input can't contain it).

# Answer
> 2 votes
# SOGL V0.12, ~~57~~ 56 bytes

```
Τ¡ā↓mΛC┌─⁵℮Ƨ⅛□→(š;∞⅟¹°⅔Ζ‽ζ÷⁴‘9n,{"s=Ο!NθæιžGš‼t╬¼Xg`‘8n┼

```

Try it Here!

Explanation:

```
..‘             push a compressed string of the locomotive in a single line
   9n           split in line lengths of 9
     ,{         for each character in the input
       "..‘       push a compressed string of a wagon in a single line
           8n     split to line lengths of 8
             ┼    add horizontally

```

# Answer
> 1 votes
# C#, 277 Bytes

Golfed:

```
string T(string s){var o=new string[]{"     o O O","   o        ","   TS__[O]","  {======|","./ o--000'" };for(int i=0;i<s.Length;i++){o[0]+="   ___  ";o[1]+="| # |   ".Replace("#",s[i]+"");o[2]+="  |___| ";o[3]+="_|\"\"\"\"\"|";o[4]+="\"`-0-0-'";}return string.Join("\r\n",o);

```

Ungolfed:

```
public string T(string s)
{
  var o = new string[] { "     o O O", "   o        ", "   TS__[O]",
    "  {======|", "./ o--000'" };

  for (int i = 0; i < s.Length; i++)
  {
    o[0] += "   ___  ";
    o[1] += "| # |   ".Replace("#", s[i] + "");
    o[2] += "  |___| ";
    o[3] += "_|\"\"\"\"\"|";
    o[4] += "\"`-0-0-'";
  }

  return string.Join("\r\n", o);
}

```

Testing:

```
Console.Write(new AllAboardTheASCIITrain().T(""));

     o O O
   o
   TS__[O]
  {======|
./ o--000'

```

And...

```
Console.Write(new AllAboardTheASCIITrain().T("Programming Puzzles & Code Golf"));

     o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___
   o        | P |   | r |   | o |   | g |   | r |   | a |   | m |   | m |   | i |   | n |   | g |   |   |   | P |   | u |   | z |   | z |   | l |   | e |   | s |   |   |   | & |   |   |   | C |   | o |   | d |   | e |   |   |   | G |   | o |   | l |   | f |
   TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
  {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./ o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

```

# Answer
> 1 votes
## C# 221 bytes

nothing special happening here.. just creating each line and join them with new lines.

```
s=>{var t=new[]{"    o O O","   o     ","  TS__[O]"," {======|","./o--000'"};foreach(var c in s){t[0]+="   ___  ";t[1]+=$"  | {c} | ";t[2]+="  |___| ";t[3]+="_|\"\"\"\"\"|";t[4]+="\"`-0-0-'";}return string.Join("\n",t);};

```

# Answer
> 1 votes
# C (clang), ~~217~~ ~~212~~ ~~208~~ 193 bytes

```
f(*t){for(char*p,d[]="    o O O   o       TS__[O] {======|./o--000'   ___    | C |   |___| _|\"\"\"\"\"|\"`-0-0-'",i=0;i<5;i+=puts(""))for(write(1,d+i*9,9),p=t;d[57]=*p++;)write(1,d+45+i*8,8);}

```

-4 bytes thanks to ceilingcat!!

Try it online!

# Answer
> 1 votes
# Jq 1.5, 178 bytes

```
[["    o O O   o       TS__[O] {======|./o--000'"|_nwise(9)]]+[range(length)as$i|[.[$i:$i+1]|"   ___    | \(.) |   |___| _|\"\"\"\"\"|\"`-0-0-'"|_nwise(8)]]|transpose|map(add)[]

```

Expanded

```
# engine
def E:"    o O O   o       TS__[O] {======|./o--000'"|_nwise(9);

# car (note string interpolation)
def C:"   ___    | \(.) |   |___| _|\"\"\"\"\"|\"`-0-0-'"|_nwise(8);

  # generate train
  [[E]] + [range(length) as $i| [.[$i:$i+1] |C]]

  # combine rows and concatenate strings
| transpose | map(add)[]

```

Sample run

```
$ jq -MRr train.jq <<< "golf"
    o O O   ___     ___     ___     ___
   o       | g |   | o |   | l |   | f |
  TS__[O]  |___|   |___|   |___|   |___|
 {======|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

$ wc -c < train.jq
  178

```

Try it online

# Answer
> 0 votes
# Excel VBA, 218 Bytes

Anonymous VBE immediate window function that takes input from range `[A1]` and outputs to the VBE immediate window

```
[B1]=[Len(A1)]:?"    o O O"[Rept("   ___  ",B1)]:?"   o     ";:For i=1To[B1]:?"  | "Mid([A1],i,1)" | ";:Next:?:?"  TS__[O]"[Rept("  |___| ",B1)]:?" {======|"[Rept("_|""""""""""|",B1)]:?"./o--000'"[Rept("""`-0-0-'",B1)]

```

## Formatted for readability

```
[B1]=[Len(A1)]
?"    o O O"[Rept("   ___  ",B1)]
?"   o     ";:For i=1To[B1]:?"  | "Mid([A1],i,1)" | ";:Next:?:
?"  TS__[O]"[Rept("  |___| ",B1)]:
?" {======|"[Rept("_|""""""""""|",B1)]:
?"./o--000'"[Rept("""`-0-0-'",B1)]

```

## Sample Output

```
    o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___
   o       | V |   | B |   | A |   |   |   | E |   | x |   | p |   | r |   | e |   | s |   | s |
  TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
 {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

```

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


title: Write a Playfair encryption program

text:
# Question
Title: Write a Playfair encryption program
Write a program that takes two lines of input and uses the first as a key phrase to encrypt the second according to the Playfair encryption technique.

Wikipedia describes Playfair encryption in some detail, but to avoid any ambiguity, here's a brief summary:

**1. Generate a key table:**

Replace all occurrences of `J` in the key phrase with `I`, then strip all non-alphabet characters and repeated characters. Insert into a 5×5 encryption table, filling the remaining cells with the rest of the alphabet (except `J`; we don't like `J`).

Example:

```
                                        S T A C K
                                        O V E R F
Stack Overflow  -->  STACKOVERFLW  -->  L W B D G
                                        H I M N P
                                        Q U X Y Z

```

**2. Prepare the message to be encrypted**

Replace every `J` with an `I`, strip all non-alphabet characters and split into pairs, using an `X` to break any pairs that contain the same letter twice. If you end up with an odd number of letters, add `X` at the end. (Note: Numerals have to be spelt out in full — `ONE`, `TWO`, `THREE`, etc. — but you can assume this has already been done for you.)

Example:

```
In:
The cat crept into the crypt, crapped, and crept out again.

Out:
TH EC AT CR EP TI NT OT HE CR YP TC RA PX PE DA ND CR EP TO UT AG AI NX

```

**3. Encryption**

Encrypt each pair of letters in turn. If they are in different rows and columns of the key table, replace each with the letter from the same row in the column where the other letter is found (e.g., `VM``EI`, `LZ``GQ`). If they are in the same row (or column), choose the two characters immediately to the right (or below), wrapping around if necessary (e.g., `OE``VR`, `ZG``KP`).

Example:

```
In:
TH EC AT CR EP TI NT OT HE CR YP TC RA PX PE DA ND CR EP TO UT AG AI NX

Out:
SI RA CA RD FM VU IC VS MO RD ZN AK EC MZ MF BC YN RD FM SV TV KB TM MY

```

The string produced by this process is the encrypted message, which your program should output.

# Rules:

* The input text and key may be obtained from `stdin`, command line arguments or other such sources. Hard-coded input is not allowed.
* Your program must accept both upper and lower case text for the pass phrase and message.
* The encrypted output may be upper or lower case.
* Your program should accept key phrases of at least 64 characters in length, and message texts of at least 16 KB.
* You are not required to handle non-ASCII input.
* You may ignore the possibility of the letter pair `XX` occurring during encryption.
* There is no need to add whitespace to the output of the program.
* Your answer should include an example of a message, key phrase and encrypted output produced by your program.
* **This is a code golf challenge, so the answer with the shortest code (in bytes) will win.**

---

> **NOTE:** Please remember that you only need to break consecutive letters if they appear **in the same pair**. So for example `MASSACHUSETTS` should be encrypted as `MA SX SA CH US ET TS` — the double `S` has to be split, but the double `T` doesn't.

# Answer
## ~~J~~ I\*, ~~536~~ ~~431~~ ~~417~~ ~~380~~ ~~263~~ ~~218~~ ~~203~~ ~~197~~ ~~186~~ 167

```
p=:4 :0
a=.u:65+9-.~i.26
,_2(5|,:~@|.@(=/)+$$,A.~5*1-0{=/)&.(5 5#:(~.n x,a)&i.)\(,'X'#~2|#)(({.,'X',}.)~1+2*1{&I._2{.\2=/\]) ::]^:_(n=:a(e.~#])'JI'charsub toupper)y
)

```

(with extensive suggestions from @algorithmshark)

example use:

```
   'Stack Overflow' p 'The cat crept into the crypt, crapped, and crept out again.'
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

```

splits input correctly:

```
   d=:(({.,'X',}.)~1+2*1{&I._2{.\2=/\]) ::]
   d^:_ 'MASSACHUSETTS'
MASXSACHUSETTS

```

---

*replace every `J` with an `I`, right?
> 12 votes

# Answer
## Ruby, ~~461~~ ~~411~~ ~~366~~ ~~359~~ ~~352~~ ~~346~~ 330 characters

```
k,m=$<.map{|x|x.tr(?j,?i).upcase.tr('^A-Z','').chars}
t=[*((k&k)|[*?A..?Z]-[?J]).each_slice(5)]
m=(m*'').gsub(/(.)\1/,'\1X\1').chars
c=->n{[t.index{|r|k=r.index n},k]}
$><<(m.size%2<1?m:m+[?X]).each_slice(2).map{|p,q|a,b,d,e=*c[p],*c[q]
a==d ?[t[a][(b+1)%5],t[d][(e+1)%5]]:b==e ?[t[(a+1)%5][b],t[(d+1)%5][e]]:[t[a][e],t[d][b]]}*''

```

Thanks to @daniero for saving... err, a *lot* of bytes. \o/

Here's the ungolfed code:

```
key = gets.chomp
msg = gets.chomp
transform = ->str{
    str.gsub! 'j', 'i'
    str.upcase!
    str.gsub! /[^A-Z]/, ''
    str.split('')
}

# 1. Generate a key table
key = transform[key]
chars = key.uniq + ([*?A..?Z] - key - ['J'])
tbl = Array.new(5) {
    Array.new(5) {
        chars.shift
    }
}

# 2. Prepare the message
msg = transform[msg]
msg = msg.join('').gsub(/(.)\1/){ "#{$1}X#{$1}" }.split('')
msg = (msg.length % 2 == 0 ? msg : msg + ['X']).each_slice(2).to_a

# 3. Encryption
coords = ->chr{
    i = -1
    [tbl.index{|row| i = row.index chr}, i]
}
msg.map! do |c1, c2|
    c1, c2 = coords[c1], coords[c2]
    if c1[0] == c2[0]
        # same row
        [tbl[c1[0]][(c1[1] + 1) % 5], tbl[c2[0]][(c2[1] + 1) % 5]]
    elsif c1[1] == c2[1]
        # same column
        [tbl[(c1[0] + 1) % 5][c1[1]], tbl[(c2[0] + 1) % 5][c2[1]]]
    else
        # neither
        [tbl[c1[0]][c2[1]], tbl[c2[0]][c1[1]]]
    end
end

# Output!
puts msg.join

```

Here's some sample outputs:

```
llama@llama:...code/ruby/ppcg23276playfair$ printf 'Stack Overflow\nThe cat crept into the crypt, crapped, and crept out again.\n' | ./playfair.rb; printf 'This is a password!\nProgramming Puzzles and Code Golf is a Stack Exchange site.\n' | ./playfair.rb
SIRAVXRDFMVUUYVSBLRDZNYVECMZMFBCYNRDFMSVTVKBVBMY
WDDEDSXIXOQFBTUYVQFISQWGRPFBWMESATAHHGMBVEITQFFISHMI

```
> 7 votes

# Answer
# C: ~~495~~ ~~401~~ ~~355~~ 341 characters

~~It's just a rough sketch as of now. I should be able to shave off at least a hundred characters.~~

Goal accomplished: more than a hundred characters (154 as of now) have mysteriously vanished from the code.

```
p[25],l[96],a=1,b,c;o(x,y){putchar(p[x%5^y%5?x/5*5+(x/5^y/5?y:x+1)%5:(x+5)%25]);}main(){for(;a&&((a=(b=getchar())>31)||(b=65))||b++<90;c=0)for(b&=-33;b/65-b/91&&p[c]^b-(b==74);p[c++]||(p[--c]=b-(b==74),l[b]=c));for(;b=getchar(),b=b>31?b&-33:(c=88),b=b/65-b/91?a?a^b?(c*=c==88,b):(c=b,88):(a=b,0):0,a&b&&(o(a=l[a],b=l[b]),o(b,a),a=c),c^88;);}

```

With some pleasant whitespace:

```
p[25],l[96],a=1,b,c;
o(x,y){
    putchar(p[
        x%5^y%5
            ?x/5*5+(x/5^y/5?y:x+1)%5
            :(x+5)%25
    ]);
}
main(){
    for(;
        a&&(
            (a=(b=getchar())>31)||
            (b=65)
        )||b++<90;
        c=0
    )for(
        b&=-33;
        b/65-b/91&&
        p[c]^b-(b==74);
        p[c++]||(
            p[--c]=b-(b==74),
            l[b]=c
        )
    );
    for(;
        b=getchar(),
        b=b>31
            ?b&-33
            :(c=88),
        b=b/65-b/91
            ?a
                ?a^b
                    ?(c*=c==88,b)
                    :(c=b,88)
                :(a=b,0)
            :0,
        a&b&&(
            o(a=l[a],b=l[b]),
            o(b,a),
            a=c
        ),
        c^88;
    );
}

```

I wrote the first iteration of the program on the verge of falling asleep, so it had a lot of superfluous meaningless statements and such. Most of that is rectified, but there are quite a few areas where improvement is most definitely possible.
> 4 votes

# Answer
# Haskell - 711

Demo:

```
[timwolla@/data/workspace/haskell/PCG]ghc pcg-23276.hs
[1 of 1] Compiling Main             ( pcg-23276.hs, pcg-23276.o )
Linking pcg-23276 ...
[timwolla@/data/workspace/haskell/PCG]./pcg-23276 "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

```

Code:

```
import Data.List
import Data.Char
import Data.Maybe
import System.Environment
main=do a<-getArgs
    putStrLn$concat$map(x (a!!0))$map(\x->if (length x)==1 then x++"X"else x)$s 2$concat$map(\x->if (length x)==1then x else intersperse 'X' x)$group$p (a!!1)
p=map(\x->if x=='J' then 'I' else x).filter(isUpper).map toUpper
k x=y++(delete 'J'$['A'..'Z']\\y)where y=nub$p x
u l m=(div i 5,mod i 5)where i=fromJust$elemIndex l$k m
x y z
    |a/=c&&b/=d=(e!!(a*5+d)):(e!!(c*5+b)):[]
    |a==c=(e!!(a*5+(mod(b+1)5))):(e!!(c*5+(mod(d+1)5))):[]
    |True=(e!!((5*(mod(a+1)5))+b)):(e!!((5*(mod(c+1)5))+d)):[]
    where
        o=u(z!!0)y
        t=u(z!!1)y
        a=fst o
        b=snd o
        c=fst t
        d=snd t
        e=k y
s _ []=[]
s n l=(take n l):(s n(drop n l))

```

Large version:

```
import Data.List
import Data.Char
import Data.Maybe

encryptAll key text = map (encrypt key) (transformValue text)

clean x = map (\x -> if x == 'J' then 'I' else x) $ filter (isUpper) $ map (toUpper) x
transformKey x = y ++ (delete 'J' $ ['A'..'Z'] \\ y)
    where y = nub (clean x)

transformValue x = map (\x -> if (length x) == 1 then x ++ "X" else x) $ split 2 $ concat $ map (\x -> if (length x) == 1 then x else intersperse 'X' x) $ group $ clean x

search letter key = (div index 5, mod index 5)
    where index = fromJust $ elemIndex letter $ transformKey key

encrypt key chars
    | rowA /= rowB && colA /= colB = (key' !! (rowA * 5 + colB)) : (key' !! (rowB * 5 + colA)) : []
    | rowA == rowB = (key' !! (rowA * 5 + ((colA + 1) `mod` 5))) : (key' !! (rowB * 5 + ((colB + 1) `mod` 5))) : []
    | otherwise = (key' !! ((5 * ((rowA + 1) `mod` 5)) + colA)) : (key' !! ((5 * ((rowB + 1) `mod` 5)) + colB)) : []
    where
        rowA = fst $ search (head chars) key
        colA = snd $ search (head chars) key
        rowB = fst $ search (last chars) key
        colB = snd $ search (last chars) key
        key' = transformKey key

-- http://stackoverflow.com/a/12876438/782822
split :: Int -> [a] -> [[a]]
split _ [] = []
split n l
  | n > 0 = (take n l) : (split n (drop n l))
  | otherwise = error "Negative n"

```
> 2 votes

# Answer
# Matlab - 458 chars

```
function p=pf(k,p)
k=[upper(k),65:90];k(k==74)=73;k(k<65|k>90)='';[~,i]=unique(k,'first');k=reshape(k(sort(i)),5,5);e=[k,k(:,1);k(1,:)];p=upper(p);p(p==74)=73;p(p<65|p>90)='';n=length(p);for i=1:2:n
if i<n&&p(i)==p(i+1)p=[p(1:i),88,p(i+1:end)];end
n=length(p);end
if mod(n,2)p=[p,88];n=n+1;end
for i=1:2:n [x,y]=find(k==p(i));[w,z]=find(k==p(i+1));p(i:i+1)=[k(w,y),k(x,z)];if x==w p(i:i+1)=[e(w,y+1),e(x,z+1)];end
if y==z p(i:i+1)=[e(x+1,z),e(w+1,y)];end
end

```

Some examples:

```
octave:180> pf('Stack Overflow', 'The cat crept into the crypt, crapped, and crept out again.')
ans = SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

octave:181> pf('This is a password!','Programming Puzzles and Code Golf is a Stack Exchange site.')
ans = WDDEDSXIXOQFBTUYVQFISQWGRPFBWMESATAHHGMBVEITQFFISHMI

octave:182> pf('Matlab needs lambdas', 'Who thought elseif is good syntax?')
ans = XGQMFQPKQDSACDKGRIFPQNILDMTW

```
> 2 votes

# Answer
# Pyth - 111

Too late for competing, I just wanted to share. Here's the encoder and decoder

```
L@G:rb0\j\iJ{y+wGKywWhZ=Zh*2xlR{RcK2 1IhZ=KXZK\x;M@J+G?!eH5?!hH?q4%G5_4 1eHVcK2A,xJhNxJeN=Z-V.DH5.DG5pgGZpgH_RZ

```

**Explanation:**

```
L    b                              L defines common method y(b); 2 calls helps us saving two bytes
    r 0                             lowercase r(b,0)
   :   \j\i                         : replaces all occurrences of "j" with "i"
 @G                                 strips all non-alphabetic characters; G = pyth built-in alphabet

    w                               first input argument
   + G                              appends the alphabet (G)
  y                                 calls y(b)
 {                                  { makes set (removes duplicated characters)
J                                   assigns result to 'J' (KEY VARIABLE)

Kyw                                 assigns output from y(second input argument) to 'K' (TEXT VARIABLE)

WhZ                         ;       While (Z+1 != 0) <-> While (Z != -1) <-> While mismatched items found
             cK2                    list of K pairs.                    e.g. 'ABCCDDE' -> [AB, CC, DD, E]
         lR{R                       l length of { unique characters.    e.g. [2, 1, 1, 1]
        x       1                   1-length first index.               e.g. 1
     h*2                            *2+1 (Index in K)                   e.g. 3 'ABC CDDE'
   =Z                               Assigns to 'Z'
                  IhZ               if (Z != -1) <-> if (mismatched found)
                     =KXZK\x        X Inserts at Z index in K an 'x' and reassigns to 'K'  e.g. 'ABCXC...'

M                                   M defines function g(G, H) where G index H vector (INDEX CONVERSION)
     ?!eH                           if (same col)
         5                              then +5
         ?!hH                           else { if (same row)
             ?q4%G5                             then if (last col)
                   _4                               then -4
                      1                             else +1
                       eH                       else col
   +G                               index += increment
 @J                                 J[index]

VcK2                                V loops over cK2 list of K pairs
     ,xJhNxJeN                      x returns pair members index in J
    A                               A assigns G = xJhN, H = xJeN
                  .DH5              .D returns [row, col] = [i/5,i%5] of 5xn matrix from index of H
                      .DG5          idem. of G
                -V                  Subtracts vectors (RELATIVE POSITION)
              =Z                    Assigns to 'Z'
                          pgGZ          p prints g(G, Z) return value
                              pgH_RZ    p prints g(H, _RZ) return value, and _R changes signs of Z vector

```

**Sample Key/Message/Output:**

```
Stack Overflow
Gottfried Leibniz is famous for his slogan Calculemus, which means Let us calculate. He envisioned a formal language to reduce reasoning to calculation.
lfaukvvnrbbomwpmupkoexvqkovfimaqohflcmkcdsqwbxqtlintinbehcbovttksbtybsavmormwuthrhrbkevfxebqbspdxtbfsvfrwyarfrctrhmpwkrssbtybsvurh

```
> 2 votes

# Answer
# C, 516

Linefeeds added for improved ~~legibility~~ presentation. (Legibility went out the window, I'm afraid.)

```
#define Z(u,v) putchar(o[u]),putchar(o[v])
#define X while((Y=getchar())>31){Y&=223;if(Y==74)Y--;if(Y<65||Y>90
P,L,A,Y,f,a,i,r,c=512,o[25],d[2],*e=o;Q(){for(i=0;o[i]!=d[0];i++);i-=(f=i%5);
for(r=0;o[r]!=d[1];r++);r-=(a=r%5);if(f==a)Z(f+(i+5)%25,a+(r+5)%25);
else if(i==r)Z((f+1)%5+i,(a+1)%5+r);else Z(a+i,f+r);}main(){X||c&(A=1<<Y-65))continue;
c|=A;*e++=Y;}A=1;Y=65;for(P=0;P<25;P++){if(!(c&A))*e++=Y;
if(++Y==74)Y++,A+=A;A+=A;}L=0;X)continue;if(L&&Y==*d)d[1]=88,Q(),*d=Y;
else d[L]=Y,L=1-L;if(!L)Q();}if(L)d[1]=88,Q();}

```

**Example:**

```
$ ./pf
Playfair
The quick brown fox jumps over the lazy dog
QMHNPEKSCBQVTPSVEPEFTQUGDOKGAYXFRTKV

```
> 1 votes

# Answer
# Python 3, ~~709~~ ~~705~~ ~~685~~ 664

Accepts input from stdin.

```
from string import ascii_uppercase as a
from itertools import product as d
import re
n=range
k=input()
p=input()
t=lambda x: x.upper().replace('J','I')
s=[]
for _ in t(k+a):
 if _ not in s and _ in a:
  s.append(_)
m=[s[i:i+5] for i in n(0,len(s),5)]
e={r[i]+r[j]:r[(i+1)%5]+r[(j+1)%5] for r in m for i,j in d(n(5),repeat=2) if i!=j}
e.update({c[i]+c[j]:c[(i+1)%5]+c[(j+1)%5] for c in zip(*m) for i,j in d(n(5),repeat=2) if i!=j})
e.update({m[i1][j1]+m[i2][j2]:m[i1][j2]+m[i2][j1] for i1,j1,i2,j2 in d(n(5),repeat=4) if i1!=i2 and j1!=j2})
l=re.findall(r'(.)(?:(?!\1)(.))?',''.join([_ for _ in t(p) if _ in a]))
print(''.join(e[a+(b if b else 'X')] for a,b in l))

```

Example:

```
mfukar@oxygen[/tmp]<>$ python playfair.py
Stack Overflow
The cat crept into the crypt, crapped, and crept out again.
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

```
> 1 votes

# Answer
# JS (node) - 528 466

```
k=n(2)+'ABCDEFGHIKLMNOPQRSTUVWXYZ',p=n(3),t=o=''
for(i=0;i<k.length;i++)if(!~t.indexOf(k[i]))t+=k[i]
for(i=0;i<p.length;){a=f(c=p[i++]),b=f(!(d=p[i])||c==d?'X':(i++,d))
if(a.x==b.x)a.y=(a.y+1)%5,b.y=(b.y+1)%5
else if(a.y==b.y)a.x=(a.x+1)%5,b.x=(b.x+1)%5
else a.x=b.x+(b.x=a.x,0)
o+=t[a.x+a.y*5]+t[b.x+b.y*5]}console.log(o)
function f(c){x=t.indexOf(c);return{x:x%5,y:x/5|0}}
function n(a){return process.argv[a].toUpperCase().replace(/[^A-Z]/g,'').replace(/J/g,'I')}

```

Sample output:

```
$ node playfair "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY
$ node playfair "Lorem ipsum" "dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
CRORSDAHGAMQKPXDOFQMQAMSBSSPUPBPTDMOAHURNRCRLUAULRGNMLCPLSKDSBSBSQQAHMIGRERYMQCROREMAGDTSZIMUHAIAQRQALSGLAHSLZRQPIETAPDXRPNMSFRYMEBPZGHARKIEMIOGROIGREPUHSUPAQIMUHAPUOYRPGRLLRCRKPXDUYAINZ

```
> 1 votes

# Answer
## Python: 591 bytes

```
import sys
l=list
n=len
a=[sys.stdin.readline().upper().replace('J','I') for i in (1,2)]
b=l('ABCDEFGHIKLMNOPQRSTUVWXYZ')
def z(x):
    a=0
    if x in b:
        b.remove(x)
        a=1
    return a
c=l(filter(z,a[0]))+b
d=[x for x in a[1] if x in c]
e=1
while e<n(d):
    if d[e-1]==d[e]:
        d.insert(e,'X')
    e+=2
if n(d)%2>0:
    d+='X'
def y(i):
    z=c.index(d[i])
    return z/5,z%5
x=lambda i,j:c[(i%5)*5+(j%5)]
def w(i):
    e,f=y(i)
    g,h=y(i+1)
    if e==g:
        z=x(e,f+1)+x(g,h+1)
    elif f==h:
        z=x(e+1,f)+x(g+1,h)
    else:
        z=x(e,h)+x(g,f)
    print z,
e=0
while e<n(d):
    w(e)
    e+=2
print

```

This uses `stdin` to get the key and the message in that order. I hope it's not cheating to use a flat list to store the encryption matrix, because that made working with the matrix pretty simple. Here are some example runs:

```
>python playfair.py
Stack Overflow
The cat crept into the crypt, crapped, and crept out again.
SI RA CA RD FM VU IC VS MO RD ZN AK EC MZ MF BC YN RD FM SV TV KB TM MY

>python playfair.py
Stack Overflow
The quick red fox jumps over the lazy brown dog.
SI OX TU KS FR GR EQ UT NH OL ER VC MO BS QZ DE VL YN FL

```
> 1 votes

# Answer
## Java - 791

My first golf, so any criticism is welcome. Using Java because I shouldn't. It doesn't seem so bad; less than double the size of the current leader. I was expecting it to be bigger since it's, well, *Java* :)

```
public class P{static String c(String s){return s.toUpperCase().replace('J','I').replaceAll("[^A-Z]","");}static int f(char[]a, char n){for(int i=0;i<a.length;i++)if(a[i]==n)return i;return -1;}public static void main(String[]a){int i=0,k,l;char j=0;String g=c(a[0]);char[]e,b,h=c(a[1]).toCharArray();b=new char[25];for(;j<g.length();j++)if(j==g.indexOf(g.charAt(j)))b[i++]=g.charAt(j);for(j=65;i<25;j++)if(f(b,j)<0&&j!=74)b[i++]=j;e=new char[h.length*2];for(i=0,j=0;j<h.length;){if(i%2>0&&h[j]==h[j-1])e[i++]=88;e[i++]=h[j++];}if(i%2>0)e[i++]=88;for(j=0;j<i;j+=2){k=f(b,e[j]);l=f(b,e[j+1]);if(k/5==l/5){e[j]=b[(k/5*5)+((k+1)%5)];e[j+1]=b[(l/5*5)+((l+1)%5)];}else if(k%5==l%5){e[j]=b[(k+5)%25];e[j+1]=b[(l+5)%25];}else{e[j]=b[(k/5*5)+(l%5)];e[j+1]=b[(l/5*5)+(k%5)];}}System.out.println(e);}}

```

With auto-format:

```
public class P {
    static String c(String s) {
        return s.toUpperCase().replace('J', 'I').replaceAll("[^A-Z]", "");
    }

    static int f(char[] a, char n) {
        for (int i = 0; i < a.length; i++)
            if (a[i] == n)
                return i;
        return -1;
    }

    public static void main(String[] a) {
        int i = 0, k, l;
        char j = 0;
        String g = c(a[0]);
        char[] e, b, h = c(a[1]).toCharArray();
        b = new char[25];
        for (; j < g.length(); j++)
            if (j == g.indexOf(g.charAt(j)))
                b[i++] = g.charAt(j);
        for (j = 65; i < 25; j++)
            if (f(b, j) < 0 && j != 74)
                b[i++] = j;
        e = new char[h.length * 2];
        for (i = 0, j = 0; j < h.length;) {
            if (i % 2 > 0 && h[j] == h[j - 1])
                e[i++] = 88;
            e[i++] = h[j++];
        }
        if (i % 2 > 0)
            e[i++] = 88;
        for (j = 0; j < i; j += 2) {
            k = f(b, e[j]);
            l = f(b, e[j + 1]);
            if (k / 5 == l / 5) {
                e[j] = b[(k / 5 * 5) + ((k + 1) % 5)];
                e[j + 1] = b[(l / 5 * 5) + ((l + 1) % 5)];
            } else if (k % 5 == l % 5) {
                e[j] = b[(k + 5) % 25];
                e[j + 1] = b[(l + 5) % 25];
            } else {
                e[j] = b[(k / 5 * 5) + (l % 5)];
                e[j + 1] = b[(l / 5 * 5) + (k % 5)];
            }
        }
        System.out.println(e);
    }
}

```

Sample output:

```
>java P "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

>java P "Write a PlayFair encryption program" "Write a program that takes two lines of input and uses the first as a key phrase to encrypt the second according to the Playfair encryption technique."
RITEWFCPGMWPGEBLYTWYQTXWINOLMWVNLECAXRNBURZWXWQILEWUWYWNQTFLDINWWEMICOTPYRIKWZRMGCBPGUOGPUWOKYGIQILYPFAPTIWMDPFLETGCEWODOWDZTZ

```
> 1 votes

# Answer
# PHP 582

```
<? list($i,$k,$v)=array_map(function($v){return str_split(preg_replace('#[^A-Z]#','',strtr(strtoupper($v),'J','I')));},$argv);@$i=array_flip;$k=$i($k)+$i(range('A','Z'));unset($k['J']);$k=array_keys($k);$q=$i($k);for($i=1;$i<count($v);$i+=2){if ($v[$i-1]==$v[$i]){array_splice($v,$i,0,'X');}}if(count($v)%2)$v[]='X';for($i=1;$i<count($v);$i+=2){$c=(int)($q[$v[$i-1]]/5);$d=$q[$v[$i-1]]%5;$e=(int)($q[$v[$i]]/5);$f=$q[$v[$i]]%5;if($c==$e){$d=($d+1)%5;$f=($f+1)%5;}elseif($d==$f){$c=($c+1)%5;$e=($e+1)%5;}else{$t=$f;$f=$d;$d=$t;}$v[$i-1]=$k[$c*5+$d];$v[$i]=$k[$e*5+$f];}echo join($v);

```

Ungolfed
Decoder

outputs

```
$ php playfair.php "Stack Overflow" "The cat crept into the crypt, crapper, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFECYNRDFMSVTVKBTMMY
$ php playfair.php "This was codegolf?" "The full J answers is shorter than my preparation code :("
HIOKVGFHCMWTKZWSIYWIEPWAMWTCPNXQZKMOMEHSCPODEA

```
> 1 votes

# Answer
## Perl, 265

Very straightforward.

```
chomp(($k,$_)=map{uc=~y/A-Z//cdr=~y/J/I/r}<>."@{[A..Z]}",~~<>);1while$k=~s/((.).*)\2/$1/;while(/(.)((?=\1|$)|(.))/g){($a,$b,$c,$d)=map{$e=index$k,$_;5*int$e/5,$e%5}$1,$3||X;print substr$k,$_%25,1 for$a-$c?$b-$d?($a+$d,$c+$b):($a+5+$b,$c+5+$d):(++$b%5+$a,++$d%5+$c)}

```

Indented:

```
chomp(($k,$_)=map{uc=~y/A-Z//cdr=~y/J/I/r}<>."@{[A..Z]}",~~<>);
1while$k=~s/((.).*)\2/$1/;
while(/(.)((?=\1|$)|(.))/g){
    ($a,$b,$c,$d)=map{$e=index$k,$_;5*int$e/5,$e%5}$1,$3||X;
    print substr$k,$_%25,1 for
        $a-$c
            ?$b-$d
                ?($a+$d,$c+$b)
                :($a+5+$b,$c+5+$d)
            :(++$b%5+$a,++$d%5+$c)
}

```
> 1 votes

# Answer
# CoffeeScript - 610

Demo:

```
[timwolla@/data/workspace/js/PCG]coffee pcg-23276.coffee "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

```

Code:

```
String::r=String::replace
_=(t,l)->
    for r in[0..4]
        for c in[0..4]
            return [r,c]if l is t[r][c]
K = {}
K[c]=c for c in (process.argv[2].toUpperCase().r(/J/g, 'I').r x=/([^A-Z])/g, '')
for i in[1..26]when i!=10
    c=String.fromCharCode 64+i
    K[c]=c
K=(c for c of K)
t=(K[s..s+4]for s in[0..24]by 5)
v=process.argv[3].toUpperCase().r(/J/g,'I').r(x,'').r(/(.)\1/g,'$1X$1').r /(..)/g, '$1 '
o=""
for p in v.trim().r(/\s([A-Z])$/, ' $1X').split /\s/
    [a,b]=p.split '';[d,f]=_ t,a;[e,g]=_ t,b
    o+=if d!=e&&f!=g
        t[d][g]+t[e][f]
    else if d==e
        t[d][++f%5]+t[e][++g%5]
    else
        t[++d%5][f]+t[++e%5][g]
console.log o

```

Ungolfed version:

```
search = (table, letter) ->
    for row in [0..4]
        for column in [0..4]
            return [ row, column ] if letter is table[row][column]

encrypt = (key, value) ->
    key = key.toUpperCase().replace(/J/g, 'I').replace /([^A-Z])/g, ''
    keyChars = {}
    keyChars[char] = char for char in key
    for i in [1..26] when i != 10
        char=String.fromCharCode 64 + i
        keyChars[char] = char
    keyChars = (char for char of keyChars)

    keyTable = (keyChars[start..start+4] for start in [0..24] by 5)

    value = value.toUpperCase().replace(/J/g, 'I').replace(/([^A-Z])/g, '').replace(/(.)\1/g, '$1X$1').replace /(..)/g, '$1 '
    pairs = value.trim().replace(/\s([A-Z])$/, ' $1X').split /\s/

    out = ""
    for pair in pairs
        [a,b] = pair.split ''
        [rowA, colA] = search keyTable, a
        [rowB, colB] = search keyTable, b
        if rowA!=rowB&&colA!=colB
            out += keyTable[rowA][colB]+keyTable[rowB][colA]
        else if rowA==rowB
            out += keyTable[rowA][++colA%5]+keyTable[rowB][++colB%5]
        else
            out += keyTable[++rowA%5][colA]+keyTable[++rowB%5][colB]
    out.replace /(..)/g, '$1 '

console.log encrypt process.argv[2], process.argv[3]

```
> 0 votes

---
Tags: code-golf, cryptography
---