Inhalt
Die Fakten:
Plattform: | codewars.com |
Name: | Is Sator Square? |
Level: | 7 kyu |
Sprache: | TypeScript |
Beschreibung:
A Discovery
One fine day while Farmer Arepo Tenaciously Labored at Turning the soil, he discovered a field that was scattered with strange stone tablets. Noticing they were carved with letters in a square pattern, he wisely kept them in case some might be special.
Your Task
Please help Farmer Arepo by inspecting each tablet to see if it forms a valid Sator Square!
The Square
is a two-dimentional palindrome, made from words of equal length that can be read in these four ways:
1) left-to-right (across)
2) top-to-bottom (down)
3) bottom-to-top (up)
4) right-to-left (reverse)
An Example
Considering this square:
B A T S
A B U T
T U B A
S T A B
Here are the four ways a word (in this case "TUBA"
) can be read:
down ↓ B A T S B A T S B A T S B A T S A B U T A B U T A B U T A B U T ← reverse across → T U B A T U B A T U B A T U B A S T A B S T A B S T A B S T A B ↑ up
IMPORTANT:
- In a
true
Sator Square, ALL of its words can be read in ALL four of these ways. - If there is any deviation, it would be
false
to consider it a Sator Square.
Some Details
- tablet (square) dimensions range from
2x2
to33x33
inclusive - all characters used will be upper-case alphabet letters
- there is no need to validate any input
Input
- an N x N (square) two-dimentional matrix of uppercase letters
Output
- boolean
true
orfalse
whether or not the tablet is a Sator Square
Enjoy!
...and please consider one of the following kata to solve next:
- Playing With Toy Blocks ~ Can you build a 4x4 square?
- Four Letter Words ~ Mutations
- Crossword Puzzle! (2x2)
- Interlocking Binary Pairs
- Setting Places for the Dead
- Four Letter Words ~ Anagrams
- Shuffle an Integer
Quelle: codewars.com
Lösung
Pseudo-Code
Wie immer gibt's reichlich Varianten, hier ist eine meiner.
Erst die Lösungsschritte in Pseudo-Code. Los geht’s:
Lösungsschritte
Schritt 1
Um alle Reihen bzw. Spalten zu durchlaufen brauchen wir einen Loop.
Schritt 2
Dann können wir alle 4
Optionen erst mal jeweils in einer Variablen speichern.
Schritt 3
leftToRight
: easy, einfach die aktuelle (i
-te) Reihe bzw. das aktuelle Element.
Schritt 4
topToBottom
: das ist jeweils der i
-te Buchstabe jeder Reihe.
Schritt 5
bottomToTop
: das ist jeweils der i
-te Buchstabe jeder Reihe von hinten bzw. rechts, spiegelverkehrt.
Schritt 6
rightToLeft
: das ist die aktuelle Reihe von hinten bzw. unten, spiegelverkehrt.
Code
Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:
Lösungsschritte
Meine erste Zeile:
export function isSatorSquare(tablet: string[][]): boolean {
Dann die leftToRight
-Variable:
const leftToRight = tablet[i].join("");
Als Zweites die topToBottom
-Variable:
const topToBottom = tablet.map((row) => row[i]).join("");
Hier mappen wir durch jedes Element, also jede Reihe und geben nur den jeweils i
-ten Buchstaben zurück. Wir erhalten jeden Buchstaben der aktuellen (i
-ten) Spalte.
Jetzt die bottomToTop
-Variable:
const bottomToTop = tablet
.slice()
.map((row) => row[row.length - 1 - i])
.reverse()
.join("");
Hier kommen wir von hinten, also rechts, indem wir vom Index
des letzten Buchstaben jeder Reihe jeweils i
abziehen. Dann drehen wir das Ganze mit .reverse()
um.
ACHTUNGNicht vergessen hier mit .slice() vorher eine Kopie zu erstellen, denn .reverse() mutiert das Array!
Und zum Schluss die rightToLeft
-Variable:
const rightToLeft = tablet[tablet.length - 1 - i].slice().reverse().join("");
Hier kommen wir von unten, indem wir vom Index
der letzten Reihe i
abziehen. Wir drehen das Ganze wieder mit .reverse()
um und erstellen vorher die Kopie mit .slice()
.
Jetzt können wir unsere Ergebnisse logisch überprüfen:
if (leftToRight !== topToBottom) return false;
if (topToBottom !== bottomToTop) return false;
if (bottomToTop !== rightToLeft) return false;
}
Hier gibt es viele Möglichkeiten dies zu tun. Diese finde ich am lesbarsten. Keep it simple!
Sollte eines unserer Ergebnisse nicht mit den anderen übereinstimmen, geben wir false
zurück.
Ansonsten true
:
return true;
}
Voilá! 💪
Komplettlösung
export function isSatorSquare(tablet: string[][]): boolean {
for (let i = 0; i < tablet.length; i++) {
const leftToRight = tablet[i].join("");
const topToBottom = tablet.map((row) => row[i]).join("");
const bottomToTop = tablet
.slice()
.map((row) => row[row.length - 1 - i])
.reverse()
.join("");
const rightToLeft = tablet[tablet.length - 1 - i]
.slice()
.reverse()
.join("");
if (leftToRight !== topToBottom) return false;
if (topToBottom !== bottomToTop) return false;
if (bottomToTop !== rightToLeft) return false;
}
return true;