Briefe, beweg dich!

35

Bei einer gegebenen Zeichenfolge müssen Sie jeden Buchstaben (beginnend mit dem ersten Buchstaben) um seine Position im Alphabet verschieben. Wenn Sie das Ende der Zeichenfolge erreichen, müssen Sie sich umschließen. Nicht-Buchstaben müssen nicht verschoben werden.

Beispiel:

Dog

Dist der vierte Buchstabe des Alphabets, also verschieben wir ihn um vier Stellen nach rechts. Nach dem Umbrechen ändert sich die Zeichenfolge in oDg. oist der 15. Buchstabe, (15 mod 3) = 0, bewegt sich also nicht. gist der 7. Buchstabe - (7 mod 3) = 1, so wird die Zeichenfolge goD.

hi*bye

  • hist der 8. Buchstabe, verschiebe ihn um 8 Stellen - hi*bye=>i*hbye
  • iist der 9. Buchstabe, verschiebe ihn um 9 Stellen - i*hbye=>*hbiye
  • bist der 2. Buchstabe, verschiebe ihn um 2 Stellen - *hbiye=>*hiybe
  • yist der 25. Buchstabe, verschiebe ihn um 25 Stellen - *hiybe=>*hibye
  • eist der 5. Buchstabe, verschiebe ihn um 5 Stellen - *hibye=>*hibey

Nicht-Buchstaben müssen nicht verschoben werden, beanspruchen aber dennoch Speicherplatz.

  • cat => tca
  • F.U.N => .F.NU
  • mississippi => msiisppssii
Geokavel
quelle
Müssen wir ein eigenständiges Programm ausführen oder reicht eine Funktion aus? Müssen wir den String auch drucken?
Katenkyo
Welche Zeichen können in der Eingabe erscheinen? Druckbares ASCII? Zeilenvorschub? Beliebiges ASCII? Irgendein Unicode?
Martin Ender
3
Auch ein Testfall mit wiederholten Buchstaben wäre gut.
Martin Ender
@Martin Beliebiges ASCII.
Geokavel
@Katenkyo Funktion ist erlaubt. Wenn Sie eine Funktion verwenden, ist output der Rückgabewert.
Geokavel

Antworten:

6

CJam, 44 42 40 Bytes

qN+ee_{Xa/~\+XW=eu__el=!\'@-*m<Xa+}fXWf=

Die Ausgabe enthält einen nachfolgenden Zeilenvorschub.

Teste es hier.

Erläuterung

Anstatt die Buchstaben durch die Zeichenfolge zu bewegen, entferne ich wiederholt einen Buchstaben, drehe die Zeichenfolge entsprechend und füge den Buchstaben erneut ein. Dafür gibt es einen Haken: Wir müssen in der Lage sein, den Anfang der Zeichenkette vom Ende der Zeichenkette zu unterscheiden (was wir nach einer einfachen Drehung nicht können). Deshalb fügen wir am Ende einen Zeilenvorschub als Guard ein (Buchstabe vor dem Zeilenvorschub ist das Ende der Zeichenkette, Buchstabe nach dem Anfang). Der Bonus ist , dass diese automatisch die letzte Zeichenfolge in die richtige Rotation zurückkehrt , wo der Zeilenvorschub tatsächlich ist am Ende des Strings.

lN+     e# Read input and append a linefeed.
ee      e# Enumerate the array, so input "bob" would become [[0 'b] [1 'o] [2 'b] [3 N]]
        e# This is so that we can distinguish repeated occurrences of one letter.
_{      e# Duplicate. Then for each element X in the copy...
  Xa/   e# Split the enumerated string around X.
  ~     e# Dump the two halves onto the stack.
  \+    e# Concatenate them in reverse order. This is equivalent to rotating the current
        e# character to the front and then removing it.
  XW=   e# Get the character from X.
  eu    e# Convert to upper case.
  _     e# Duplicate.
  _el=! e# Check that convert to lower case changes the character (to ensure we have a
        e# letter).
  \'@-  e# Swap with the other upper-case copy and subtract '@, turning letters into 1 to
        e# 26 (and everything else into junk).
  *     e# Multiply with whether it's a letter or not to turn said junk into 0 (that means
        e# everything which is not a letter will be moved by 0 places).
  m<    e# Rotate the string to the left that many times.
  Xa+   e# Append X to the rotated string.
}fX
Wf=     e# Extract the character from each pair in the enumerated array.

Betrachten Sie die letzte Iteration des hi*byeBeispiels, um festzustellen, warum dies an der richtigen Position endet . Nachdem wir die verarbeitet haben e, befindet sich die aufgezählte Zeichenfolge an der folgenden Position:

[[4 'y] [6 N] [2 '*] [0 'h] [1 'i] [3 'b] [5 'e]]

Zuerst teilen wir uns den Zeilenvorschub auf und verketten die Teile in umgekehrter Reihenfolge:

[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y]]

