Inhalt
Die Fakten:
Plattform: | codewars.com |
Name: | Playing Cards Draw Order – Part 1 |
Level: | 7 kyu |
Sprache: | TypeScript |
Beschreibung:
- This is Part 1 of this series of two katas — Part 2 is here.
- If you like playing cards, have also a look at Hide a message in a deck of playing cards and Card-Chameleon, a Cipher with Playing cards.
In this series of two katas, we will draw playing cards from a deck using a particular procedure: after drawing one card, we place the next one at the bottom of the deck.
In details, the procedure is:
- We draw the top card of the deck.
- We take the next card, and put it at the bottom of the deck.
- We repeat steps 1 and 2 until there aren't any card left in the deck.
Let's take a small deck containing four cards — named A, B, C, D — as an example:
- The deck order is
A-B-C-D
at the beginning, the cardA
is at the top andD
at the bottom. A
is drawn. The deck is nowB-C-D
.B
is placed at the bottom of the deck. The deck is nowC-D-B
.C
is drawn. The deck is nowD-B
.D
is placed at the bottom of the deck. The deck is nowB-D
.B
is drawn. The deck is nowD
.D
is drawn.
The order of the cards drawn is A-C-B-D
.
Your task
Write a function accepting a deck of cards as argument, and returning the cards drawn following the procedure.
const draw = (deck) => {
draw = (deck) ->
export const draw = (deck: string[]): string[] => {
public static List draw(List deck) {
def draw(deck: Seq[String]): Seq[String] = ???
Each card is represented with a two-character string: the rank of the card and its suit.
AC 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC
for the Clubs
AD 2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD
for the Diamonds
AH 2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH
for the Hearts
AS 2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS
for the Spades
A preloaded function allows to easily print a deck to the console:
printDeck(deck, unicode);
printDeck deck, unicode
import { printDeck } from "./preloaded";
printDeck(deck, unicode);
DeckPrinter.printDeck(deck, unicode);
import Preloaded.printDeck
printDeck(deck, unicode)
The first argument is the deck to print, the second one is a boolean value allowing the selection of the character set: regular or Unicode (for which a font containing the playing cards characters needs to be installed on your system).
Example
const deck = ["KC", "KH", "QC", "KS", "KD", "QH", "QD", "QS"];
draw(deck);
deck = ["KC", "KH", "QC", "KS", "KD", "QH", "QD", "QS"]
draw deck
const deck = ["KC", "KH", "QC", "KS", "KD", "QH", "QD", "QS"];
draw(deck);
List deck = Arrays.asList(new String[] {"KC", "KH", "QC", "KS", "KD", "QH", "QD", "QS"});
CardDraw.draw(deck);
val deck = Seq("KC", "KH", "QC", "KS", "KD", "QH", "QD", "QS")
draw(deck)
should return:
["KC", "QC", "KD", "QD", "KH", "QH", "KS", "QS"];
["KC", "QC", "KD", "QD", "KH", "QH", "KS", "QS"]
["KC", "QC", "KD", "QD", "KH", "QH", "KS", "QS"];
["KC", "QC", "KD", "QD", "KH", "QH", "KS", "QS"];
Seq("KC", "QC", "KD", "QD", "KH", "QH", "KS", "QS")
Have fun!
I hope you will enjoy this kata! Feedbacks and translations are very welcome.
After this one, jump to Part 2, where we will be ordering the deck to be drawn to have a chosen result!
Quelle: codewars.com
Lösung
Pseudo-Code
Wie immer gibt's reichlich Varianten, hier ist eine meiner.
Ordentlich Text... 🫣 aber letztlich halb so wild!
Erst die Lösungsschritte in Pseudo-Code. Los geht’s:
Lösungsschritte
Schritt 1
Zuerst brauchen wir eine Variable, in der wir die gezogenen, nicht zurückgelegten Karten speichern.
Schritt 2
Dann sollten wir vom Input Array eine Kopie erstellen, um die Funktion "pur" zu halten.
Schritt 3
Jetzt können wir durch das kopierte Array loopen.
Schritt 4
Wenn der Index der nächsten Karte gerade ist, legen wir sie auf den neuen Stapel.
Schritt 5
Wenn nicht, kommt sie zurück ans Ende.
Code
Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:
Lösungsschritte
Meine erste Zeile:
export const draw = (deck: string[]): string[] => {
Wir erstellen unsere beiden Variablen:
const drawnCards: string[] = [];
const remainingDeck = [...deck];
Jetzt der Loop:
while (remainingDeck.length) {
Wir wollen solange loopen, wie Karten im Ausgangs-Stapel sind. Also solange die Länge des Arrays nicht 0
, also true
ist.
Die jeweils aktuelle Karte speichere ich der Übersichtlichkeit halber in einer Variablen:
const currCard = remainingDeck.shift()!;
Das Ausrufezeichen !
am Ende sagt TypeScript
, dass wir sicher sind, dass es dieses Element im Array auch wirklich gibt.
Wir können uns sicher sein, da wir ja nur solange loopen, wie Elemente im Array sind.
Jetzt prüfen wir den Index der Karte:
if (i % 2 === 0) drawnCards.push(currCard);
Wenn er gerade ist, legen wir die Karte (ans Ende) des neuen Stapels.
Um den Index prüfen zu können müssen wir ihn vorher deklarieren. Wir ergänzen oben also unsere Deklaration von i
. Der obere Bereich unserer Funktion sieht dann so aus:
const drawnCards: string[] = [];
const remainingDeck = [...deck];
let i = 0; // Deklaration von i hinzufügen
Wenn i
ungerade ist, legen wir die Karte (ans Ende) des Ausgangsstapels:
else remainingDeck.push(currCard);
Und jetzt noch i
:
i++;
}
Zum Schluss noch unser Ergebnis zurückgeben:
return drawnCards;
};
Voilá! 💪
Komplettlösung
export const draw = (deck: string[]): string[] => {
const drawnCards: string[] = [];
const remainingDeck = [...deck];
let i = 0;
while (remainingDeck.length) {
const currCard = remainingDeck.shift()!;
if (i % 2 === 0) drawnCards.push(currCard);
else remainingDeck.push(currCard);
i++;
}
return drawnCards;
};