A - Lucky Direction
Source: atcoder
Difficulty: 100

Problem Statement
You are given a string
D
representing one of the eight directions (north, east, west, south, northeast, northwest, southeast, southwest). The correspondence between the directions and their representing strings is as follows.
North:
N
East:
E
West:
W
South:
S
Northeast:
NE
Northwest:
NW
Southeast:
SE
Southwest:
SW
Print the string representing the direction opposite to the direction denoted by
D
.
Constraints
D
is one of
N
,
E
,
W
,
S
,
NE
,
NW
,
SE
,
SW
.
Input
The input is given from Standard Input in the following format:
D
Output
Print the answer.
Sample Input 1
N
Sample Output 1
S
Print
S
, which represents south, the direction opposite to north.
Sample Input 2
SE
Sample Output 2
NW
Print
NW
, which represents northwest, the direction opposite to southeast.

C++ solution:
#line 1 "A_Lucky_Direction.cpp"
#include <bits/stdc++.h>

template <class A, class B>
std::ostream& operator<<(std::ostream& ost, const std::pair<A, B>& p) {
    ost << "(" << p.first << ", " << p.second << ")";
    return ost;
}

template <class T>
std::ostream& operator<<(std::ostream& ost, const std::vector<T>& v) {
    ost << "[";
    for (int i = 0; i < v.size(); i++) {
        if (i) ost << ", ";
        ost << v[i];
    }
    ost << "]";
    return ost;
}

template <class T>
std::ostream& operator<<(std::ostream& ost, const std::set<T>& s) {
    ost << "{";
    bool first = true;
    for (const auto& v : s) {
        if (!first) ost << ", ";
        ost << v;
        first = false;
    }
    ost << "}";
    return ost;
}

template <class T, class U>
std::ostream& operator<<(std::ostream& ost, const std::map<T, U>& m) {
    ost << "{";
    bool first = true;
    for (const auto& [k, v] : m) {
        if (!first) ost << ", ";
        ost << k << ":" << v;
        first = false;
    }
    ost << "}";
    return ost;
}

void print() {}

template <class Head, class... Tail>
void print(Head&& head, Tail&&... tail) {
    std::cout << head;
    if (sizeof...(Tail)) {
        std::cout << " ";
    }
    print(std::forward<Tail>(tail)...);
}

template <class... Args>
void println(Args&&... args) {
    print(args..., '\n');
}

