From fa549e34b6a30a622eff36dbab97c8543a9b26a6 Mon Sep 17 00:00:00 2001 From: Angelika Tyborska Date: Wed, 8 Mar 2023 21:48:48 +0100 Subject: [PATCH] Sync crypto-square --- .../crypto-square/.docs/instructions.md | 34 ++++++------ .../practice/crypto-square/.meta/config.json | 2 +- .../practice/crypto-square/.meta/proof.ci.ts | 55 +++++++------------ .../practice/crypto-square/.meta/tests.toml | 16 +++++- .../crypto-square/crypto-square.test.ts | 13 +++-- 5 files changed, 60 insertions(+), 60 deletions(-) diff --git a/exercises/practice/crypto-square/.docs/instructions.md b/exercises/practice/crypto-square/.docs/instructions.md index f919ff5b9..6c3826ee5 100644 --- a/exercises/practice/crypto-square/.docs/instructions.md +++ b/exercises/practice/crypto-square/.docs/instructions.md @@ -4,11 +4,10 @@ Implement the classic method for composing secret messages called a square code. Given an English text, output the encoded version of that text. -First, the input is normalized: the spaces and punctuation are removed -from the English text and the message is downcased. +First, the input is normalized: the spaces and punctuation are removed from the English text and the message is down-cased. -Then, the normalized characters are broken into rows. These rows can be -regarded as forming a rectangle when printed with intervening newlines. +Then, the normalized characters are broken into rows. +These rows can be regarded as forming a rectangle when printed with intervening newlines. For example, the sentence @@ -22,13 +21,16 @@ is normalized to: "ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots" ``` -The plaintext should be organized in to a rectangle. The size of the -rectangle (`r x c`) should be decided by the length of the message, -such that `c >= r` and `c - r <= 1`, where `c` is the number of columns -and `r` is the number of rows. +The plaintext should be organized into a rectangle as square as possible. +The size of the rectangle should be decided by the length of the message. -Our normalized text is 54 characters long, dictating a rectangle with -`c = 8` and `r = 7`: +If `c` is the number of columns and `r` is the number of rows, then for the rectangle `r` x `c` find the smallest possible integer `c` such that: + +- `r * c >= length of message`, +- and `c >= r`, +- and `c - r <= 1`. + +Our normalized text is 54 characters long, dictating a rectangle with `c = 8` and `r = 7`: ```text "ifmanwas" @@ -40,8 +42,7 @@ Our normalized text is 54 characters long, dictating a rectangle with "sroots " ``` -The coded message is obtained by reading down the columns going left to -right. +The coded message is obtained by reading down the columns going left to right. The message above is coded as: @@ -49,17 +50,14 @@ The message above is coded as: "imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau" ``` -Output the encoded text in chunks that fill perfect rectangles `(r X c)`, -with `c` chunks of `r` length, separated by spaces. For phrases that are -`n` characters short of the perfect rectangle, pad each of the last `n` -chunks with a single trailing space. +Output the encoded text in chunks that fill perfect rectangles `(r X c)`, with `c` chunks of `r` length, separated by spaces. +For phrases that are `n` characters short of the perfect rectangle, pad each of the last `n` chunks with a single trailing space. ```text "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau " ``` -Notice that were we to stack these, we could visually decode the -ciphertext back in to the original message: +Notice that were we to stack these, we could visually decode the ciphertext back in to the original message: ```text "imtgdvs" diff --git a/exercises/practice/crypto-square/.meta/config.json b/exercises/practice/crypto-square/.meta/config.json index 20a365918..a238d43da 100644 --- a/exercises/practice/crypto-square/.meta/config.json +++ b/exercises/practice/crypto-square/.meta/config.json @@ -19,5 +19,5 @@ }, "blurb": "Implement the classic method for composing secret messages called a square code.", "source": "J Dalbey's Programming Practice problems", - "source_url": "http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" + "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" } diff --git a/exercises/practice/crypto-square/.meta/proof.ci.ts b/exercises/practice/crypto-square/.meta/proof.ci.ts index 26d5e0fa4..a231be853 100644 --- a/exercises/practice/crypto-square/.meta/proof.ci.ts +++ b/exercises/practice/crypto-square/.meta/proof.ci.ts @@ -11,53 +11,40 @@ export class Crypto { return '' } - const splitRegex = new RegExp(`.{1,${chunkSize}}`, 'g') - return this.ciphertextSegments() - .join('') - .match(splitRegex) - .map((item) => item.padEnd(chunkSize, ' ')) - .join(' ') + return this.ciphertextSegments().join(' ') } public get size(): number { const realLength = Math.sqrt(this.plaintext.length) - return Math.ceil(realLength) + return Math.trunc(Math.ceil(realLength)) } private ciphertextSegments(): string[] { - const textSegments = this.plaintextSegments() - const columns: string[][] = [] - let i: number - let j: number - let currentSegment: RegExpMatchArray[number] - let currentLetter: RegExpMatchArray[number][number] - - for (i = 0; i < this.size; i += 1) { - columns.push([]) - } - - for (i = 0; i < textSegments.length; i += 1) { - currentSegment = textSegments[i] - - for (j = 0; j < currentSegment.length; j += 1) { - currentLetter = currentSegment[j] - columns[j].push(currentLetter) - } - } - - const result: string[] = [] - for (i = 0; i < columns.length; i += 1) { - result[i] = columns[i].join('') + const textSegments = this.plaintextSegments().map((s) => s.split('')) + if (textSegments === []) { + return [] + } else { + return textSegments[0].map((_firstTextSegmentLetter, i) => + textSegments.map((_textSegment, j) => textSegments[j][i]).join('') + ) } - - return result } - private plaintextSegments(): RegExpMatchArray { + private plaintextSegments(): string[] { const plainText = this.plaintext const chunkSize = this.size const splitRegex = new RegExp(`.{1,${chunkSize}}`, 'g') - return plainText.match(splitRegex) + const matches = plainText.match(splitRegex) + + if (!matches) { + return [] + } + + if (matches[matches.length - 1].length < this.size) { + matches[matches.length - 1] += ' '.repeat(this.size - matches.length + 1) + } + + return matches } } diff --git a/exercises/practice/crypto-square/.meta/tests.toml b/exercises/practice/crypto-square/.meta/tests.toml index 054544573..085d142ea 100644 --- a/exercises/practice/crypto-square/.meta/tests.toml +++ b/exercises/practice/crypto-square/.meta/tests.toml @@ -1,10 +1,20 @@ -# This is an auto-generated file. Regular comments will be removed when this -# file is regenerated. Regenerating will not touch any manually added keys, -# so comments can be added in a "comment" key. +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. [407c3837-9aa7-4111-ab63-ec54b58e8e9f] description = "empty plaintext results in an empty ciphertext" +[aad04a25-b8bb-4304-888b-581bea8e0040] +description = "normalization results in empty plaintext" + [64131d65-6fd9-4f58-bdd8-4a2370fb481d] description = "Lowercase" diff --git a/exercises/practice/crypto-square/crypto-square.test.ts b/exercises/practice/crypto-square/crypto-square.test.ts index 80aaf5af0..3955c2254 100644 --- a/exercises/practice/crypto-square/crypto-square.test.ts +++ b/exercises/practice/crypto-square/crypto-square.test.ts @@ -6,17 +6,22 @@ describe('Crypto', () => { expect(crypto.ciphertext).toEqual('') }) - it('Lowercase', () => { + xit('normalization results in empty plaintext', () => { + const crypto = new Crypto('... --- ...') + expect(crypto.ciphertext).toEqual('') + }) + + xit('Lowercase', () => { const crypto = new Crypto('A') expect(crypto.ciphertext).toEqual('a') }) - it('Remove spaces', () => { + xit('Remove spaces', () => { const crypto = new Crypto(' b ') expect(crypto.ciphertext).toEqual('b') }) - it('Remove punctuation', () => { + xit('Remove punctuation', () => { const crypto = new Crypto('@1,%!') expect(crypto.ciphertext).toEqual('1') }) @@ -31,7 +36,7 @@ describe('Crypto', () => { expect(crypto.ciphertext).toEqual('clu hlt io ') }) - it.skip('54 character plaintext results in 7 chunks, the last two with trailing spaces', () => { + xit('54 character plaintext results in 7 chunks, the last two with trailing spaces', () => { const crypto = new Crypto( 'If man was meant to stay on the ground, god would have given us roots.' )