Do outro lado do alfabeto

14

Do outro lado do alfabeto

Neste desafio, você tem problemas para lembrar as letras do alfabeto. Para contornar isso, você sobe e desce o alfabeto até chegar à letra.

Como você deseja que seu código seja portátil, você o escreverá com blocos de letras. Você tem uma quantidade limitada de blocos de letras porque a maioria deles foi roubada; portanto, você precisa garantir que seu código seja o mais curto possível.

Exemplos

Os pares de entrada / saída são separados por uma linha em branco:

Ac
ABc

Ad
ABcd

fA
fedCBA

adB
abcdcB


Hello, World!
HGfefghijkllmno, WVUTSrqpopqrqponmlkjihgfed!

Desafio

Seu objetivo é encadear letras adjacentes com todas as letras intermediárias do alfabeto ( A-Za-z) entre elas. Se a capitalização diferir, a capitalização deve ser transformada no meio. Se a capitalização não pode ser uniformemente transformada no meio, ela se desfaz após o meio. Se um personagem não é um caracter alfabético, nenhuma transformação deve ser feita.

Ganhando

Este é o pelo que o código mais curto em bytes vence!

-10% Bônus: se o seu código vincular dígitos

Downgoat
fonte
1
O que você quer dizer com blocos de letras?
precisa
@ LegionMammal978 Blocos de letra . Não é realmente relevante para o desafio, apenas uma razão aleatória eu vim com para o código curto
Downgoat
Ok, estou me perguntando se você quis dizer fonte restrita .
precisa
Pelas suas regras, você não acha que adBdeve se transformar em abcdCBporque c está no meio de d e b.
geokavel
Muito parecido com o meu alfabeto entre criptografia , mas isso já tem o dobro dos votos, então vou sinalizar o meu.
fase

Respostas:

2

Python 2, 303 291 288 282 276 261 253 bytes

Esse é um algoritmo completamente diferente do de Hannes Karppila e, depois de muito golfe, consegui uma melhora substancial no comprimento. Eu acho que esse algoritmo também pode permitir um dos códigos mais curtos em outros idiomas, especialmente idiomas com loops do-while e funções de signum internas. Sugestões para melhorias adicionais são bem-vindas. (Algo me diz que todo o loop interno deve ser reescrito como uma compreensão da lista.)

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))
quintopia
fonte
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!"

Explicação

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
)
user81655
fonte
1
O uso \wfalhará com dígitos. Tente '09'
edc65
Salve 1 char usando charCodeAt () sem argumento
edc65 9-15
E salve 2 caracteres evitando o Math.abs a>b?a-b:b-a... e existem outros truques 'padrão' para reduzir o javascript. Com o seu método de interpolação, você pode bater minha pontuação. Verifique as dicas neste site
edc65
Obrigado pela informação! Eu ainda estou pegando o jeito do código de golfe. :)
user81655
1

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

Editar Modificado para obter o bônus de 10%

Teste a execução do trecho abaixo usando um navegador compatível com EcmaScript 6 (eu uso o 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
fonte
0

Python 2, 349 bytes

É muito longo, mas pelo menos é o primeiro.

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
fonte