#define SHOW(...)                                             \
    SHOW_IMPL(__VA_ARGS__, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, \
              SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define SHOW1(x) println(#x, "=", (x))
#define SHOW2(x, y) println(#x, "=", (x), #y, "=", (y))
#define SHOW3(x, y, z) println(#x, "=", (x), #y, "=", (y), #z, "=", (z))
#define SHOW4(x, y, z, w) \
    println(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w))
#define SHOW5(x, y, z, w, v)                                                 \
    println(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \
            (v))
#define SHOW6(x, y, z, w, v, u)                                              \
    println(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \
            (v), #u, "=", (u))

int Yes() {
    println("Yes");
    return 0;
}
int No() {
    println("No");
    return 0;
}

#define FOR1(a) for (int64_t _ = 0; _ < int64_t(a); ++_)
#define FOR2(i, a) for (int64_t i = 0; i < int64_t(a); ++i)
#define FOR3(i, a, b) for (int64_t i = a; i < int64_t(b); ++i)
#define FOR4(i, a, b, c) for (int64_t i = a; i < int64_t(b); i += (c))
#define FOR1_R(a) for (int64_t i = (a) - 1; i >= int64_t(0); --i)
#define FOR2_R(i, a) for (int64_t i = (a) - 1; i >= int64_t(0); --i)
#define FOR3_R(i, a, b) for (int64_t i = (b) - 1; i >= int64_t(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define rep(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define rep_r(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

template <typename A, typename B>
inline void chmin(A& a, const B b) {
    if (a > b) a = b;
}
template <typename A, typename B>
inline void chmax(A& a, const B b) {
    if (a < b) a = b;
}

inline int32_t popcount(int64_t x) {
    return popcount(static_cast<uint64_t>(x));
}

#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define fi first
#define se second

#define int long long  // <= 64bit ミ(°_°)ミ

using vint = std::vector<int>;
using pint = std::pair<int, int>;
using vpint = std::vector<pint>;
using namespace std;

constexpr int INF = 1ll << 61;

signed main() {
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    // torichan

    string S = "NESW";
    string D;
    cin >> D;
    for (auto& c : D) {
        int k = S.find(c);
        c = S[(k + 2) % 4];
    }
    println(D);
    return 0;
}

Go solution:
package main

import (
	"fmt"
	"io"
	"os"
	"strings"
)

type DirectionEnum int

// iotaを用いて連番を生成する
const (
	N DirectionEnum = iota
	NE
	E
	SE
	S
	SW
	W
	NW
)

var directionMap = map[DirectionEnum]string{
	N:  "N",
	NE: "NE",
	E:  "E",
	SE: "SE",
	S:  "S",
	SW: "SW",
	W:  "W",
	NW: "NW",
}

// iotaを用いて生成した連番に対して、別名を与えて定義する
func (yn DirectionEnum) LuckyDirection() DirectionEnum {
	return (yn + 4) % 8
}

// iotaを用いて生成した連番に対して、別名を与えて定義する
func directionEnumbyString(dstr string) DirectionEnum {
	switch dstr {
	case "N":
		return N
	case "NE":
		return NE
	case "E":
		return E
	case "SE":
		return SE
	case "S":
		return S
	case "SW":
		return SW
	case "W":
		return W
	case "NW":
		return NW
	}
	return N
}

func main() {
	lines := getStdin()
	culcFunction(lines)
}

// / 標準入力を取得する
func getStdin() []string {
	stdin, _ := io.ReadAll(os.Stdin)
	return strings.Split(string(stdin), "\n")
}

func culcFunction(line []string) {
	var d = directionEnumbyString(line[0])

	fmt.Println(directionMap[d.LuckyDirection()])
}

Java solution:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
//        BufferedReader br = new BufferedReader(new FileReader("input.in"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        if(s.equals("N")){
            System.out.println("S");
        } else if(s.equals("S")){
            System.out.println("N");
        } else if(s.equals("E")){
            System.out.println("W");
        } else if(s.equals("W")){
            System.out.println("E");
        } else if(s.equals("NE")){
            System.out.println("SW");
        } else if(s.equals("SW")){
            System.out.println("NE");
        } else if(s.equals("NW")){
            System.out.println("SE");
        } else if(s.equals("SE")){
            System.out.println("NW");
        }
    }
}

JavaScript solution:
function Main(input) {
    const data = {
        縦: ['N', 'S'],
        横: ['E', 'W'],
        東寄り: ['NE', 'SW'],
        西寄り: ['NW', 'SE'],
    };

    const direction = input.trim();

    for (const key in data) {
        if (data[key].includes(direction)) {
            const index = data[key].indexOf(direction);
            console.log(data[key][index === 0 ? 1 : 0]);
            break;
        }
    }
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));

Python solution:
d = input()
ans = ""
for i in d:
    if i == "N":
        ans += "S"
    if i == "S":
        ans += "N"
    if i == "E":
        ans += "W"
    if i == "W":
        ans += "E"
print(ans)

Ruby solution:
a = gets.chomp
if a == "N"
  puts "S"
elsif a == "S"
  puts "N"
elsif a == "E"
  puts "W"
elsif a == "W"
  puts "E"
elsif a == "NE"
  puts "SW"
elsif a == "SW"
  puts "NE"
elsif a == "SE"
  puts "NW"
elsif a == "NW"
  puts "SE"
end