Lettres, bouge!

35

Étant donné une chaîne, vous devez déplacer chaque lettre (à partir de la première lettre) de sa position dans l'alphabet. Si vous atteignez la fin de la chaîne, vous devez vous envelopper. Les non-lettres n'ont pas besoin d'être déplacées.

Exemple:

Dog

Dest la quatrième lettre de l’alphabet, nous la déplaçons donc de quatre points à droite. Après avoir terminé, cela change la chaîne en oDg. oest la 15ème lettre, (15 mod 3) = 0, donc elle ne bouge pas. gest la 7ème lettre - (7 mod 3) = 1, ainsi la chaîne devient goD.

hi*bye

  • hest la 8ème lettre, déplacez-la de 8 points - hi*bye=>i*hbye
  • iest la 9ème lettre, déplacez-la 9 places - i*hbye=>*hbiye
  • best la 2e lettre, déplacez-la de 2 points - *hbiye=>*hiybe
  • yest la 25ème lettre, déplacez-la de 25 points - *hiybe=>*hibye
  • eest la 5ème lettre, déplacez-la de 5 points - *hibye=>*hibey

Les non-lettres n'ont pas besoin d'être déplacées, mais elles prennent toujours de la place.

  • cat => tca
  • F.U.N => .F.NU
  • mississippi => msiisppssii
geokavel
la source
Devons-nous faire un programme autonome ou une fonction suffit? Aussi, devons-nous imprimer la chaîne?
Katenkyo
Quels caractères peuvent apparaître dans l'entrée? ASCII imprimable? Des sauts de ligne? Tout ASCII? Unicode?
Martin Ender
3
Aussi, un cas de test avec des lettres répétées serait bien.
Martin Ender
@Martin N'importe quel ASCII.
geokavel
La fonction @Katenkyo est autorisée. Si vous utilisez une fonction, la sortie est la valeur de retour.
geokavel

Réponses:

6

CJam, 44 42 40 octets

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

La sortie contient un retour à la ligne final.

Testez-le ici.

Explication

Au lieu de déplacer les lettres dans la chaîne, j'enlève à plusieurs reprises une lettre, la fais pivoter en conséquence, puis je réinsère la lettre. Il y a un problème pour cela: nous devons pouvoir distinguer le début de la chaîne de la fin de la chaîne (ce qui n'est pas possible après une simple rotation). C'est pourquoi nous insérons un saut de ligne à la fin en guise de garde (lettre avant le saut de ligne est la fin de la chaîne, lettre après le début). Le bonus est que cela ramène automatiquement la dernière chaîne à la bonne rotation où le saut de ligne se situe réellement à la fin de la chaîne.

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.

Pour voir pourquoi cela aboutit dans la bonne position, considérons la dernière itération de l' hi*byeexemple. Après avoir traité le e, la chaîne énumérée se trouve dans cette position:

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

Tout d'abord, nous divisons autour du saut de ligne et concaténons les parties dans l'ordre inverse:

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

Le saut de ligne serait maintenant soit au début ou à la fin de cette chaîne. Mais comme le saut de ligne est juste un garde qui marque la fin de la chaîne, cela signifie que les caractères sont en fait dans le bon ordre. Maintenant, le saut de ligne n'est pas une lettre, de sorte que le tableau ne subit aucune rotation. Ainsi, lorsque nous ajoutons le saut de ligne, il se place là où il se trouve et tout est dans l'ordre que nous recherchons:

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

Quelques résultats supplémentaires si quelqu'un souhaite comparer des cas de test plus longs:

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

J'aime ce dernier. :)

Martin Ender
la source
Pyth a besoin d'une liste de hachage sur la liste.
isaacg
@isaacg Nah, je suis sûr que ce n'est pas le cas. ;)
Martin Ender
Pourriez-vous faire en sorte qu'il prenne en charge les chaînes multilignes?
geokavel
@geokavel Oh oui, corrigé.
Martin Ender
Le sith est ravi, Dark Büttner.
geokavel
4

Ruby 125 130 132 139 octets

->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*''}

Démo en ligne avec tests: http://ideone.com/GYJm2u

L'initiale (version non-golfée): http://ideone.com/gTNvWY

Edit: Un grand merci à manatwork pour ses suggestions!

Edition 2 : nombre de caractères fixe (je comptais initialement les fins de ligne CRLF.)

Cristian Lupascu
la source
Juste à peine testé: c.upcase.ord-64c.ord%32.
manatwork
@manatwork Cela fonctionne bien, merci!
Cristian Lupascu
En regardant encore… Attends! a.join??? Qui es-tu et qu'as-tu fait de w0lf? Il l'écrirait certainement comme a*''.
manatwork
@manatwork :) J'étais tellement contrarié d'avoir un while ... endcode dans mon code que j'ai oublié de le faire. Merci d'avoir remarqué!
Cristian Lupascu
ne pouvez-vous pas transformer cela while ... enden (...)while ...?
Martin Ender
3

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

Je devrais vraiment mieux jouer au golf , mais voici ma solution, merci à katenkyo pour son aide en matière de logique et à Cyoce et Mego pour leur aide en matière de golf.

Edit: Enfin, je l'ai réduit à une déclaration de comparaison. COURTISER! (Et oui, je pourrais le déplacer z=-zen a,m=m,abits, mais cela ne sauve pas les octets et cela brouille le code plus que je ne le pensais nécessaire)

Edit: Le nombre d'octets était désactivé.

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
la source
Je * crois * que cela p[j][0]peut être réduit en fixant J=p[j];au début, puis en remplaçant les occurrences de p[j][0]avecP[0]
Cyoce
@Cyoce Je pense que le problème, c'est que je dois éditer pdirectement, et non une variable qui l'avait p[j]affectée. De plus, si vous examinez l'historique de mes révisions, j'avais une variable k = p[j][0]pour les a<=k<=mcomparaisons, mais il s'est avéré que l'abandon kétait préférable, car j'avais sauvegardé plus d'octets sur les retraits de la ligne supplémentaire à définir kqu'en utilisant k.
Sherlock9