Al otro lado del alfabeto

14

Al otro lado del alfabeto

En este desafío, tienes problemas para recordar las letras del alfabeto. Para evitar esto, sube y baja el alfabeto hasta llegar a la letra.

Debido a que desea que su código sea portátil, lo escribirá con bloques de letras. Tiene una cantidad limitada de bloques de letras porque la mayoría de ellos fueron robados, por lo que debe asegurarse de que su código sea lo más corto posible.

Ejemplos

Los pares de entrada / salida están separados por una línea en blanco:

Ac
ABc

Ad
ABcd

fA
fedCBA

adB
abcdcB


Hello, World!
HGfefghijkllmno, WVUTSrqpopqrqponmlkjihgfed!

Desafío

Su objetivo es encadenar letras adyacentes con todas las letras intermedias del alfabeto ( A-Za-z) entre ellas. Si la capitalización difiere, la capitalización debe transformarse en el medio. Si la capitalización no se puede transformar uniformemente en el medio, se divide después del medio. Si un personaje no es alfabético, no se debe realizar ninguna transformación.

Victorioso

Este es el código más corto en bytes gana!

-10% de bonificación: si su código encadena dígitos

Downgoat
fuente
1
¿Qué quieres decir con bloques de letras?
LegionMammal978
@ LegionMammal978 Bloques de letras . No es realmente relevante para el desafío, solo una razón aleatoria que se me ocurrió para el código corto
Downgoat
De acuerdo, solo me preguntaba si te referías a una fuente restringida .
LegionMammal978
Según sus reglas, ¿no cree que adBdebería transformarse en abcdCBporque c está en el medio de d y b?
geokavel
Bastante similar a mi Alphabet Between Encryption , pero esto ya tiene el doble de votos, así que solo marcaré el mío.
fase del

Respuestas:

2

Python 2, 303 291 288 282 276 261 253 bytes

Este es un algoritmo completamente diferente al de Hannes Karppila, y después de mucho golf, he logrado una mejora sustancial en la longitud. Creo que este algoritmo también podría permitir uno de los códigos más cortos en otros idiomas, especialmente los idiomas con bucles do-while y funciones de signum incorporadas. Sugerencias para más mejoras bienvenidas. (Algo me dice que todo el ciclo interno debe reescribirse como una lista de comprensión).

l=map(ord,list(raw_input()));f=q=1
while q:
 q=0;m=~-f/2;c=m
 while abs(c)<len(l)-1:
  u=c+f;d=(l[u]-96)%32-(l[c]-96)%32
  if chr(l[c]).isalpha()*chr(l[u]).isalpha()*(d*d>1):l[:u-m]+=[l[c]+d/abs(d)];u+=f;q=1
  c=u
 f=-f
print "".join(map(chr,l))
quintapia
fuente
1

JavaScript (ES6), 198 197 194 bytes

f=s=>(o="",a=u=0,[...s].map(c=>{j=c.toUpperCase();p=j==c;b=j<"A"|j>"Z"?0:j.charCodeAt();for(i=0,m=a<b?b-a:a-b;a&&b&&++i<m;)o+=String.fromCharCode(i*(a<b||-1)+a+32*!(i>m/2?p:u));a=b;u=p;o+=c}),o)

Uso

f("Hello, World!")
=> "HGfefghijkllmno, WVUTSrqpopqrqponmlkjihgfed!"

Explicación

f=s=>(
  o="",                                   // o = output string
  a=                                      // a = previous character code (or 0 if symbol)
    u=0,                                  // u = 1 if previous character was upper-case
  [...s].map(c=>{                         // iterate through each letter of input

    // Get information about the current character
    j=c.toUpperCase();                    // j = current character in upper-case
    p=j==c;                               // p = current character is upper-case
    b=j<"A"|j>"Z"?0:j.charCodeAt();       // b = current character code (or 0 if symbol)

    // Interpolate characters (unless A or B is a symbol)
    for(i=0,m=a<b?b-a:a-b;a&&b&&++i<m;)   // loop for each character between A and B
      o+=String.fromCharCode(             // add interpolated character to output
        i*(a<b||-1)+a+                    // interpolate character code
          32*!(i>m/2?p:u)                 // apply case of the nearest character
      );

    // Set character A values to B for the next character
    a=b;
    u=p;
    o+=c                                  // add B itself to the output

  }),
  o                                       // return the output
)
usuario81655
fuente
1
El uso \wfallará con los dígitos. Prueba '09'
edc65
Ahorre 1 char usando charCodeAt () sin argumento
edc65
Y guarde 2 caracteres evitando Math.abs a>b?a-b:b-a... y hay más otros trucos 'estándar' para acortar JavaScript. Con tu método de interpolación podrías superar mi puntaje. Consulte las sugerencias en este sitio
edc65
Gracias por la info! Todavía me estoy acostumbrando al código golf. :)
user81655
1

JavaScript ES6, 168 (186-10%) 176 193

Editar modificado para obtener el 10% de bonificación

Pruebe a ejecutar el fragmento a continuación utilizando un navegador compatible con EcmaScript 6 (uso FireFox)

f=s=>[...s].map(c=>{a=parseInt(c,36),m=(a-q)/(d=a>q?1:-1);for(n=1;m&&(a>9)==(q>9)&&(q+=d)!=a;n+=2)r=q.toString(36),o+=n<m&p<'a'|n>=m&c<'a'?r.toUpperCase():r;p=c,q=a,o+=c},o='',p=q=-f)&&o

// Explained
U=s=>(
  o = '', // initialize output
  p = '', // provious char, initialize to none
  q = NaN, // previous char code, initialize to none
  [...s].map( c => { // for each char 
    a = parseInt(c,36), // convert digit/letter to numeric code, case invariant, NaN if invalid
    d = a > q ? 1 : -1, // sign of difference (if not equal)
    m = (a - q) / d; // absolute value of difference or NaN 
    if (m && (a>9)==(q>9)) // if current and prev are different and both alpha or both digits  
      for( n = 1; 
          (q += d) != a; // loop from prev char (not included) to current (not included)
           n += 2)
        r=q.toString(36),
        // add intermediate char to output
        // upcase if: left side & prev is upcase or right side and current is upcase
        o+= n<m&p<'a'|n>=m&c<'a'?r.toUpperCase():r;
    p = c, // copy current to previous
    q = a, // copy current to previous
    o += c // add current char to ouput
  }),
  o
)  

// test
console.log=(...x)=>O.innerHTML+=x+'\n'

;['Ac','Ad','fA','adB','04aQ27','Hello World!'].
forEach(x=>console.log(x + ' -> ' + f(x)))
<pre id=O></pre>

edc65
fuente
0

Python 2, 349 bytes

Es demasiado largo, pero al menos es el primero.

f=lambda p:ord(p.lower())
u=lambda p:"".join(p).upper()
s=raw_input()
w=s[0]
r=w
for q in s[1:]:
 o=q+w
 if q==w:o=""
 if o.isalpha():
  m=(f(w)<f(q))*2-1
  e=map(chr,range(f(w)+m,f(q)+m,m))
  if o==u(o):e=u(e)
  elif q==u(q):e[len(e)/2:]=u(e[len(e)/2:])
  elif -o.islower()+1:e[:len(e)/2]=u(e[:len(e)/2])
  r+="".join(e)
 else:
  r+=q
 w=q
print r
Hannes Karppila
fuente