How does the Brainfuck Hello World actually work? - brainfuck

Someone sent this to me and claimed it is a hello world in Brainfuck (and I hope so...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
I know the basics that it works by moving a pointer and increment and decrementing stuff...
Yet I still want to know, how does it actually work? How does it print anything on the screen in the first place? How does it encode the text? I do not understand at all...

1. Basics
To understand Brainfuck you must imagine infinite array of cells initialized by 0 each.
...[0][0][0][0][0]...
When brainfuck program starts, it points to any cell.
...[0][0][*0*][0][0]...
If you move pointer right > you are moving pointer from cell X to cell X+1
...[0][0][0][*0*][0]...
If you increase cell value + you get:
...[0][0][0][*1*][0]...
If you increase cell value again + you get:
...[0][0][0][*2*][0]...
If you decrease cell value - you get:
...[0][0][0][*1*][0]...
If you move pointer left < you are moving pointer from cell X to cell X-1
...[0][0][*0*][1][0]...
2. Input
To read character you use comma ,. What it does is: Read character from standard input and write its decimal ASCII code to the actual cell.
Take a look at ASCII table. For example, decimal code of ! is 33, while a is 97.
Well, lets imagine your BF program memory looks like:
...[0][0][*0*][0][0]...
Assuming standard input stands for a, if you use comma , operator, what BF does is read a decimal ASCII code 97 to memory:
...[0][0][*97*][0][0]...
You generally want to think that way, however the truth is a bit more complex. The truth is BF does not read a character but a byte (whatever that byte is). Let me show you example:
In linux
$ printf ł
prints:
ł
which is specific polish character. This character is not encoded by ASCII encoding. In this case it's UTF-8 encoding, so it used to take more than one byte in computer memory. We can prove it by making a hexadecimal dump:
$ printf ł | hd
which shows:
00000000 c5 82 |..|
Zeroes are offset. 82 is first and c5 is second byte representing ł (in order we will read them). |..| is graphical representation which is not possible in this case.
Well, if you pass ł as input to your BF program that reads single byte, program memory will look like:
...[0][0][*197*][0][0]...
Why 197 ? Well 197 decimal is c5 hexadecimal. Seems familiar ? Of course. It's first byte of ł !
3. Output
To print character you use dot . What it does is: Assuming we treat actual cell value like decimal ASCII code, print corresponding character to standard output.
Well, lets imagine your BF program memory looks like:
...[0][0][*97*][0][0]...
If you use dot (.) operator now, what BF does is print:
a
Because a decimal code in ASCII is 97.
So for example BF program like this (97 pluses 2 dots):
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++..
Will increase value of the cell it points to up to 97 and print it out 2 times.
aa
4. Loops
In BF loop consists of loop begin [ and loop end ]. You can think it's like while in C/C++ where the condition is actual cell value.
Take a look BF program below:
++[]
++ increments actual cell value twice:
...[0][0][*2*][0][0]...
And [] is like while(2) {}, so it's infinite loop.
Let's say we don't want this loop to be infinite. We can do for example:
++[-]
So each time a loop loops it decrements actual cell value. Once actual cell value is 0 loop ends:
...[0][0][*2*][0][0]... loop starts
...[0][0][*1*][0][0]... after first iteration
...[0][0][*0*][0][0]... after second iteration (loop ends)
Let's consider yet another example of finite loop:
++[>]
This example shows, we haven't to finish loop at cell that loop started on:
...[0][0][*2*][0][0]... loop starts
...[0][0][2][*0*][0]... after first iteration (loop ends)
However it is good practice to end where we started. Why ? Because if loop ends another cell it started, we can't assume where the cell pointer will be. To be honest, this practice makes brainfuck less brainfuck.

Wikipedia has a commented version of the code.
+++++ +++++ initialize counter (cell #0) to 10
[ use loop to set the next four cells to 70/100/30/10
> +++++ ++ add 7 to cell #1
> +++++ +++++ add 10 to cell #2
> +++ add 3 to cell #3
> + add 1 to cell #4
<<<< - decrement counter (cell #0)
]
> ++ . print 'H'
> + . print 'e'
+++++ ++ . print 'l'
. print 'l'
+++ . print 'o'
> ++ . print ' '
<< +++++ +++++ +++++ . print 'W'
> . print 'o'
+++ . print 'r'
----- - . print 'l'
----- --- . print 'd'
> + . print '!'
> . print '\n'
To answer your questions, the , and . characters are used for I/O. The text is ASCII.
The Wikipedia article goes on in some more depth, as well.
The first line initialises a[0] = 10 by simply incrementing ten times
from 0. The loop from line 2 effectively sets the initial values for
the array: a[1] = 70 (close to 72, the ASCII code for the character
'H'), a[2] = 100 (close to 101 or 'e'), a[3] = 30 (close to 32, the
code for space) and a[4] = 10 (newline). The loop works by adding 7,
10, 3, and 1, to cells a[1], a[2], a[3] and a[4] respectively each
time through the loop - 10 additions for each cell in total (giving
a[1]=70 etc.). After the loop is finished, a[0] is zero. >++. then
moves the pointer to a[1], which holds 70, adds two to it (producing
72, which is the ASCII character code of a capital H), and outputs it.
The next line moves the array pointer to a[2] and adds one to it,
producing 101, a lower-case 'e', which is then output.
As 'l' happens
to be the seventh letter after 'e', to output 'll' another seven are
added (+++++++) to a[2] and the result is output twice.
'o' is the
third letter after 'l', so a[2] is incremented three more times and
output the result.
The rest of the program goes on in the same way.
For the space and capital letters, different array cells are selected
and incremented or decremented as needed.

Brainfuck
same as its name.
It uses only 8 characters > [ . ] , - + which makes it the quickest programming language to learn but hardest to implement and understand.
….and makes you finally end up with f*cking your brain.
It stores values in array: [72 ][101 ][108 ][111 ]
let, initially pointer pointing to cell 1 of array:
> move pointer to right by 1
< move pointer to left by 1
+ increment the value of cell by 1
- increment the value of element by 1
. print value of current cell.
, take input to current cell.
[ ] loop, +++[ -] counter of 3 counts bcz it have 3 ′+’ before it, and - decrements count variable by 1 value.
the values stored in cells are ascii values:
so referring to above array: [72 ][101 ][108 ][108][111 ]
if you match the ascii values you’ll find that it is Hello writtern
Congrats! you have learned the syntax of BF
——-Something more ———
let us make our first program i.e Hello World, after which you’re able to write your name in this language.
+++++ +++++[> +++++ ++ >+++++ +++++ >+++ >+ <<<-]>++.>+.+++++ ++..+++.++.+++++ +++++ +++++.>.+++.----- -.----- ---.>+.>.
breaking into pieces:
+++++ +++++[> +++++ ++
>+++++ +++++
>+++
>+
<<<-]
Makes an array of 4 cells(number of >) and sets a counter of 10 something like :
—-psuedo code—-
array =[7,10,3,1]
i=10
while i>0:
element +=element
i-=1
because counter value is stored in cell 0 and > moves to cell 1 updates its value by+7 > moves to cell 2 increments 10 to its previous value and so on….
<<< return to cell 0 and decrements its value by 1
hence after loop completion we have array : [70,100,30,10]
>++.
moves to 1st element and increment its value by 2(two ‘+’) and then prints(‘.’) character with that ascii value. i.e for example in python:
chr(70+2) # prints 'H'
>+.
moves to 2nd cell increment 1 to its value 100+1 and prints(‘.’) its value i.e chr(101)
chr(101) #prints ‘e’
now there is no > or < in next piece so it takes present value of latest element and increment to it only
+++++ ++..
latest element = 101 therefore, 101+7 and prints it twice(as there are two‘..’) chr(108) #prints l twice
can be used as
for i in array:
for j in range(i.count(‘.’)):
print_value
———Where is it used?——-
It is just a joke language made to challenge programmers and is not used practically anywhere.

To answer the question of how it knows what to print, I have added the calculation of ASCII values to the right of the code where the printing happens:
> just means move to the next cell
< just means move to the previous cell
+ and - are used for increment and decrement respectively. The value of the cell is updated when the increment/decrement happens
+++++ +++++ initialize counter (cell #0) to 10
[ use loop to set the next four cells to 70/100/30/10
> +++++ ++ add 7 to cell #1
> +++++ +++++ add 10 to cell #2
> +++ add 3 to cell #3
> + add 1 to cell #4
<<<< - decrement counter (cell #0)
]
> ++ . print 'H' (ascii: 70+2 = 72) //70 is value in current cell. The two +s increment the value of the current cell by 2
> + . print 'e' (ascii: 100+1 = 101)
+++++ ++ . print 'l' (ascii: 101+7 = 108)
. print 'l' dot prints same thing again
+++ . print 'o' (ascii: 108+3 = 111)
> ++ . print ' ' (ascii: 30+2 = 32)
<< +++++ +++++ +++++ . print 'W' (ascii: 72+15 = 87)
> . print 'o' (ascii: 111)
+++ . print 'r' (ascii: 111+3 = 114)
----- - . print 'l' (ascii: 114-6 = 108)
----- --- . print 'd' (ascii: 108-8 = 100)
> + . print '!' (ascii: 32+1 = 33)
> . print '\n'(ascii: 10)

All the answers are thorough, but they lack one tiny detail: Printing.
In building your brainfuck translator, you also consider the character ., this is actually what a printing statement looks like in brainfuck. So what your brainfuck translator should do is, whenever it encounters a . character it prints the currently pointed byte.
Example:
suppose you have --> char *ptr = [0] [0] [0] [97] [0]...
if this is a brainfuck statement: >>>. your pointer should be moved 3 spaces to right landing at: [97], so now *ptr = 97, after doing that your translator encounters a ., it should then call
write(1, ptr, 1)
or any equivalent printing statement to print the currently pointed byte, which has the value 97 and the letter a will then be printed on the std_output.

I think what you are asking is how does Brainfuck know what to do with all the code. There is a parser written in a higher level language such as Python to interpret what a dot means, or what an addition sign means in the code.
So the parser will read your code line by line, and say ok there is a > symbol so i have to advance memory location, the code is simply, if (contents in that memory location) == >, memlocation =+ memlocation which is written in a higher level language, similarly if (content in memory location) == ".", then print (contents of memory location).
Hope this clears it up. tc

Related

MATLAB only runs first case in a switch-case block

I am trying to separate data from a csv file into "blocks" of data that I then put into 10 different categories. Each block has a set of spaces at the top of it. Each category contains 660 blocks. Currently, my code successfully puts in the first block, but only the first block. It does correctly count the number of blocks though. I do not understand why it only puts in the first block when the block count works correctly, and any help would be appreciated.
The csv file can be downloaded from here.
https://archive.ics.uci.edu/ml/machine-learning-databases/00195/
fid = fopen('Train_Arabic_Digit.txt','rt');
traindata = textscan(fid, '%f%f%f%f%f%f%f%f%f%f%f%f%f', 'MultipleDelimsAsOne',true, 'Delimiter','[;', 'HeaderLines',1);
fclose(fid);
% Each line in Train_Arabic_Digit.txt or Test_Arabic_Digit.txt represents
% 13 MFCCs coefficients in the increasing order separated by spaces. This
% corresponds to one analysis frame. Lines are organized into blocks, which
% are a set of 4-93 lines separated by blank lines and corresponds to a
% single speech utterance of an spoken Arabic digit with 4-93 frames.
% Each spoken digit is a set of consecutive blocks.
% TO DO: how get blocks...split? with /n?
% In Train_Arabic_Digit.txt there are 660 blocks for each spoken digit. The
% first 330 blocks represent male speakers and the second 330 blocks
% represent the female speakers. Blocks 1-660 represent the spoken digit
% "0" (10 utterances of /0/ from 66 speakers), blocks 661-1320 represent
% the spoken digit "1" (10 utterances of /1/ from the same 66 speakers
% 33 males and 33 females), and so on up to digit 9.
content = fileread( 'Train_Arabic_Digit.txt' ) ;
default = regexp(content,'\n','split');
digit0=[];
digit1=[];
digit2=[];
digit3=[];
digit4=[];
digit5=[];
digit6=[];
digit7=[];
digit8=[];
digit9=[];
blockcount=0;
a=0;
for i=1:1:length(default)
if strcmp(default{i},' ')
blockcount=blockcount+1;
else
switch blockcount % currently only works for blockcount=1 even though
%it does pick up the number of blocks...
case blockcount>0 && blockcount<=660 %why does it not recognize 2 as being<660
a=a+1;
digit0=[digit0 newline default{i}];
case blockcount>660 && blockcount<=1320
digit1=[digit1 newline default{i}];
case blockcount<=1980 && blockcount>1320
digit2=[digit2 newline default{i}];
case blockcount<=2640 && blockcount>1980
digit3=[digit3 newline default{i}];
case blockcount<=3300 && blockcount>2640
digit4=[digit4 newline default{i}];
case blockcount<=3960 && blockcount>3300
digit5=[digit5 newline default{i}];
case blockcount<=4620 && blockcount>3960
digit6=[digit6 newline default{i}];
case blockcount<=5280 && blockcount>4620
digit7=[digit7 newline default{i}];
case blockcount<=5940 && blockcount>5280
digit8=[digit8 newline default{i}];
case blockcount<=6600 && blockcount>5940
digit9=[digit9 newline default{i}];
end
end
end
That's because you have somehow confused if-else syntax with switch-case. Note that an expression like blockcount>0 && blockcount<=660 always returns a logical value, meaning it's either 0 or 1. Now, when blockcount is equal to 1, first case expression also results 1 and the rest result 0, so, 1==1 and first block runs. But when blockcount becomes 2, the first case expression still results 1 and 2~=1 so nothing happens!
You can either use if-else or change your case expressions to cell arrays containing ranges of values. According to docs:
The switch block tests each case until one of the case expressions is
true. A case is true when:
For numbers, case_expression == switch_expression.
For character vectors, strcmp(case_expression,switch_expression) == 1.
For objects that support the eq function, case_expression ==
switch_expression. The output of the overloaded eq function must be
either a logical value or convertible to a logical value.
For a cell array case_expression, at least one of the elements of the
cell array matches switch_expression, as defined above for numbers,
character vectors, and objects.
It should be something like:
switch blockcount
case num2cell(0:660)
digit0 ...
case num2cell(661:1320)
digit1 ...
...
end
BUT, this block of code will take forever to complete. First, always avoid a = [a b] in loops. Resizing matrices is time consuming. Always preallocate a and do a(i) = b.

When using fscanf, what is happening inbetween lines being scanned?

I have an input file that I scan each line until the end. I use the first character as an indicator as what I want to do: 1. paused for x cycles, 2. write a 16-bit word serially, 3. write one bit at a time, 4 end of file.
The issue is that I see an extra mode in between the first p to w transition.
I tried printing out the string value of my variable "mode" but what I see is printed on the wave in between the first p and w is an additional mode not specified in my case statement.
at time = 0: mode equals " " (blank, nothing, all fine)
at time = A: mode now equals "p" (paused 4 cycles long, sure fine, I can fix this later)
at time = B: mode now equals "[]" (ERROR! this is not the next line)
at time = C: mode now equals "w" (back to normal)
input file:
p 10
w DEAD
w BEEF
p 5
b HHLL
p 100
eol
I have my systemverilog code that is suppose to scan the input file:
$fscanf(fd, "%c %h", mode, mystr);
case(mode)
"p": begin
wait_v = mystr.atoi();
repeat ( wait_v) begin
//turns bits on or off, but only modifies wire outputs and not mode
end
end
"w": begin
data = mystr.atohex();
// writes data, each character is 4 bits. each word is 16 cycles
end
"b": begin
lastsix = mystr.atobin();
// writes data outputs either high or low, each character is 1 cycle long
end
"eol": begin
$fclose(fn);
$stop;
end
Expected:
time => 0: mode equals " " (blank, nothing, all fine)
time => A: mode now equals "p" (paused for 3 cycles)
time => C: mode now equals "w" (back to normal)
Actual:
time => 0: mode equals " " (blank, nothing, all fine)
time => A: mode now equals "p" (paused 4 cycles long, sure fine, I can fix this later)
time => B: mode now equals "[]" (ERROR! this is not the next line)
time => C: mode now equals "w" (back to normal)
When you use %c in scanf it will read the very next character. When you use %h it will read a hex value, stopping after the last valid hex digit, and not reading what is next. So after your first fscanf call, the input will be pointing at the newline a the end of the first line, and the next fscanf call will read that newline with %c, and you'll get mode == "\n"
What you probably want is to use " %c%h" as your format -- note the (space) before the %c. The space causes fscanf to read and discard whitespace. Since %h automatically skips whitespace before reading a number, you don't need the space before it.

Matlab: Function that returns a string with the first n characters of the alphabet

I'd like to have a function generate(n) that generates the first n lowercase characters of the alphabet appended in a string (therefore: 1<=n<=26)
For example:
generate(3) --> 'abc'
generate(5) --> 'abcde'
generate(9) --> 'abcdefghi'
I'm new to Matlab and I'd be happy if someone could show me an approach of how to write the function. For sure this will involve doing arithmetic with the ASCII-codes of the characters - but I've no idea how to do this and which types that Matlab provides to do this.
I would rely on ASCII codes for this. You can convert an integer to a character using char.
So for example if we want an "e", we could look up the ASCII code for "e" (101) and write:
char(101)
'e'
This also works for arrays:
char([101, 102])
'ef'
The nice thing in your case is that in ASCII, the lowercase letters are all the numbers between 97 ("a") and 122 ("z"). Thus the following code works by taking ASCII "a" (97) and creating an array of length n starting at 97. These numbers are then converted using char to strings. As an added bonus, the version below ensures that the array can only go to 122 (ASCII for "z").
function output = generate(n)
output = char(97:min(96 + n, 122));
end
Note: For the upper limit we use 96 + n because if n were 1, then we want 97:97 rather than 97:98 as the second would return "ab". This could be written as 97:(97 + n - 1) but the way I've written it, I've simply pulled the "-1" into the constant.
You could also make this a simple anonymous function.
generate = #(n)char(97:min(96 + n, 122));
generate(3)
'abc'
To write the most portable and robust code, I would probably not want those hard-coded ASCII codes, so I would use something like the following:
output = 'a':char(min('a' + n - 1, 'z'));
...or, you can just generate the entire alphabet and take the part you want:
function str = generate(n)
alphabet = 'a':'z';
str = alphabet(1:n);
end
Note that this will fail with an index out of bounds error for n > 26, so you might want to check for that.
You can use the char built-in function which converts an interger value (or array) into a character array.
EDIT
Bug fixed (ref. Suever's comment)
function [str]=generate(n)
a=97;
% str=char(a:a+n)
str=char(a:a+n-1)
Hope this helps.
Qapla'

Brainfuck challenge

I have a any challenge. I must write brainfuck-code.
For a given number n appoint its last digit .
entrance
Input will consist of only one line in which there is only one integer n ( 1 < = n < = 2,000,000,000 ) , followed by a newline ' \ n' (ASCII 10).
exit
On the output has to find exactly one integer denoting the last digit of n .
example I
entrance: 32
exit: 2
example II:
entrance: 231231132
exit: 2
This is what I tried, but it didn't work:
+[>,]<.>++++++++++.
The last input is the newline. So you have to go two memory positions back to get the last digit of the number. And maybe you don't have to return a newline character, so the code is
,[>,]<<.
Nope sorry, real answer is
,[>,]<.
because your answer was getting one too far ;)
Depending on the interpreter, you might have to escape the return key by yourself. considering the return key is ASCII: 10, your code should look like this :
>,----- -----[+++++ +++++>,----- -----]<.
broken down :
> | //first operation (just in case your interpreter does not
support a negative pointer index)
,----- ----- | //first entry if it's a return; you don't even get in the loop
[
+++++ +++++ | //if the value was not ASCII 10; you want the original value back
>, | //every next entry
----- ----- | //check again for the the return,
you exit the loop only if the last entered value is 10
]
<. | //your current pointer is 0; you go back to the last valid entry
and you display it
Your issue is that a loop continues for forever until at the end of the loop the cell the pointer is currently on in equal to 0. Your code never prints in the loop, and never subtracts, so your loop will never end, and all that your code does is take an ASCII character as input, move one forward, take an ASCII character as input, and so on. All of your code after the end of the loop is useless, because that your loop will never end.

Code Golf - Word Scrambler

Please answer with the shortest possible source code for a program that converts an arbitrary plaintext to its corresponding ciphertext, following the sample input and output I have given below. Bonus points* for the least CPU time or the least amount of memory used.
Example 1:
Plaintext: The quick brown fox jumps over the lazy dog. Supercalifragilisticexpialidocious!
Ciphertext: eTh kiquc nobrw xfo smjup rvoe eth yalz .odg !uioiapeislgriarpSueclfaiitcxildcos
Example 2:
Plaintext: 123 1234 12345 123456 1234567 12345678 123456789
Ciphertext: 312 4213 53124 642135 7531246 86421357 975312468
Rules:
Punctuation is defined to be included with the word it is closest to.
The center of a word is defined to be ceiling((strlen(word)+1)/2).
Whitespace is ignored (or collapsed).
Odd words move to the right first. Even words move to the left first.
You can think of it as reading every other character backwards (starting from the end of the word), followed by the remaining characters forwards. Corporation => XoXpXrXtXoX => niaorCoprto.
Thank you to those who pointed out the inconsistency in my description. This has lead many of you down the wrong path, which I apologize for. Rule #4 should clear things up.
*Bonus points will only be awarded if Jeff Atwood decides to do so. Since I haven't checked with him, the chances are slim. Sorry.
Python, 50 characters
For input in i:
' '.join(x[::-2]+x[len(x)%2::2]for x in i.split())
Alternate version that handles its own IO:
print ' '.join(x[::-2]+x[len(x)%2::2]for x in raw_input().split())
A total of 66 characters if including whitespace. (Technically, the print could be omitted if running from a command line, since the evaluated value of the code is displayed as output by default.)
Alternate version using reduce:
' '.join(reduce(lambda x,y:y+x[::-1],x) for x in i.split())
59 characters.
Original version (both even and odd go right first) for an input in i:
' '.join(x[::2][::-1]+x[1::2]for x in i.split())
48 characters including whitespace.
Another alternate version which (while slightly longer) is slightly more efficient:
' '.join(x[len(x)%2-2::-2]+x[1::2]for x in i.split())
(53 characters)
J, 58 characters
>,&.>/({~(,~(>:#+:#i.#-#<.,+:#i.#>.)#-:)#<:##)&.><;.2,&' '
Haskell, 64 characters
unwords.map(map snd.sort.zip(zipWith(*)[0..]$cycle[-1,1])).words
Well, okay, 76 if you add in the requisite "import List".
Python - 69 chars
(including whitespace and linebreaks)
This handles all I/O.
for w in raw_input().split():
o=""
for c in w:o=c+o[::-1]
print o,
Perl, 78 characters
For input in $_. If that's not acceptable, add six characters for either $_=<>; or $_=$s; at the beginning. The newline is for readability only.
for(split){$i=length;print substr$_,$i--,1,''while$i-->0;
print"$_ ";}print $/
C, 140 characters
Nicely 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);}}
Lua
130 char function, 147 char functioning program
Lua doesn't get enough love in code golf -- maybe because it's hard to write a short program when you have long keywords like function/end, if/then/end, etc.
First I write the function in a verbose manner with explanations, then I rewrite it as a compressed, standalone function, then I call that function on the single argument specified at the command line.
I had to format the code with <pre></pre> tags because Markdown does a horrible job of formatting Lua.
Technically you could get a smaller running program by inlining the function, but it's more modular this way :)
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 at Lua so I'd like to see a shorter solution if there is one.
For a minimal cipher on all args to stdin, we can do 111 chars:
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 does output a trailing space like some of the other solutions.
For an input 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 whitespace.
TCL
125 characters
set s set f foreach l {}
$f w [gets stdin] {$s r {}
$f c [split $w {}] {$s r $c[string reverse $r]}
$s l "$l $r"}
puts $l
Bash - 133, assuming input is in $w variable
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 a trailing space.