Der Zeilenvorschub würde sich nun entweder am Anfang oder am Ende dieser Zeichenfolge befinden. Da der Zeilenvorschub jedoch nur ein Wächter ist, der das Ende der Zeichenfolge markiert , bedeutet dies, dass die Zeichen tatsächlich in der richtigen Reihenfolge sind. Jetzt ist der Zeilenvorschub kein Buchstabe, so dass das Array überhaupt nicht gedreht wird. Wenn wir also den Zeilenvorschub anhängen, geht er dahin, wo er hingehört, und alles ist in der Reihenfolge, nach der wir suchen:

[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y] [6 N]]

Einige zusätzliche Ergebnisse, wenn jemand längere Testfälle vergleichen möchte:

Hello, World!
,W oeHlo!lrld

Programming Puzzles & Code Golf
ago fgliPomomnrr elP& uC dezzsG

The quick brown fox jumps over the lazy dog
t eg chbi ko qfTounyzrj omw epx ueoahs rlvd

abcdefghijklmnopqrstuvwxyz
aqbrcdsetfguhivjwklxmnyozp

zyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyz

Ich mag den letzten. :)

Martin Ender
quelle
Pyth braucht Chop List on List.
isaacg
@isaacg Nein, ich bin sicher, dass es nicht so ist. ;)
Martin Ender
Könnten Sie es so machen, dass es mehrzeilige Zeichenfolgen unterstützt?
Geokavel
@geokavel Oh, richtig, behoben.
Martin Ender
Der Sith freut sich, Darth Büttner.
Geokavel
4

Ruby 125 130 132 139 Bytes

->q{a=q.chars.map{|c|[c,c=~/[a-z]/i&&c.ord%32]}
while i=a.index{|c,s|s}
c,s=a.delete_at i
a.insert (i+s)%q.size,[c]
end
a*''}

Online-Demo mit Tests: http://ideone.com/GYJm2u

Die Initiale (ungolfed version): http://ideone.com/gTNvWY

Edit: Vielen Dank an Manatwork für seine Vorschläge!

Edit 2 : feste Zeichenanzahl (Ich habe anfangs CRLF-Zeilenenden gezählt.)

Cristian Lupascu
quelle
Gerade erst getestet: c.upcase.ord-64c.ord%32.
Handarbeit
@manatwork Das funktioniert gut, danke!
Cristian Lupascu
Nochmal schauen ... Warten Sie! a.join??? Wer bist du und was hast du mit w0lf gemacht? Er würde es bestimmt so schreiben a*''.
Handarbeit
@manatwork :) Ich war so verärgert, while ... enddass ich vergessen habe, das zu tun. Danke fürs bemerken!
Cristian Lupascu
können Sie nicht drehen while ... endin (...)while ...?
Martin Ender
3

Python 3, 278 275 273 270 260 258 249 248 243 238 Bytes

Ich sollte das wirklich besser runtergolfen, aber hier ist meine Lösung, danke an runtergolfen katenkyo für seine Hilfe bei der Logik und an Cyoce und Mego für ihre Hilfe beim Golfen.

Edit: Endlich habe ich es auf eine Vergleichsanweisung gebracht. WOO! (Und ja, ich könnte das z=-zin ein a,m=m,aBit verschieben, aber das spart keine Bytes und verwirrt den Code mehr, als ich für notwendig hielt.)

Bearbeiten: Bytezahl war aus.

def m(s):
 l=len(s);r=range(l);p=[[i,s[i]]for i in r]
 for i in r:
  if s[i].isalpha():
   a=p[i][0];p[i][0]=m=(a+ord(s[i])%32)%l;z=1
   if a>m:a,m=m,a;z=-z
   for j in r:p[j][0]-=z*(j!=i)*(a<=p[j][0]<=m) 
 return''.join(dict(p).values())

Ungolfed:

def move(string):
 length = len(string)
 places = [[i,string[i]]for i in range(length)]
 for index in range(length):
  char = string[index]
  if char.isalpha():
   a = places[index][0]
   mov = (a + ord(char)%32) % length
   places[index][0] = mov
   for j in range(length):
    k = places[j][0]
    if a <= k <= mov and j!=index:
     places[j][0]-=1
    elif mov <= k <= a and j != index:
     places[j][0]+=1
 return''.join(dict(places).values())
Sherlock9
quelle
I * glauben *, die p[j][0]durch Einstellung reduziert werden kann J=p[j];am Anfang, dann ersetzt Instanzen p[j][0]mitP[0]
Cyoce
@Cyoce Ich denke, das Problem ist, dass ich pdirekt bearbeiten muss und keine Variable, die dieser p[j]zugewiesen wurde. Wenn Sie sich meinen Revisionsverlauf ansehen, hatte ich zwar eine Variable k = p[j][0]für a<=k<=mVergleiche, aber es stellte sich heraus, dass das Löschen kbesser war, weil ich mehr Bytes an Einzügen aus der zu setzenden zusätzlichen Zeile kals mit gespeichert habe k.
Sherlock9