Code Golf - Word Scrambler

Please respond with the shortest possible source code for a program that converts arbitrary plaintext to the corresponding ciphertext, following the input and output examples below. Bonus points * for the least processor time or the smallest amount of memory used.

Example 1:

Plain text: A quick brown fox jumps over a lazy dog. Supercalifragilisticexpialidocious!

Ciphertext : eTh kiquc nobrw xfo smjup rvoe eth yalz.odg! uioiapeislgriarpSueclfaiitcxildcos

Example 2:

Plain text: 123 1234 12345 123456 1234567 12345678 123456789

Ciphertext : 312 4213 53124 642135 7531246 86421357 975312468

Rules:

  • Punctuation is defined as being included in the number to which it is closest.
  • The center of a word is defined as the ceiling ((strlen (word) +1) / 2).
  • Spaces are ignored (or flushed).
  • Odd words first move to the right. Even the words first move to the left.

You can think of it as reading every other character backward (starting at the end of a word), followed by the rest of the characters ahead. Corporation => XoXpXrXtXoX => niaorCoprto.

Thanks to those who pointed out inconsistencies in my description. This has led many of you to the wrong path from which I apologize. Rule number 4 should fix the problem.

* Bonus points will only be awarded when Jeff Atwood decides to do so. Since I did not check it, the chances are small. Unfortunately.

+4
source share
10 answers

Python 50 characters

To enter in i :

 ' '.join(x[::-2]+x[len(x)%2::2]for x in i.split()) 

An alternative version that processes its own IO:

 print ' '.join(x[::-2]+x[len(x)%2::2]for x in raw_input().split()) 

A total of 66 characters, including spaces. (Technically, print can be omitted at startup from the command line, as the evaluated code value is displayed as default output.)


Alternative option with reduce :

 ' '.join(reduce(lambda x,y:y+x[::-1],x) for x in i.split()) 

59 characters.

The original version (both even and odd at the beginning) for input to i :

 ' '.join(x[::2][::-1]+x[1::2]for x in i.split()) 

48 characters, including spaces.

Another alternative version, which (although slightly longer) is slightly more efficient:

 ' '.join(x[len(x)%2-2::-2]+x[1::2]for x in i.split()) 

(53 characters)

+7
source

J , 58 characters

 >,&.>/({~(,~(>:@+:@ i.@- @<.,+:@ i.@ >.)@-:)@<:@#)&.><;.2,&' ' 
+4
source

Haskell 64 characters

 unwords.map(map snd.sort.zip(zipWith(*)[0..]$cycle[-1,1])).words 

Good, good, 76 if you add the required " import List ".

+4
source

Python - 69 characters

(including spaces and line breaks)

This handles all I / O operations.

 for w in raw_input().split(): o="" for c in w:o=c+o[::-1] print o, 
+3
source

Perl, 78 characters

To enter in $_ . If this is unacceptable, add six characters for $_=<>; or $_=$s; at the beginning. The new line is read-only.

 for(split){$i=length;print substr$_,$i--,1,''while$i-->0; print"$_ ";}print $/ 
+1
source

Lua

130 char function, 147 char functioning program

Lua does not have enough love for code golf - perhaps because it is difficult to write a short program when you have long keywords, such as function / end , if / then / end , etc.

First, I write the function in a detailed way with explanations, then I rewrite it as a compressed, stand-alone function, then I call this function with the only argument specified on the command line.

I had to format the code with <pre></pre> tags because Markdown does a terrible job of formatting Lua.

Technically, you can get a smaller working program by inserting a function into it, but it is more modular :)

  t = "The quick brown fox jumps over the lazy dog. Supercalifragilisticexpialidocious!"
 T = t: gsub ("% S +", - for each word in t ...
                   function (w) - argument: current word in t
                     W = "" - initialize new Word
                     for i = 1, # w do - iterate over each character in word
                         c = w: sub (i, i) - extract current character
                         - determine whether letter goes on right or left end
                         W = (#w% 2 ~ = i% 2) and W .. c or c .. W
                     end
                     return W - swap word in t with inverted Word
                   end)


 - code-golf unit test
 assert (T == "eTh kiquc nobrw xfo smjup rvoe eth yalz .odg! uioiapeislgriarpSueclfaiitcxildcos")

 - need to assign to a variable and return it,
 - because gsub returns a pair and we only want the first element
 f = function (s) c = s: gsub ("% S +", function (w) W = "" for i = 1, # w do c = w: sub (i, i) W = (# w% 2 ~ = i% 2) and W ..c or c ..W end return W end) return c end
 - 1 2 3 4 5 6 7 8 9 10 11 12 13
 --34567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
 - 130 chars, compressed and written as a proper function

 print (f (arg [1]))
 --34567890123456
 - 16 (+1 whitespace needed) chars to make it a functioning Lua program, 
 - operating on command line argument

Output:

  $ lua insideout.lua 'The quick brown fox jumps over the lazy dog.  Supercalifragilisticexpialidocious! '
 eTh kiquc nobrw xfo smjup rvoe eth yalz .odg! uioiapeislgriarpSueclfaiitcxildcos

I'm still pretty new to Lua, so I would like to see a shorter solution, if any.


For minimal encryption for all stdin arguments, we can do 111 characters:
  for _, w in ipairs (arg) do W = "" for i = 1, # w do c = w: sub (i, i) W = (# w% 2 ~ = i% 2) and W ..c or c ..W end io.write (W .. '') end

But this approach brings out a finite space similar to some other solutions.

+1
source

C, 140 characters

Beautifully formatted:

 main(c, v) char **v; { for( ; *++v; ) { char *e = *v + strlen(*v), *x; for(x = e-1; x >= *v; x -= 2) putchar(*x); for(x = *v + (x < *v-1); x < e; x += 2) putchar(*x); putchar(' '); } } 

Compressed:

 main(c,v)char**v;{for(;*++v;){char*e=*v+strlen(*v),*x;for(x=e-1;x>=*v;x-=2)putchar(*x);for(x=*v+(x<*v-1);x<e;x+=2)putchar(*x);putchar(32);}} 
+1
source

To enter in s :

 f=lambda t,r="":t and f(t[1:],len(t)&1and t[0]+r or r+t[0])or r " ".join(map(f,s.split())) 

Python, 90 characters, including spaces.

0
source

Bash - 133 if the input to the variable $ w

Pretty

 for x in $w; do z=""; for l in `echo $x|sed 's/\(.\)/ \1/g'`; do if ((${#z}%2)); then z=$z$l; else z=$l$z; fi; done; echo -n "$z "; done; echo 

Compressed

 for x in $w;do z="";for l in `echo $x|sed 's/\(.\)/ \1/g'`;do if ((${#z}%2));then z=$z$l;else z=$l$z;fi;done;echo -n "$z ";done;echo 

Ok, so it outputs the finite space.

0
source

TCL

125 characters

 set s set f foreach l {} $fw [gets stdin] {$sr {} $fc [split $w {}] {$sr $c[string reverse $r]} $sl "$l $r"} puts $l 
0
source

All Articles