Skip to content

Commit 0a5b3e8

Browse files
authored
Merge pull request #127 from bward/master
atbash-cipher exercise for TypeScript
2 parents 8559bd5 + 680ad1a commit 0a5b3e8

9 files changed

+2987
-0
lines changed

config.json

+13
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,19 @@
541541
"games",
542542
"parsing"
543543
]
544+
},
545+
{
546+
"uuid": "04de61fb-9fde-461c-b306-0b4ce52e2169",
547+
"slug": "atbash-cipher",
548+
"core": true,
549+
"difficulty": 7,
550+
"topics": [
551+
"algorithms",
552+
"arrays",
553+
"control-flow-(conditionals)",
554+
"control-flow-(loops)",
555+
"text-formatting"
556+
]
544557
}
545558
],
546559
"foregone": [],

exercises/atbash-cipher/README.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Atbash Cipher
2+
3+
Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.
4+
5+
The Atbash cipher is a simple substitution cipher that relies on
6+
transposing all the letters in the alphabet such that the resulting
7+
alphabet is backwards. The first letter is replaced with the last
8+
letter, the second with the second-last, and so on.
9+
10+
An Atbash cipher for the Latin alphabet would be as follows:
11+
12+
```text
13+
Plain: abcdefghijklmnopqrstuvwxyz
14+
Cipher: zyxwvutsrqponmlkjihgfedcba
15+
```
16+
17+
It is a very weak cipher because it only has one possible key, and it is
18+
a simple monoalphabetic substitution cipher. However, this may not have
19+
been an issue in the cipher's time.
20+
21+
Ciphertext is written out in groups of fixed length, the traditional group size
22+
being 5 letters, and punctuation is excluded. This is to make it harder to guess
23+
things based on word boundaries.
24+
25+
## Examples
26+
27+
- Encoding `test` gives `gvhg`
28+
- Decoding `gvhg` gives `test`
29+
- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`
30+
## Setup
31+
32+
Go through the setup instructions for TypeScript to
33+
install the necessary dependencies:
34+
35+
http://exercism.io/languages/typescript
36+
37+
## Requirements
38+
39+
Install assignment dependencies:
40+
41+
```bash
42+
$ yarn install
43+
```
44+
45+
## Making the test suite pass
46+
47+
Execute the tests with:
48+
49+
```bash
50+
$ yarn test
51+
```
52+
53+
54+
55+
## Source
56+
57+
Inspired by the Extreme Startup game [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup)
58+
59+
## Submitting Incomplete Solutions
60+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class AtbashCipher {
2+
private alphabet: string = "abcdefghijklmnopqrstuvwxyz"
3+
private numbers: string = "0123456789"
4+
5+
public encode(plainText: string) {
6+
const lowerCaseLettersOnly = plainText
7+
.toLowerCase()
8+
.split("")
9+
.filter((char) => this.alphabet.includes(char) || this.numbers.includes(char))
10+
.join("")
11+
12+
return this.decode(lowerCaseLettersOnly)
13+
.split("")
14+
.reduce((accumulator: string[], _, index, array) => {
15+
if (index % 5 === 0) {
16+
accumulator.push(array.slice(index, index + 5).join(""))
17+
}
18+
return accumulator
19+
}, [])
20+
.join(" ")
21+
}
22+
23+
public decode(cipherText: string) {
24+
return cipherText
25+
.split(" ").join("")
26+
.split("")
27+
.map((char) => this.alphabet.includes(char) ? this.alphabet[25 - this.alphabet.indexOf(char)] : char)
28+
.join("")
29+
}
30+
}
31+
32+
export default AtbashCipher
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import AtbashCipher from './atbash-cipher'
2+
3+
describe('AtbashCipher', () => {
4+
let atbash: AtbashCipher
5+
6+
beforeAll(() => {
7+
atbash = new AtbashCipher()
8+
})
9+
10+
describe("encoding", () => {
11+
it("encode yes", () => {
12+
const cipherText = atbash.encode("yes")
13+
expect(cipherText).toEqual("bvh")
14+
})
15+
16+
xit("encode no", () => {
17+
const cipherText = atbash.encode("no")
18+
expect(cipherText).toEqual("ml")
19+
})
20+
21+
xit("encode OMG", () => {
22+
const cipherText = atbash.encode("OMG")
23+
expect(cipherText).toEqual("lnt")
24+
})
25+
26+
xit("encode spaces", () => {
27+
const cipherText = atbash.encode("O M G")
28+
expect(cipherText).toEqual("lnt")
29+
})
30+
31+
xit("encode mindblowingly", () => {
32+
const cipherText = atbash.encode("mindblowingly")
33+
expect(cipherText).toEqual("nrmwy oldrm tob")
34+
})
35+
36+
xit("encode numbers", () => {
37+
const cipherText = atbash.encode("Testing,1 2 3, testing.")
38+
expect(cipherText).toEqual("gvhgr mt123 gvhgr mt")
39+
})
40+
41+
xit("encode deep thought", () => {
42+
const cipherText = atbash.encode("Truth is fiction.")
43+
expect(cipherText).toEqual("gifgs rhurx grlm")
44+
})
45+
46+
xit("encode all the letters", () => {
47+
const cipherText = atbash.encode("thequickbrownfoxjumpsoverthelazydog")
48+
expect(cipherText).toEqual("gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt")
49+
})
50+
})
51+
52+
xdescribe("decode", () => {
53+
xit("decode exercism", () => {
54+
const plainText = atbash.decode("vcvix rhn")
55+
expect(plainText).toEqual("exercism")
56+
})
57+
58+
xit("decode a sentence", () => {
59+
const cipherText = atbash.decode("zmlyh gzxov rhlug vmzhg vkkrm thglm v")
60+
expect(cipherText).toEqual("anobstacleisoftenasteppingstone")
61+
})
62+
63+
xit("decode numbers", () => {
64+
const plainText = atbash.decode("gvhgr mt123 gvhgr mt")
65+
expect(plainText).toEqual("testing123testing")
66+
})
67+
68+
xit("decode all the letters", () => {
69+
const cipherText = atbash.decode("gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt")
70+
expect(cipherText).toEqual("thequickbrownfoxjumpsoverthelazydog")
71+
})
72+
})
73+
})

exercises/atbash-cipher/atbash-cipher.ts

Whitespace-only changes.

exercises/atbash-cipher/package.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "xtypescript",
3+
"version": "1.0.0",
4+
"description": "Exercism exercises in Typescript.",
5+
"author": "",
6+
"private": true,
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/exercism/xtypescript"
10+
},
11+
"devDependencies": {},
12+
"scripts": {
13+
"test": "tsc --noEmit -p . && jest --no-cache",
14+
"lint": "tsc --noEmit -p . && tslint \"*.ts?(x)\"",
15+
"lintci": "tslint \"*.ts?(x)\" --force"
16+
},
17+
"dependencies": {
18+
"@types/jest": "^21.1.5",
19+
"@types/node": "^8.0.47",
20+
"jest": "^21.2.1",
21+
"ts-jest": "^21.1.3",
22+
"tslint": "^5.8.0",
23+
"typescript": "^2.5.3"
24+
},
25+
"jest": {
26+
"transform": {
27+
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
28+
},
29+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
30+
"moduleFileExtensions": [
31+
"ts",
32+
"tsx",
33+
"js"
34+
]
35+
}
36+
}

exercises/atbash-cipher/tsconfig.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2017",
4+
"module": "commonjs",
5+
"alwaysStrict": true,
6+
"noUnusedLocals": true,
7+
"noUnusedParameters": true,
8+
"noImplicitAny": true,
9+
"strictNullChecks": true,
10+
"preserveConstEnums": true,
11+
"noFallthroughCasesInSwitch":true,
12+
"noImplicitThis":true,
13+
"noImplicitReturns":true,
14+
"sourceMap": true,
15+
"noEmitOnError": true,
16+
"outDir": "./build"
17+
},
18+
"compileOnSave": true,
19+
"exclude": [
20+
"node_modules"
21+
]
22+
}

exercises/atbash-cipher/tslint.json

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
{
2+
"jsRules": {
3+
"class-name": true,
4+
"comment-format": [
5+
true,
6+
"check-space"
7+
],
8+
"indent": [
9+
true,
10+
"spaces"
11+
],
12+
"no-duplicate-variable": true,
13+
"no-eval": true,
14+
"no-trailing-whitespace": true,
15+
"no-unsafe-finally": true,
16+
"one-line": [
17+
true,
18+
"check-open-brace",
19+
"check-whitespace"
20+
],
21+
"quotemark": [
22+
false,
23+
"double"
24+
],
25+
"semicolon": [
26+
true,
27+
"never"
28+
],
29+
"triple-equals": [
30+
true,
31+
"allow-null-check"
32+
],
33+
"variable-name": [
34+
true,
35+
"ban-keywords"
36+
],
37+
"whitespace": [
38+
true,
39+
"check-branch",
40+
"check-decl",
41+
"check-operator",
42+
"check-separator",
43+
"check-type"
44+
]
45+
},
46+
"rules": {
47+
"class-name": true,
48+
"comment-format": [
49+
true,
50+
"check-space"
51+
],
52+
"indent": [
53+
true,
54+
"spaces"
55+
],
56+
"no-eval": true,
57+
"no-internal-module": true,
58+
"no-trailing-whitespace": true,
59+
"no-unsafe-finally": true,
60+
"no-var-keyword": true,
61+
"one-line": [
62+
true,
63+
"check-open-brace",
64+
"check-whitespace"
65+
],
66+
"semicolon": [
67+
true,
68+
"never"
69+
],
70+
"triple-equals": [
71+
true,
72+
"allow-null-check"
73+
],
74+
"typedef-whitespace": [
75+
true,
76+
{
77+
"call-signature": "nospace",
78+
"index-signature": "nospace",
79+
"parameter": "nospace",
80+
"property-declaration": "nospace",
81+
"variable-declaration": "nospace"
82+
}
83+
],
84+
"variable-name": [
85+
true,
86+
"ban-keywords"
87+
],
88+
"whitespace": [
89+
true,
90+
"check-branch",
91+
"check-decl",
92+
"check-operator",
93+
"check-separator",
94+
"check-type"
95+
],
96+
"no-namespace": true,
97+
"prefer-for-of": true,
98+
"only-arrow-functions": [true, "allow-declarations"],
99+
"no-var-requires": true,
100+
"no-any": true,
101+
"curly": true,
102+
"forin": true,
103+
"no-arg": true,
104+
"label-position": true,
105+
"no-conditional-assignment": true,
106+
"no-console": [true, "log", "error"],
107+
"no-construct": true,
108+
"no-duplicate-variable": true,
109+
"no-empty": true,
110+
"no-invalid-this": [true, "check-function-in-method"],
111+
"no-misused-new": true,
112+
"no-null-keyword": true,
113+
"no-string-literal": true,
114+
"radix": true,
115+
"typeof-compare": true,
116+
"use-isnan": true,
117+
"prefer-const": true,
118+
"array-type": [true, "array-simple"],
119+
"arrow-parens": true,
120+
"new-parens": true,
121+
"no-consecutive-blank-lines": [true,1],
122+
"no-parameter-properties": true,
123+
"no-unnecessary-initializer": true,
124+
"object-literal-shorthand": true,
125+
"object-literal-key-quotes": [true, "as-needed"]
126+
}
127+
}

0 commit comments

Comments
 (0)