| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | AWK | 250402T191546Z | xrs |
| nan | JavaScript Node.js | 250402T114326Z | Fhuvi |
| nan | Bash | 140324T033703Z | Glenn Ra |
| 391 | JavaScript | 140324T103626Z | Eliseo D |
| 050 | Javascript 391 441 | 140320T142940Z | TrungDQ |
| nan | 140320T063632Z | couchand | |
| nan | 140319T201908Z | kitcar20 | |
| 212 | TeX | 140319T170704Z | Bruno Le |
AWK, 221 bytes - 50 = 171
func J(){gsub(/ $/,"",a);if(1~d)a=sprintf("%*s",$1,a);else for(k=1;length(a)<$1;)a=gensub(/ /," ",k++%d+1,a);s=s a"\t"a"\n";a=X}{for(j=1;j++<NF;){if(length(a)+length($j)>$1){j--;J();d=0}else{d++;a=a $j" "}j~NF&&J()}}$0=s
func J(){ # J does formatting
gsub(/ $/,"",a); # strip trailing space
if(1~d) # if only one word
a=sprintf("%*s",$1,a); # pad spaces in front
else for(k=1; # else round robin
length(a)<$1;) # shorter than columns
a=gensub(/ /," ", # turn space into two
k++%d+1,a); # word mod num words
s=s a"\t"a"\n"; # concat string for stereo
a=X}{ # reset string
for(j=1;j++<NF;) # for each word
{if(length(a)+length($j) # if too long >
>$1) # our column input
{j--; # back up a word
J(); # output string
d=0} # reset word count
else{d++; # if it's shorter we add word
a=a $j" "} # concat new word with a space
j~NF&&J() # print last line
}}$0=s # print the whole string
JavaScript (Node.js), score=123 (193 bytes -70 bonus)
The challenge didn't specify anything regarding the "justified text", so i did a text wrapping instead like in the Bash answer, while still putting the necessary spaces for stereogram.
Note : the text given in example also contains some weird spacing after each punctuation, which have been kept as is.
(s,k,c,m,a=[" $1","$1 "])=>k.split` `.map(w=>s=(r=(x,z,y=/0(\S+)/g)=>x.replace(y,z))(s+" ",0+w+" ",w+" "))&&s.match(RegExp(`.{0,${c}}\\s`,'g')).map(l=>r(l,a[m]).padEnd(c+4)+r(l,a[1-m])).join`
`
s is the text, k is the hidden message, c is the column size, and m is the stereo mode : 0 for parallel and 1 for crossed.
First, we append a zero (assumed to never appear in the text parameter) before each of the first occurrence of words that are contained in the hidden message. Words are recognized by the space following them, so we added a space at the end of the full text to protect the last word.
Then using a regex we "text wrap" the text parameter with a maximum column width, and still using spaces to identify the end of words.
After that, we parse each line and add a padding to the left column. We then use replace again (which have been stored) to identify the words beginning with a zero, we remove the zero and put a space before or after the word, depending whether it's the left or right column, and depending of the vision mode.
It might be possible to beat this JS solution by not using all these regex and replace, and appending the words one by one while keeping track of the number of characters added in each line.
Bash, sed: 228 223 197 (242 - 70) = 172
c=${5:-=};R=$c;L=;for f in r l;do
e="sed -e ";$e"$ d;s/$\| */ \n/g" $1>m
o=1;for w in `$e"$ p;d" $1`;do
$e"$o,/^$w /s/^$w /$L$w$R /" m>n;o="/$c/"
cp n m;done;tr -d \\n<n|fold -sw${2:-35}|$e"s/$c/ /g">$f
L=$c;R=;done;pr -tmw${3:-80} ${4:-l r}
If the script is in an executable file called "stereo", then type
stereo file.in [column_width [page_width ["r l"]]]
column_width is a number; 25-45 will work, default is 35.
page_width is a number, should be about twice the column_width, default is 80
For cross-eyed viewing, use "r l" as the 4th argument. Default is "l r" which sets up for parallel viewing.
EDIT: Rewrote to split the file into one word per line, then reassemble at the end. Note: reserves the "=" sign for its own use. Any "=" signs in the input file will become blanks.
EDIT: If your message has "=" signs in it, you can choose another symbol for the script to use, by supplying it as the 5th parameter.
Example
Input: vegetarianism.txt:
I invented vegetarianism. It is a diet involving no meat, just
vegetables. It is also common in cows - they are awesome.
vegetarianism. is awesome.
Result
./stereo vegetarianism.txt 32 72 "l r" : | expand (using the colon for its internal working symbol)
I invented vegetarianism. It I invented vegetarianism. It
is a diet involving no meat, is a diet involving no meat,
just vegetables. It is also just vegetables. It is also
common in cows - they are common in cows - they are
awesome. awesome.
./stereo washington.txt 35 75 "l r" |expand
In a little district west of In a little district west of
Washington Square the streets Washington Square the streets
have run crazy and broken have run crazy and broken
themselves into small strips themselves into small strips
called 'places'. These 'places' called 'places'. These 'places'
make strange angles and curves. make strange angles and curves.
One Street crosses itself a time One Street crosses itself a time
or two. An artist once discovered or two. An artist once discovered
a valuable possibility in this a valuable possibility in this
street. Suppose a collector with a street. Suppose a collector with a
bill for paints, paper and canvas bill for paints, paper and canvas
should, in traversing this route, should, in traversing this route,
suddenly meet himself coming suddenly meet himself coming
back, without a cent having been back, without a cent having been
paid on account! paid on account!
The "|expand" isn't necessary but when shifting the output by 4 places the TABs get handled incorrectly. It could be put into the script at a cost of 7 bytes.
ImageMagick variation
Replacing the last line with a text-to-image ImageMagick command:
c=${6:-=};R=$c;L=;for f in r l;do
e="sed -e ";$e"$ d;s/$\| */ \n/g" $1>m
o=1;for w in `$e"$ p;d" $1`;do
$e"$o,/^$w /s/^$w /$L$w$R /" m>n;o="/$c/"
cp n m;done;tr -d \\n<n|fold -sw${2:-35}|$e"s/$c/ /g">$f
L=$c;R=;done;
convert -border 10x30 label:@${4:-l} label:@${5:-r} +append show:
In this one, the "r" and "l" for cross-eyed versus parallel viewing are separate arguments:
./im_stereo vegetarianism.txt 40 80 l r =

