Lettere, muoviti!


35

Data una stringa devi spostare ogni lettera (a partire dalla prima lettera) in base alla sua posizione nell'alfabeto. Se raggiungi la fine della stringa, devi avvolgerla. Non è necessario spostare le non lettere.

Esempio:

Dog

Dè la quarta lettera dell'alfabeto, quindi la spostiamo di quattro punti a destra. Dopo averlo spostato, cambia la stringa in oDg. oè la 15a lettera, (15 mod 3) = 0, quindi non si muove. gè la 7a lettera - (7 mod 3) = 1, quindi la stringa diventa goD.

hi*bye

  • hè l'ottava lettera, spostala di 8 punti - hi*bye=>i*hbye
  • iè la nona lettera, spostala di 9 punti - i*hbye=>*hbiye
  • bè la seconda lettera, spostala di 2 punti - *hbiye=>*hiybe
  • yè la 25a lettera, spostala di 25 punti - *hiybe=>*hibye
  • eè la 5 ° lettera, spostala di 5 punti - *hibye=>*hibey

Non è necessario spostare le non lettere, ma occupano comunque spazio.

  • cat => tca
  • F.U.N => .F.NU
  • mississippi => msiisppssii

Dobbiamo fare un programma autonomo o una funzione è sufficiente? Inoltre, dobbiamo stampare la stringa?
Katenkyo,

Quali caratteri possono apparire nell'input? ASCII stampabile? Linefeeds? Qualche ASCII? Qualche Unicode?
Martin Ender,

3
Anche un caso di test con lettere ripetute sarebbe buono.
Martin Ender,

@Martin Any ASCII.
geokavel,

La funzione @Katenkyo è consentita. Se si utilizza una funzione, l'output è il valore restituito.
geokavel,

Risposte:


6

CJam, 44 42 40 byte

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

L'output contiene un avanzamento riga finale.

Provalo qui.

Spiegazione

Invece di spostare le lettere attraverso la stringa, rimuovo ripetutamente una lettera, ruoto di conseguenza la stringa e quindi reinserisco la lettera. C'è un trucco per farlo: dobbiamo essere in grado di distinguere l'inizio della stringa dalla fine della stringa (cosa che non possiamo dopo una semplice rotazione). Ecco perché inseriamo un avanzamento di riga alla fine come guardia (la lettera prima dell'alimentazione di riga è la fine della stringa, la lettera dopo che è l'inizio). Il vantaggio è che questo restituisce automaticamente la stringa finale alla rotazione corretta in cui l'avanzamento è effettivamente alla fine della stringa.

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.

Per capire perché questo finisce nella giusta posizione, considera l'ultima iterazione hi*byedell'esempio. Dopo aver elaborato il e, la stringa enumerata è in questa posizione:

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

Innanzitutto, ci dividiamo attorno all'alimentazione di linea e concateniamo le parti in ordine inverso:

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

L'alimentazione di linea ora sarebbe all'inizio o alla fine di questa stringa. Ma poiché il linefeed è solo una guardia che segna la fine della stringa, ciò significa che i personaggi sono effettivamente nell'ordine giusto. Ora il linefeed non è una lettera, quindi l'array non viene ruotato affatto. Pertanto, quando aggiungiamo l'alimentazione di linea, va dove appartiene e tutto è nell'ordine che stiamo cercando:

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

Alcuni risultati aggiuntivi se qualcuno vuole confrontare casi di test più lunghi:

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

Mi piace l'ultimo. :)


Pyth ha bisogno di tagliare l'elenco sulla lista.
isaacg,

@isaacg Nah, sono sicuro che non lo è. ;)
Martin Ender,

Potresti farlo in modo che supporti stringhe multilinea?
geokavel,

@geokavel Oh giusto, riparato.
Martin Ender,

Il sith è contento, Darth Büttner.
geokavel,

4

Rubino 125 130 132 139 byte

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

Demo online con test: http://ideone.com/GYJm2u

La versione iniziale (versione non modificata): http://ideone.com/gTNvWY

Modifica: un grande grazie all'opera d' arte per i suoi suggerimenti!

Modifica 2 : conteggio caratteri fisso (inizialmente stavo contando i finali di riga CRLF).


Appena provato: c.upcase.ord-64c.ord%32.
arte

@manatwork Funziona bene, grazie!
Cristian Lupascu,

Guardando di nuovo ... Aspetta! a.join??? Chi sei e cosa hai fatto con w0lf? Lo scriverebbe sicuramente come a*''.
arte

@manatwork :) Ero così arrabbiato di avere un while ... endnel mio codice che mi sono dimenticato di farlo. Grazie per averlo notato!
Cristian Lupascu,

non puoi trasformarlo while ... endin (...)while ...?
Martin Ender,

3

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

Dovrei davvero giocare a golf meglio, ma ecco la mia soluzione, grazie a Katenkyo per il suo aiuto con la logica e a Cyoce e Mego per il loro aiuto con il golf.

Modifica: Alla fine, ho ottenuto una dichiarazione di confronto. CORTEGGIARE! (E sì, potrei spostarlo z=-zin a,m=m,abit, ma ciò non salva byte e ha confuso il codice più di quanto pensassi fosse necessario)

Modifica: il conteggio dei byte era disattivato.

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())

* Credo * che p[j][0]può essere ridotto impostando J=p[j];all'inizio, quindi sostituendo le istanze di p[j][0]conP[0]
Cyoce

@Cyoce Penso che il problema sia che devo modificare pdirettamente, e non una variabile che gli era stata p[j]assegnata. Inoltre, se osservi la mia cronologia delle revisioni, avevo una variabile k = p[j][0]per i a<=k<=mconfronti, ma si è scoperto che il calo kera migliore perché ho salvato più byte sui rientri dalla riga aggiuntiva da impostare krispetto a quelli salvati utilizzando k.
Sherlock9,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.