g | x | w | all
Bytes Lang Time Link
051Vyxal 3250430T085416ZThemooni
162C++250617T215449ZDrParano
095Python250506T083638ZSevC_10
085Plain TeX250505T112830Zjlab
081Python250503T153352ZAlbert.L
087Python250503T060346Zmovatica
nanbrainfuck250501T215401ZLevel Ri
051Wolfram Language Mathematica250430T181052ZGreg Mar
091Python 3250502T022839Zcd_woomy
090JavaScript Node.js250501T012845ZSteve Be
132C250501T021132Zchux
090JavaScript Node.js250430T012233Zl4m2
02705AB1E250430T083355ZKevin Cr
107Python250430T101458ZNicola S
099Python250501T103736ZLucenapo
085cQuents250501T031611ZStephen
076Ruby250501T012836ZLevel Ri
nanprint"\n".join["N"250430T123934Zuser1280
076Retina 0.8.2250501T002513ZNeil
026Jelly250430T213931ZJonathan
064x86_64 Machine Code250430T211511Zdthusian
074Perl 5250430T195346ZXcali
073cmd.exe250430T082422ZJan Blum
029Charcoal250430T085359ZNeil
197C# 12250430T080525Zjuanferr

Vyxal 3, 51 bytes

"ᛞA
_.⧖dᏐ①%g4xT≠a∧⟒Aξƶ▲⅟xZ⎊↯ƓṪ∩tᐕ8⎂⩔⎇j⟒▦½“"WN bES"⊢

-18 bytes by using a better compression technique

Vyxal It Online!

"ᛞA
_.⧖dᏐ①%g4xT≠a∧⟒Aξƶ▲⅟xZ⎊↯ƓṪ∩tᐕ8⎂⩔⎇j⟒▦½“"WN bES"⊢­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁢⁠⁡‏⁠‎⁢⁠⁢‏⁠‎⁢⁠⁣‏⁠‎⁢⁠⁤‏⁠‎⁢⁠⁢⁡‏⁠‎⁢⁠⁢⁢‏⁠‎⁢⁠⁢⁣‏⁠‎⁢⁠⁢⁤‏⁠‎⁢⁠⁣⁡‏⁠‎⁢⁠⁣⁢‏⁠‎⁢⁠⁣⁣‏⁠‎⁢⁠⁣⁤‏⁠‎⁢⁠⁤⁡‏⁠‎⁢⁠⁤⁢‏⁠‎⁢⁠⁤⁣‏⁠‎⁢⁠⁤⁤‏⁠‎⁢⁠⁢⁡⁡‏⁠‎⁢⁠⁢⁡⁢‏⁠‎⁢⁠⁢⁡⁣‏⁠‎⁢⁠⁢⁡⁤‏⁠‎⁢⁠⁢⁢⁡‏⁠‎⁢⁠⁢⁢⁢‏⁠‎⁢⁠⁢⁢⁣‏⁠‎⁢⁠⁢⁢⁤‏⁠‎⁢⁠⁢⁣⁡‏⁠‎⁢⁠⁢⁣⁢‏⁠‎⁢⁠⁢⁣⁣‏⁠‎⁢⁠⁢⁣⁤‏⁠‎⁢⁠⁢⁤⁡‏⁠‎⁢⁠⁢⁤⁢‏⁠‎⁢⁠⁢⁤⁣‏⁠‎⁢⁠⁢⁤⁤‏⁠‎⁢⁠⁣⁡⁡‏⁠‎⁢⁠⁣⁡⁢‏⁠‎⁢⁠⁣⁡⁣‏⁠‎⁢⁠⁣⁡⁤‏⁠‎⁢⁠⁣⁢⁡‏⁠‎⁢⁠⁣⁢⁢‏‏​⁡⁠⁡‌⁢​‎‎⁢⁠⁣⁤⁣‏‏​⁡⁠⁡‌⁣​‎‎⁢⁠⁣⁢⁣‏⁠‎⁢⁠⁣⁢⁤‏⁠‎⁢⁠⁣⁣⁡‏⁠‎⁢⁠⁣⁣⁢‏⁠‎⁢⁠⁣⁣⁣‏⁠‎⁢⁠⁣⁣⁤‏⁠‎⁢⁠⁣⁤⁡‏⁠‎⁢⁠⁣⁤⁢‏‏​⁡⁠⁡‌­

"ᛞA                                              # ‎⁡compressed integer 118527397431132348315259064471309367980399198767544169918914239830184073459407054382133548256390
_.⧖dᏐ①%g4xT≠a∧⟒Aξƶ▲⅟xZ⎊↯ƓṪ∩tᐕ8⎂⩔⎇j⟒▦½“         
                                              ⊢  # ‎⁢converted to base
                                      "WN bES"   # ‎⁣literal string "WN bES"
💎

Created with the help of Luminespire.

<script type="vyxal3">
"ᛞA
_.⧖dᏐ①%g4xT≠a∧⟒Aξƶ▲⅟xZ⎊↯ƓṪ∩tᐕ8⎂⩔⎇j⟒▦½“"WN bES"⊢
</script>
<script>
    args=[]
</script>
<script src="https://themoonisacheese.github.io/snippeterpreter/snippet.js" type="module"/>

C++, 162 bytes

#include<cstdio>
int main(){puts("N NbE NNE NEbN NE NEbE ENE EbN E EbS ESE SEbE SE SEbS SSE SbE S SbW SSW SWbS SW SWbW WSW WbS W WbN WNW NWbW NW NWbN NNW NbW")};

Python, 95 bytes

b='b'
print(*'NESW')
for z in'NE','SE','SW','NW':x,y=z;print(z,z+b+x,z+b+y,x+z,y+z,x+b+y,y+b+x)

Attempt This Online!

Output:

N E S W
NE NEbN NEbE NNE ENE NbE EbN
SE SEbS SEbE SSE ESE SbE EbS
SW SWbS SWbW SSW WSW SbW WbS
NW NWbN NWbW NNW WNW NbW WbN

Plain TeX, 85 bytes

N S E W\def~#1#2{ #1b#2 #1#1#2 #1#2b#1 #1#2 #1#2b#2 #2#1#2 #2b#1}~N E~N W~S E~S W\bye

Example

Python, 81 bytes

*x,=11*" EWEW"
for x[51:51]in"NSSN":print(b'%#{r;r{27#{2sr3r'.hex().translate(x))

Attempt This Online!

Python, 86 bytes

*x,=9*"WE bNSEW"
for j in b"6464":print(b'CbDbF4$bF6&F&4'.hex().translate(x),x.pop(j))

Attempt This Online!

Python, 88 bytes

print(*"NWSE",*[b"CRDRE4$RE5%E%4".hex().translate(26*" b"+x+y)for x in"NS"for y in"EW"])

Attempt This Online!

Python, 91 89 87 bytes

b="NE NNE ENE NbE NEbE EbN NEbN ";b+=b.replace(*"EW");print(*"NESW",b+b.replace(*"NS"))

Attempt This Online!

As the order does not matter, simple replacement is shorter than the string.translate() trick.

brainfuck, 209 bytes (196 without newlines)

->>--->>->>>>->>>>-
[[---<+<+<+>>>]<--<++<+++<]
<+++++[->
>++>--->->++>++>--->>++
>++>>->++>++>>>++[<]<]>
>>---.>>.<.>.<
[.<<.>.>>.
<..<.>>.
<.<.<.>>.>.
<.<.>>.
<.<.<.>.>>.
<<.>.<.>>.
<<.<.>>.>.>>>]
<<<<.>.<<.

Try it online!

Developed at https://minond.xyz/brainfuck/ which doesn't like use of cells with negative index (hence an additional >>>>> would be needed at the start of the program.) TIO.run accepts negative cells so this is not required. Newlines are not essential and are added for clarity.

Commented code

To minimise the use of negative indices, this commented code assumes the pointer starts at cell 4. ! is used to represent newline.

->>--->>->>>>->>>>-          Initialize cells 4;8;12;16 to 255 Subtract 3 from cell 6 (this will help adjust the cell to E)
[[---<+<+<+>>>]<--<++<+++<]  Reduce cell 16 to 0 setting the 3 cells to the left to 255/3=85: modify to ASCII XWS: shift 4 left and repeat until empty cell 0 reached.
<+++++[->                    Set cell -1 to 5 and loop 5 times adjusting cells 1 to 16
>++>--->->++>++>--->>++      Adjust cells 1..8  to bHN!bES!  
>++>>->++>++>>>++[<]<]>      Adjust cells 9..16 to bWN!bWS! (return pointer to -1 at the end of each iteration using the 0 in cell 0)
>>---.>>.<.>.<               Adjust cell 2 from H to E and output E!N!
[.<<.>.>>.                   Loop 4 times outputting NbE!
<..<.>>.                     NNE!
<.<.<.>>.>.                  NEbN!
<.<.>>.                      NE!
<.<.<.>.>>.                  NEbE!
<<.>.<.>>.                   ENE!
<<.<.>>.>.>>>]               EbN! etc; advancing 4 cells each iteration
<<<<.>.<<.                   Output S!W

tinyBF, 281 characters (70.25 bytes when compressed)

+>>=+++=>>+>>>>+>>>>+||+++=>=+=>=+=>=+>>>=|>++>=++=>=+++=>|>+++++=|+>>++>=+++=>=+=>++>++>=+++=>>++>++>>=+=>++>++>>>++|=>|>|=>>>=+++===>>===>===>===>=|===>>===>==>>===>====>===>>===>==>==>===>>==>===>==>===>>===>==>==>===>==>>===>>===>===>===>>===>>==>===>>==>==>>>=|>>>>===>===>>==

Try it online!

A cross-compile of the above answer (the signs of some counters were changed to reduce the length of the TinyBF code.)

TinyBF is an encoding of Brainfuck using only 4 symbols (this allows 4 symbols to fit in a byte.) The encoding is as below:

 Tiny BF   Brianfuck
 =         switch between the symbols below   
 +         + or -      
 >         > or <     
 |         ] or [     
 ==        . (switching twice does nothing, so is used as output symbol)
 |=|       , (Brainfuck infinite loop [] is used as input symbol)    

Wolfram Language (Mathematica), 51 bytes

One hard-earned byte saved thanks to infinitezero!

ResourceFunction["CompassPoint"][29E#,32]&~Array~32

Gotta love a builtin…! This program outputs

{"EbN", "SSE", "SWbW", "NW", "NEbN", "ESE", "SbW", "W", "NbW", "ENE", "SEbS", "SW", "NWbW", "NNE", "EbS", "S", "WbS", "NNW", "NEbE", "SE", "SWbS", "WNW", "NbE", "E", "SbE", "WSW", "NWbN", "NE", "SEbE", "SSW", "WbN", "N"}

which is every 7th entry from the full list of compass directions, taken cyclically until ending at "N". To explain the code, let's start with the initial 52-byte version

ResourceFunction["CompassPoint"][45#/4,32]&~Array~32

which outputs the compass directions in the order from the OP except "N" is at the end rather than the beginning. The first 32 in the code tells CompassPoint to use this list of fine-grained outputs (rather than just N/S/E/W say), while the second 32 calls the function 32 times. It doesn't work at TIO because TIO won't load the resources needed for ResourceFunction.

The number 45/4 in the original code is the 360 degrees of a circle divided by the 32 points we want to sample. It can be replaced by any odd multiple of itself—that just permutes the output. infinitezero found that \$29e \approx 78.83\$ is close enough to \$7\times\frac{45}4 = 78.75\$ that the compass directions all still round to the same things, which is how the btye was saved.

Python 3, 98 bytes 91 bytes

-7 thanks to xnor

print(*'NEWS',*['b b b    b'.translate([n,o]*4)for o in'NS'for n in'EW'])

91 Byte Try it online!

print(['N E W S']+['b b b    b'.translate({7:o,6:n})for o in 'NS'for n in 'EW'])

98 Byte Try it online!

This uses the template string XbY YbX XYbX XY XXY YXY XYbY to generate most of the output and appends N E W S separate because I could not find a way to include them cleanly in the template. It uses unprintable chars BEL (0x07) and ACK (0x06) in place of X and Y in order to save two one bytes in making the translation table (as X and Y are 88 and 89, which are two digits each) by not requiring a table length greater than 18.

The output is now a cleanly printed space separated string of directions. The second asterisk may not be strictly necessary in terms of 'anything goes' separating each direction, but it makes the output a lot nicer.


The output is a list of space delimited strings (['N E W S', 'NbE EbN NEbN NE NNE ENE NEbE', 'NbW WbN NWbN NW NNW WNW NWbW', 'SbE EbS SEbS SE SSE ESE SEbE', 'SbW WbS SWbS SW SSW WSW SWbW']), taking full advantage of the 'just separate the directions somehow, anything goes' policy.

If I really wanted to, I could drop the square brackets around the 'N E W S' and change the plus to a comma, saving two bytes and making the output even uglier...

Additionally, the current old version of the logic can run standalone in the REPL without the print, making it a 91 byte one-liner there.

JavaScript (Node.js), 90 bytes

(x='NbE NNE NEbN NE NEbE ENE EbN ',y=x+x.split`N`.join`S`)=>y+y.split`E`.join`W`+'N E S W'

Try it online!

JavaScript (Node.js), 92 bytes

(x='NbE NNE NEbN NE NEbE ENE EbN ',y=x+x.replace(/N/g,'S'))=>y+y.replace(/E/g,'W')+'N E S W'

Try it online!

C, 132 [bytes]

puts("N,NbE,NNE,NEbN,NE,NEbE,ENE,EbN,E,EbS,ESE,SEbE SE,SEbS,SSE,SbE,S,SbW,SSW,SWbS,SW,SWbW,WSW,WbS,W,WbN,WNW,NWbW,NW,NWbN,NNW,NbW");

A trivial starting point.

Now to consider a better algorithmic one...

JavaScript (Node.js), 90 bytes

_=>a+a.split`E`.join`W`+'N S'
a=`NbE NNE NEbN NE NEbE ENE EbN `
a+=a.split`N`.join`S`+'E '

Try it online!

Port of Jan Blumschein's .bat answer

JavaScript (Node.js), 96 bytes

_=>`NE
SE
NW
SW
N
E
S
W`.replace(/../g,n=>`0b1
001
01b0
01
01b1
101
1b0`.replace(/\d/g,c=>n[c]))

Try it online!

05AB1E, 32 27 bytes

•Rв₄DŠ`•48в„NS„EWâ'bìδÅвJ˜ê

-5 bytes porting @JonathanAllan's approach in his Jelly answer, using both \$1\$ (binary 1) and \$2\$ (binary 10) for the single-character compass-directions with an uniquify at the end

Try it online.

Explanation:

•Rв₄DŠ`•    # Push compressed integer 29417449383887
  48в       # Convert it to base-48 as list: [1,2,5,11,14,19,23,46,47]
„NS         # Push "NS"
   „EW      # Push "EW"
      â     # Cartesian product of the two: ["NE","NW","SE","SW"]
       'bì '# Prepend "b" before each: ["bNE","bNW","bSE","bSW"]
δ           # Apply double-vectorized over both lists:
 Åв         #  Convert the integers to a base-string list,
            #  aka, convert it to a base-length list, and index into the string
   J        # Join each inner character-list to a string
    ˜       # Flatten this list of lists of strings
     ê      # Uniquify (and sort) these strings
            # (after which the result is output implicitly)

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why •Rв₄DŠ`• is 29417449383887 and •Rв₄DŠ`•48в is [1,2,5,11,14,19,23,46,47].

Python, 107 bytes

a="N|NbE|NNE|NEbN|NE|NEbE|ENE|EbN|E|EbS|ESE|SEbE|SE|SEbS|SSE|SbE|"
print(a+a.translate("W"*70+"S"*9+"N"*5))

Attempt This Online!


Just 26 bytes shorter than a raw literal print. I'm sure there are better Python approaches, but I'll leave an initial one here.


@Lucenaposition improved on this significantly in their own answer

Python, 99 bytes

print(a:="N NbE NNE NEbN NE NEbE ENE EbN W WbN WNW NWbW NW NWbN NNW NbW",a.translate('bS.E .W'*40))

Attempt This Online!

cQuents, 85 bytes

#32&b@N;@W;k,b@N;@E;k+1,b@S;@E;k,b@S;@W;k+1
:A,A~@b~B,B~@b~A,A~Z,A~B,A~Z,B~Y,X~@b~B,B

Try it online!

Have some other ideas, but they're starting to get pretty wacky so I'll call it a night here :D

Output:

N,NbE,S,SbW,NbW,EbN,SbE,WbS,WbN,NEbN,EbS,SWbS,NWbN,NE,SEbS,SW,NW,NNE,SE,SSW,NNW,ENE,SSE,WSW,WNW,NEbE,ESE,SWbW,NWbW,E,SEbE,W

Verify output: Try it online!

Explanation

I tried a few patterns, but the pattern I ended up with was:

X, XbY, YbX, XYbX, XY, XXY, YXY, XYbY, Y

This can be repeated 4 times to generate all 32 points. However, the X term must always be the N/S side of the compass. Additionally, it will over-generate the cardinal directions, so I have to ensure I pull X from the front twice, and Y from the back twice, to correctly generate N/S/E/W all once.

The order is also relevant - string literals are a bit expensive in cQuents, so YbX and XY are positioned so that the follow-up terms can back-reference instead of building the term from scratch.

Mapped to the corresponding X,Y pairs 4 times, this pattern leads to:

N, NbE, NNE, NEbN, NE, NEbE, ENE, EbN, E
N, NbW, NNW, NWbN, NW, NWbW, WNW, WbN, W
S, SbW, SSW, SWbS, SW, SWbW, WSW, WbS, W
S, SbE, SSE, SEbS, SE, SEbE, ESE, EbS, E

Below is the code explanation. The second line implements the pattern above. The first line is the main sequence, which will have 32 terms. For every k = 1 to 8, it will call the second line (the X/Y pattern) for each set of cardinal X/Y pairs (N,W, N,E, S,E, S,W), but for the second and fourth pairs, it offsets the k by 1, to get the other cardinal direction.

#32&b@N;@W;k,b@N;@E;k+1,b@S;@E;k,b@S;@W;k+1  line 1
#32                                          n = 32, k = 1
   &        ,          ,        ,            mode sequence 2 - given input n, output first n terms
    b  ;  ;                                  next term = line 2 (     ,     ,   )
     @N                                                           "N"
        @W                                                              "W"
           k                                                                  k
             b@N;@E;k+1                      next term = line 2 ( "N" , "E" , k+1 )
                        b@S;@E;k             next term = line 2 ( "S" , "E" , k )
                                 b@S;@W;k+1  next term = line 2 ( "S" , "W" , k+1 )
                                             reset to first term, k += 1

:A,A~@b~B,B~@b~A,A~Z,A~B,A~Z,B~Y,X~@b~B,B    line 2
: ,      ,      ,   ,   ,   ,   ,      ,     mode sequence 1 - given input n, output nth term
                                             inputs = A, B, n
 A                                           next term = first input
   A                                         next term = first input
    ~                                                                concat
     @b                                                                     "b"
       ~                                                                        concat
        B                                                                              second input
          B~@b~A                             next term = second input concat "b" concat first input
                 A~Z                         next term = first input concat previous term
                     A~B                     next term = first input concat second input
                         A~Z                 next term = first input concat previous term
                             B~Y             next term = second input concat 2 terms previous
                                 X~@b~B      next term = 3 terms previous concat "b" concat second input
                                        B    next term = second input

100 bytes

#32&b@W;@N;'NW';k,b@N;@E;'NE';k,b@E;@S;'SE';k,b@S;@W;'SW';k
:A,B~C,A~C,A~@b~B,C,C~@b~A,C~@b~B,B~@b~A

Try it online!

Ruby, 76 bytes

p %w{S N NE AEW}.map{|i|'NbE,NNE,NEbN,NE,NEbE,ENE,EbN,'.tr(i,"SW")+i[-1]}*?,

Try it online!

print("\n".join(["N","NbE","NNE","NEbN","NE","NEbE","ENE","EbN","E","EbS","ESE","SEbE","SE","SEbS","SSE","SbE","S","SbW","SSW","SWbS","SW","SWbW","WSW","WbS","W","WbN","WNW","NWbW","NW","NWbN","NNW","NbW"]))

Retina 0.8.2, 76 bytes


NbE,NNE,NEbN,NE,NEbE,ENE,EbN
^
N,$'¶E,
^
$'¶
T`N`S`¶.+¶.+
T`\E`W`.+¶.+$
S`,

Try it online! Explanation:


NbE,NNE,NEbN,NE,NEbE,ENE,EbN

Insert the intermediate points between N and E.

^
N,$'¶E,

Duplicate this list, but prefix N to the first copy and E to the second.

^
$'¶

Duplicate both lists.

T`N`S`¶.+¶.+

Change N to S in the middle two copies.

T`\E`W`.+¶.+$

Change E to W in the bottom two copies.

S`,

Split each point onto its own line.

Jelly, 26 bytes

⁾NSp⁾EW;€”b“¢£¦¿ÇŒç./‘ṃⱮẎQ

A niladic Lik that yields a list of lists of characters.

Try it online! (The result is sorted alphabetically and pretty-printed for ease of comparison.)

How?

⁾NSp⁾EW;€”b“...‘ṃⱮẎQ - Link: no arguments
⁾NS                  - "NS"
    ⁾EW              - "EW"
   p                 - {"NS"} Cartesian product {"EW"}
       ;€”b          - concatenate 'b' to each
                        -> CharacterSets = ["NEb", "NWb", "SEb", "SWb"]
           “...‘     - code-page indices
                        -> MagicNumbers = [1, 2, 5, 11, 14, 19, 23, 46, 47]
                 Ɱ   - map across {CharacterSet in CharacterSets} with:
                ṃ    -   {MagicNumbers} base decompress {CharacterSet}
                  Ẏ  - tighten
                   Q - deduplicate (since we made two of each cardinal direction)

x86_64 Machine Code, 64 bytes

Requires a CPU with AVX512VBMI2. Unfortunately, that also means it can't run on any online demos I know of. It is a function that outputs into a buffer whose pointer is passed in rdi, with each compass direction delimited by a newline.

Hexdump:

48 b8 a5 97 a7 96 b1 b2 9b 00 c4 e1 fb 92 c8 b8
00 00 62 0a 48 ba 4e 45 53 45 53 57 4e 57 66 89
d0 62 f2 7d 48 7c c0 62 f2 7d 49 63 07 48 83 c7
1f 48 c1 ea 10 75 e7 c6 47 fe 45 c6 47 df 57 c3

Disassembled and annotated:

compass:
  mov rax,0x9bb2b196a797a5     ; call this constant k1
  kmovq k1,rax
  mov eax,0xa620000            ; template = "\0\0b\n"
  mov rdx,0x574e57534553454e   ; directions = "NESENWSW"
loop0:
  mov ax,dx                    ; template[15:0] = directions[15:0] (e.g. "NEb\n")
  vpbroadcastd zmm0,eax        ; set zmm0 to repeat template (e.g. "NEb\nNEb\nNEb\nNEb\n" ... 16 times total)
  vpcompressb [rdi]{k1},zmm0   ; each set bit of k1 -> corresponding element from zmm0 stored to buffer contiguously
  add rdi,31                   ; each chunk stored is 31 bytes
  shr rdx,16
  jnz loop0                    ; shift directions by 16b and loop until 0
  mov byte ptr[rdi-2],'E'      ; code outputs N,S twice and E,W no times, fix that
  mov byte ptr[rdi-33],'W'
  ret

Perl 5, 74 bytes

say'N S E W ',$_="NbE NNE NEbN NE NEbE ENE EbN ",y/N/S/r,y/E/W/r,y/NE/SW/r

Try it online!

cmd.exe, 84 75 73 bytes

set N=NbE NNE NEbN NE NEbE ENE EbN 
set N=%N%%N:N=S%E 
echo %N%%N:E=W%N S

(Note whitespace: Trailing blank after first and second line, no linefeed after last line, other lines separated by <LF>.)

Charcoal, 29 bytes

⪫NEWSψFEWFNS⍘⍘F@=RdCaFeγ⟦bικ 

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

⪫NEWSψ

Output the four cardinals spaced out.

FEWFNS

Loop over the four pairs of cardinals.

⍘⍘F@=RdCaFeγ⟦bικ 

Decode the string RdCaFeγ as base 95 using printable ASCII as a custom character set, then encode as base 4 using a custom character set of b = 0, E/W = 1, N/S = 2 and space = 3. This outputs all of the intermediate compass points between the two cardinals.

C# 12 - 197 bytes

f=()=>{List<string>v=["N","S"],h=["E","W"];var o="";for(int i=0;i<2;i++){o+=$"{v[i]},{h[i]},";for(int j=0;j<2;j++)o+=$"cbn,ccn,cnbc,cn,cnbn,ncn,nbc,".Replace("c",v[i]).Replace("n",h[j]);}return o;}

Ungolfed:

f = () =>
{
    List<string> v = ["N", "S"],
                 h = ["E", "W"];
    var o = "";

    for (int i = 0; i < 2; i++)
    {
        o += $"{v[i]},{h[i]},";
        for (int j = 0; j < 2; j++)
            o += $"cbn,ccn,cnbc,cn,cnbn,ncn,nbc,".Replace("c", v[i]).Replace("n", h[j]);
    }

    return o;
}
```