(source: simplesystems.org)
EDIT 3: Added ImageMagick variation.
JavaScript 391
_='L=b=>b.length;c=console.log;p=prompt;r=(l*=" ")3m*),s=(f=[]3n=w=a52i=0;i<67i++)l/==m@&&(m!,l/=g+r/,r/8g),?>w&&(w=?72;67){9$]52:]56)&&%#)+64)<w;)#8l4+g,:-1]8r@+g,l!,r!;#8g.repeat(w-%#))}2c(f,s7%f7)a8$f4+s4+"\\n",f!,s!;c(a)!.shift()#9-1]$??%L(*=p().split(g/[i]2for(3).slice(),4[0]5="";6%l7);8+=9f[%f):s[%s)?6/)+1@[$0]';for(Y in $='@?:98765432/*%$#!')with(_.split($[Y]))_=join(pop());eval(_)
Javascript 391 (441 - 50)
(My first code golf)
k=' ';Q='length';A=prompt().split(k);S=prompt().split(k);i=-1;M=25;L=[[]];j=0;R='';while(i++<A[Q]-1){if((j+A[i][Q])<M){if(S.indexOf(A[i])>-1){A[i]=(j?k+k:k)+A[i]}L[L[Q]-1].push(A[i]);j+=A[i][Q]+1}else{j=0;i--;L.push([])}}for(i=0;i<L[Q]-1;P(L[i++].join(C))){C=k;while(L[i].join(C+k)[Q]<M){C+=k}}P(L[i].join(k)+k);function P(a){while(a[Q]<M){a=a.replace(k,k+k)}R+=a;for(c in S){a=a.split(k+k+S[c]).join(k+S[c]+k)}R+=k+k+a+'\n'}console.log(R);
Result
In a little district In a little district
west of Washington west of Washington
Square the streets have Square the streets have
run crazy and broken run crazy and broken
themselves into small themselves into small
strips called 'places'. strips called 'places'.
These 'places' make These 'places' make
strange angles and strange angles and
curves. One Street curves. One Street
crosses itself a time or crosses itself a time or
two. An artist once two. An artist once
discovered a valuable discovered a valuable
possibility in this possibility in this
street. Suppose a street. Suppose a
collector with a bill collector with a bill
for paints, paper and for paints , paper and
canvas should, in canvas should, in
traversing this route, traversing this route,
suddenly meet himself suddenly meet himself
coming back, without a coming back, without a
cent having been paid on cent having been paid on
account! account!
Long code:
var arr = "In a little district west of Washington Square the streets have run crazy and broken themselves into small strips called 'places'. These 'places' make strange angles and curves. One Street crosses itself a time or two. An artist once discovered a valuable possibility in this street. Suppose a collector with a bill for paints, paper and canvas should, in traversing this route, suddenly meet himself coming back, without a cent having been paid on account!".split(' ');
var secret = "Washington paints himself".split(' ');
var i = -1;
var MAX_WIDTH = 25;
var lines = [[]];
var _l = 0;
var result = '';
while (i++ < arr.length - 1) {
if ((_l + arr[i].length) < MAX_WIDTH) {
if (secret.indexOf(arr[i]) > -1) {arr[i] = (_l?' ':' ') + arr[i]}
lines[lines.length - 1].push(arr[i]);
_l += arr[i].length + 1;
} else {
_l = 0;
i--;
lines.push([]);
}
}
for (var i = 0; i < lines.length - 1; putText(lines[i++].join(chars))) {
// Align text
var chars = ' ';
while (lines[i].join(chars + ' ').length < MAX_WIDTH) {
chars += ' ';
}
}
putText(lines[i].join(' ') + ' ');
function putText(line) {
while (line.length < MAX_WIDTH) {
line = line.replace(' ', ' ');
}
// Make the illusion
result += line;
for (var val in secret) {
line = line.split(' '+secret[val]).join(' ' + secret[val] + ' ');
}
result += (' ' + line) + '\n';
}
console.log(result);
GolfScript 209 (279 -50 -20)
This is my first big GolfScript program. I wouldn't be surprised if there are optimizations to be had. Both the bonuses are supported; they are expected to be found after the message inputs, like:
"I invented vegetarianism. It is a diet involving no meat, just vegetables. It is also common in cows - they are awesome."
"vegetarianism. is awesome."
16 # column width
0 # view type, 1 for cross eyed (?)
If you've saved that file to input (and downloaded GolfScript) you can invoke the script with:
> cat input | ruby golfscript.rb
Golfed
~{{\}}{{}}if:v;:w;n%~' '%\' '%[.]zip 0:c;{' '*}:s;{[.;]}:r;\{:x;{.c=0=x=}{1c+:c;}until.c<\1c+>[[x' 'v+' 'x v+]]\++}/zip{0:c;[[]]\{.,.c+w<{1c++:c;\)@r+r+}{:c;[r]+}if}/{.{,}%{+}*w\- 1$,1-.{1$1$/@@%@0:g;{3$3$g>+s\++1g+:g;}*\;\;}{[;.2/\2%1$s@@+s@)\;\]{+}*}if}%}%zip{{4s\++}*}%n*puts
Ungolfed
~
#The program:
# Parameters, in reverse natural order
{{\}}{{}}if:v; # view - truthy for parallel, falsey for cross-eyed
:w; # col width
n%~ # split input on newlines
' '%\ # split secret message tokens
' '% # split public message
[.]zip # left and right
0:c; # word count
{' '*}:s; # spaces
{[.;]}:r; # array of top
# for each secret word
\{
:x; # word
{.c=0=x=}
{1c+:c;} until
# next public word is this private word
# splice edits
.c< \1c+> [[x' 'v+ ' 'x v+]]\ ++
}/
zip
# layout both messages
{
0:c; # char count
[[]]\ # line accumulator
# split lines
{
.,.c+w<
# if enough room on line
#append to current line
{1c++:c;
\)@r+r+
}
#append as new line
{:c;
[r]+
}if
}/
# set lines
{
.{,}%{+}* # line chars
w\- # space chars
1$,1- # gaps between words
# if multi word
.{
1$1$ # duplicate params
/@@ # chars per space
% # extra space gaps
@ # load line
0:g; # current gap
# join row
{
3$3$ # params
g>+ # extra space
s # space chars
\++ # append
1g+:g; # update gap
}*
\;\; # drop params
}
# else one word
{
[
; # drop gap count
. # num spaces needed
2/\ # spaces per side
2% # extra space
1$s # left space
@@+s # right space
@)\;\ # word
]{+}* # join
}if
}% # end line layout
}% # end message layout
zip
{{4s\++}*}%
n*
puts
Javascript 493 (minimum expectations)
g=" ";l=prompt().split(g);r=l.slice();m=prompt().split(g);f=[];s=f.slice();w=0;n=0;a="";for(i=0;i<l.length;i++){if(l[i]==m[0]){m.shift();l[i]=g+r[i];r[i]+=g;}if(l[i].length+1>w)w=l[i].length+1;}while(l.length){f[f.length]="";s[s.length]="";while(l.length&&f[f.length-1].length+l[0].length<w){f[f.length-1]+=l[0]+g;s[s.length-1]+=r[0]+g;l.shift();r.shift();}f[f.length-1]+=g.repeat(w-f[f.length-1].length);}console.log(f,s);while(f.length){a+=f[0]+s[0]+"\n";f.shift();s.shift();}console.log(a);
This code sets up two arrays of lines (left and right), arranges them in a string and prints to f12 console.
This is just a minimum answer, not intended to win.
TeX 212
I am using a typesetting system, not ASCII. The column width can be changed by changing 90pt in the fourth line, but I don't know if that's enough to qualify for the 50 bytes discount. The distance between the two copies of the text can be changed by changing the 9pt, also in the fourth line. The code can probably be made shorter. One can replace each newline by a single space, but not remove them completely.
\let\e\expandafter\read5to\t\read5to\.\def\a#1
{\def\~##1#1##2\a{\def\t{##1\hbox{\
#1\~{}}##2}\a}\e\~\t\a}\e\a\.{}\shipout\hbox
spread9pt{\hsize90pt\fontdimen3\font\hsize\vbox{\t}\
\let\~\ \def\ {}\vbox{\t}}\end.
After calling tex filename.tex in the terminal, the user is prompted to give the main text, then prompted again for a list of words to shift. No empty line in between. The (space-separated) list of words given in the second line should appear exactly as it is in the main text (punctuation is treated just like a letter would be, only spaces delimit words).