13
\$\begingroup\$

Across the alphabet

In this challenge, you have trouble remembering the letters of the alphabet. To circumvent this, you go up and down the alphabet, till you get to the letter.

Because you want your code to be portable, you'll be writing it with letter blocks. You have a limited amount of letter blocks because most of them got stolen so you need to make sure your code is as short as possible.

Examples

Input / Output pairs are separated by a blank line:

Ac
ABc
Ad
ABcd
fA
fedCBA
adB
abcdcB
Hello, World!
HGfefghijkllmno, WVUTSrqpopqrqponmlkjihgfed!

Challenge

Your goal is to chain adjacent letters with all the intermediate letters of the alphabet (A-Za-z) between them. If capitalization differs, the capitalization should be transformed in the middle. If capitalization cannot be evenly transformed in the middle, it broken up after the middle. If a character isn't an alphabetical character, no transformation should be done.

Winning

This is so shortest code in bytes wins!

-10% Bonus: if your code chains digits

rydwolf
19.3k2 gold badges90 silver badges180 bronze badges
asked Nov 7, 2015 at 20:50
\$\endgroup\$
17
  • 1
    \$\begingroup\$ What do you mean by letter blocks? \$\endgroup\$ Commented Nov 7, 2015 at 21:38
  • \$\begingroup\$ @LegionMammal978 Letter blocks. Not really relevant to the challenge, just a random reason I came up with for short code \$\endgroup\$ Commented Nov 7, 2015 at 21:40
  • \$\begingroup\$ Okay, just wondering if you meant restricted-source. \$\endgroup\$ Commented Nov 7, 2015 at 21:41
  • \$\begingroup\$ By your rules, dont you think adB should transform to abcdCB because c is in the middle of d and b. \$\endgroup\$ Commented Nov 7, 2015 at 22:02
  • \$\begingroup\$ Pretty similar to my Alphabet Between Encryption, but this already has twice the votes so I'll just flag mine. \$\endgroup\$ Commented Nov 9, 2015 at 7:38

5 Answers 5

4
+100
\$\begingroup\$

Pyth, 40 bytes

+sm?-rdZGhd+hdsrVc2jktr.*rdZm!}kGd.:z2ez

Try it online.

answered Nov 16, 2015 at 6:06
\$\endgroup\$
2
\$\begingroup\$

Python 2, (削除) 303 (削除ここまで) (削除) 291 (削除ここまで) (削除) 288 (削除ここまで) (削除) 282 (削除ここまで) (削除) 276 (削除ここまで) (削除) 261 (削除ここまで) 253 bytes

This is a completely different algorithm than Hannes Karppila's, and after lots of golfing, I've managed a substantial improvement in length. I think this algorithm might allow for one of the shortest codes in other languages too, especially languages with do-while loops and built-in signum functions. Suggestions for further improvement welcome. (Something tells me that whole inner loop should be rewritten as a list comprehension.)

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))
answered Nov 16, 2015 at 7:43
\$\endgroup\$
1
\$\begingroup\$

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)

Usage

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

Explanation

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
)
answered Nov 9, 2015 at 12:47
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Using \w will fail with digits. Try '09' \$\endgroup\$ Commented Nov 9, 2015 at 14:35
  • \$\begingroup\$ Save 1 char using charCodeAt() with no argument \$\endgroup\$ Commented Nov 9, 2015 at 21:45
  • \$\begingroup\$ And save 2 chars avoiding Math.abs a>b?a-b:b-a ... and there are more other 'standard' tricks to shorten javascript. With your interpolation method you could beat my score. Check the hints in this site \$\endgroup\$ Commented Nov 9, 2015 at 22:26
  • \$\begingroup\$ codegolf.stackexchange.com/questions/2682/… codegolf.stackexchange.com/questions/37624/… \$\endgroup\$ Commented Nov 9, 2015 at 22:33
  • \$\begingroup\$ Thanks for the info! I'm still getting the hang of code golf. :) \$\endgroup\$ Commented Nov 11, 2015 at 1:25
1
\$\begingroup\$

JavaScript ES6, 168 (186-10%) (削除) 176 193 (削除ここまで)

Edit Modified to get the 10% bonus

Test running the snippet below using an EcmaScript 6 compliant browser (I use 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>

answered Nov 9, 2015 at 15:07
\$\endgroup\$
0
\$\begingroup\$

Python 2, 349 bytes

It's way too long, but at least it's first.

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
answered Nov 9, 2015 at 7:33
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.