Finden Sie den kürzesten Swype-Pfad

12

Einführung

In letzter Zeit habe ich mich daran gewöhnt, mit Swype zu tippen .

Ich habe bemerkt, dass bestimmte Wörter erzeugt werden können, indem eine gerade Linie vom Anfangsbuchstaben zum Endbuchstaben gezogen wird oder indem Buchstaben, die sich wiederholen, übersprungen werden.

Zum Beispiel kann ich das Wort ballooneingeben, indem ich über die folgenden Buchstaben tippe:

b> a> l> o> n.

Herausforderung

Definieren wir den kürzesten Swype-Pfad oder SSPdie Mindestanzahl unterscheidbarer Liniensegmente, die zum Eingeben einer Zeichenfolge erforderlich sind. Ein Liniensegment ist eine durchgehende gerade Linie zwischen zwei oder mehr Buchstaben. Bei jeder Richtungsänderung wird ein neues Liniensegment erstellt. Einige Wörter können jedoch durch Ziehen einer einzelnen geraden Linie vertauscht werden.

Verwenden Sie dieses einfache QWERTZ- Tastaturlayout:

q w e r t y u i o p
a s d f g h j k l
  z x c v b n m

In dem obigen Beispiel wird das Wort balloonwird eine hat SSPvon 4so detailliert in der folgenden Reihenfolge:

1) Start at `b` (line segments = 0)
2) slide to `a` (line segments = 1)
3) slide to `l` (line segments = 2)
4) slide to `o` (line segments = 3)
5) slide to `n` (line segments = 4)

Die Zeichenfolge qwertyhat SSP= 1, da beim Swippen dieses Wortes keine Richtungsänderung erforderlich ist.

Eingang

Eine einzelne Wortfolge, die a-züber STDIN, ein Funktionsargument oder eine Befehlszeile eine beliebige Zeichenfolge enthält .

Ausgabe

Drucken Sie über STDOUT, return oder die nächstgelegene Alternative Ihrer Sprache, wobei die Zahl ndie Zeichenfolge darstellt SSP.

Eine abschließende Newline optional in outut. Standardlücken sind nicht erlaubt. Kürzeste Einreichung in Bytes gewinnt.

Anmerkungen

  • Ein Richtungswechsel startet ein neues Liniensegment.
  • Buchstaben, die sich wiederholen, werden nur einmal gezählt (zB: bookkeepersollten als behandelt werden bokeper).
  • Normalerweise korrigiert Swpye fehlende Buchstaben, indem es benachbarte Buchstaben ansieht und die bestmögliche Schätzung eingibt. Nehmen Sie für diese Herausforderung an, dass es keine natürlichen Spracherweiterungen, Textvorhersagen oder Fehlerkorrekturen gibt.
  • A-ZEingaben in Großbuchstaben werden wie ihre Gegenstücke in Kleinbuchstaben behandelt.
  • Ignorieren Sie alle Zahlen 0-9in der Eingabe.
  • Diagonal Pfade erlaubt - das heißt, eine gerade Linie, die Abdeckungen Buchstaben o, k, n, beispielsweise als zählen 1Segment. Diese Regel gilt auch für alle diagonalen Neigung (zB Buchstaben c, h, isind in Zeile).

Beispiele

Input          Output
---------------------
a                0
aa               0
aaaaaa           0
aaaaaabc         2
in               1
int              2
java             3
qwerty           1
chicago          5
balloon          4
BALLOON          4
typewriter       5
bookkeeper       6
stackexchange    11
2hello7          3
2HELLO7          3
CzarMatt
quelle
h ist auf der Linie von c nach i, aber es gibt keine Buchstaben zwischen c und o?
Sparr
Wenn die Einsendungen auch Großbuchstaben unterstützen müssen, schlage ich vor, einige in die Testfälle aufzunehmen.
Dennis
@ Sparr Richtig.
CzarMatt
@Dennis Guter Anruf - Testfälle hinzugefügt.
CzarMatt
Ich schreibe gerne mit Swype, aber ich weiß nicht, wie man die Zeilen programmiert ...
mbomb007

Antworten:

8

CJam, 78 76 73 68 62 Bytes

relA,s-:_2ew{:-},{{i"x8LÑejPG ÀÏi"225b28b=A+Ab}/.-:ma}%e`,

Beachten Sie, dass der Code nicht druckbare Zeichen enthält.

Die clevere Idee von Borrowing @ isaacg, RLE zu verwenden, um die 6 Bytes gespeicherten Pfade zu zählen.

Probieren Sie es online im CJam-Interpreter aus . Wenn der Link nicht funktioniert, kopieren Sie den Code aus dieser Paste .

Wie es funktioniert

rel      e# Read a token from STDIN and cast it to lowercase.
A,s-     e# Remove all digits.
:_       e# Duplicate each element of the argument (string/array).
2ew      e# Push all overlapping slices of length 2.
{:-},    e# Filter out slices where both elements are equal.
{        e# For each slice:
  {      e#   For each character of the slice:
    i    e#     Push its code point.

    "x8LÑejPG ÀÏi"225b28b

         e#     Convert the string from base 225 to base 28, pushing the array
         e#     [15 7 16 17 18 27 26 8 9 0 3 11 4 6 24 1 22 5 21 10 25 23 12 2 13 14].
         e#     These are the positions on the QWERTY keyboard, starting from the
         e#     upper left corner and going right.

    =    e#     Select the element that corresponds to the code point.

         e#     Arrays wrap around in CJam. Since 'a' has code point 97, the array has
         e#     length 26 and 97 % 26 == 19, 'a' corresponds to the 20th element.

    A+Ab e#     Add 10 and convert to base 10. Example: 8 -> [1 8]
  }/     e#
  .-     e#     Vectorized subtraction. [a b] [c d] -> [a-c b-d]
  :ma    e#     atan2. Pushes the angle of the direction. [y x] -> arctan(y/x)
}%       e#
e`       e# Apply run-length encoding.
,        e# Count the runs.
Dennis
quelle
Sehr schlau. Vielen Dank für die Erklärung.
CzarMatt
3

Pyth, 53 50 49 Bytes

lrPMfT-VJm.jF.D@jC"XÖ;¿ìÇ×;¤ð$  _"28CdT@GrzZtJ8

Tastaturkomprimierungsformat dank @Dennis.

Diese Antwort enthält einige nicht druckbare Zeichen. Den richtigen Code finden Sie unter den folgenden Links.

Vorführung . Testgeschirr.

Erläuterung:

lrPMfT-VJm.jF.D@jC"..."28CdT@GrzZtJ8
                              rzZ      Convert input to lowercase.
                            @G         Take the intersection with G.
                                       This removes the numbers.
         m                             Map over the characters
                 C"..."                Treat the string as a base 256 number.
                j      28              Convert this number to base 28, giving:
                                       [15, 7, 16, 17, 18, 27, 26,  ... ]
                                       which is the character positions 
                                       from top left, rotated by 97 places.
               @         Cd            Index this list by ord(character)
             .D            T           divmod by 10, giving the x-y position.
          .jF                          Convert this to a complex number.
        J                              Save the result to J.
      -VJ                        tJ    Vectorize - over J and J[1:]. This gives
                                       pairwise diffeences between J's elements.
    fT                                 Filter the differences on being truthy.
                                       This removes letter pairs with no movement.
  PM                                   Map the remaining complex numbers to their
                                       phases, which indicates their directions.
 r                                 8   Run-length encode the result.
l                                      Print out the number of separate RLE groups.
isaacg
quelle
Über 20% kürzer! Ich freue mich auf Ihre Erklärung.
Dennis