# All Aboard the ASCII Train!

    o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___
o       | C |   | O |   | D |   | E |   |   |   | G |   | O |   | L |   | F |
TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
{======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'


You best be prepared to ride the train, because you're about to build the train you'll be riding on. Given a string s, output a fully formed train as depicted above. The first thing output is always the engine that'll be tugging your string along, as depicted alone below:

    o O O
o
TS__[O]
{======|
./o--000'


Following the locomotive are rail-cars containing each character of your precious cargo. To save confusion when unloading, your company has tasked you with labeling the outside of these cars. The cars in question will always look like this:

   ___
| # |
|___|
_|"""""|
"-0-0-'


Where the # is representative of the character that is inside the "cargo" hold. Chaining the engine to each car is also part of your job, as you've been tasked with overseeing the fluidity and success of this entire shipment. So, once you've labeled all the cars and got the engine on the tracks, you must ensure that the train is assembled and ready to roll.

# Rules

• The only input your program should take is a single string.
• The engine must always be output, even if your shipment is empty.
• Each car can only hold one character, don't push your luck you may damage the goods.
• You need only support the following printable ASCII characters: _-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
If you end up doing more, that's fine too, but this is the bare minimum.
• 1-2 trailing spaces are acceptable, as is a single trailing newline.
• This is , shortest byte-count wins.
• Vaguely related. – Martin Ender Nov 30 '16 at 22:33
• I don't think this is actually kolmogorov-complexity. Based on this meta post this question is certainly on the line between fitting and not fitting our definition and I would personally say that it does not fit the tag similar to this question which also asks for a type of string wrapping. – Wheat Wizard Dec 1 '16 at 4:05
• This is beautiful ascii-art – CAD97 Dec 1 '16 at 5:19
• @WheatWizard it's a mixture of multiple genres. The engine would fall under kolmogrov complexity, the whole thing under ASCII-Art and it probably also falls a little bit into string manipulation. – Magic Octopus Urn Dec 1 '16 at 14:23
• I was under the impression that compressing the actual pattern of the train would be worthy of the tag; but I'll just remove it to stop the argument. – Magic Octopus Urn Dec 1 '16 at 17:46

# 05AB1E, 101 99 bytes

Naive first attempt.

"    o O O   o"ð7×"TS__[O] {======|./o--000'"J5ä¹v… _ €ÐJy“ | ÿ |   |___| _|"""""|"-0-0-'“«5ä})øJ»


Try it online!

• Well, the code doesn't resemble a train, but it's winning now. – Magic Octopus Urn Dec 2 '16 at 14:27

# JavaScript (ES6), 149 144 bytes

s=>    o O Oa   ___
o     a  | $& | TS__[O]a |___| {======|a_|"""""| ./o--000'a"\-0-0-'.replace(/a(.*)/g,(_,c)=>s.replace(/./g,c))  I don't think the engine itself can be compressed, but perhaps it's possible. ### Test snippet let f = s=> o O Oa ___ o a |$& |
TS__[O]a  |___|
{======|a_|"""""|
./o--000'a"\-0-0-'.replace(/a(.*)/g,(_,c)=>s.replace(/./g,c))

O.innerHTML = f("CODE GOLF")
<input value="CODE GOLF" oninput="O.innerHTML=f(this.value.replace(/\n/g,'&lt;br&gt;'))"><br>
<pre id=O></pre>

• Lots of repeated characters, should be possible to squeeze some more bytes out of it. – orion Nov 30 '16 at 23:11
• One can almost see the train packed in the source code :-) – Luis Mendo Nov 30 '16 at 23:15
• Upvoted primarily becuase the code resembles a train – Rohan Jhunjhunwala Dec 1 '16 at 1:02
• Bonus points because it runs right there in the browser! – DGM Dec 1 '16 at 20:40

# Befunge, 276 270 bytes

p1p~:7>7+#:#~_$:v >#p0p10:p00:+1g00_v#: v"!!!!!"v>0p01g\-0g1+53p v"!}!#!}!!"v0 p115< v"!}}!!"v^:-1< v"}#####}">00g:| >"(.1.1.a#"^+<v1< v"P!P!p!!! "v5>g00p v"!!!!!p!!!"v6 v"^P\TU!!"vp v"}>>>>>>|!"v+ >"(111..p0/"v6 v-1:g110">>"<g >:11p!#v_p011^ #-:#1_@>>,#  Try it online! Explanation The car and engine are encoded as two sets of five strings on lines 3 to 12. The character values are off by 1 so as to avoid having to deal with the double quotes which can't be used in a Befunge string. The code works by building up the full set of characters needed to render the train on the stack. For each line of output, an appropriate car string is first added to the stack, repeated as many times as necessary for the cargo, and then one copy of the appropriate engine string. After each line has been constructed, a pair of the down arrows to left of the strings is replaced with a right arrow, so the next iteration of the loop follows a different path through the code, using a different pair of strings for the car and engine. Once all the data has been built up on the stack, there's a final rendering loop which writes out the characters, subtracting 1 each time to account for the initial encoding. As a bonus, the source is designed in the shape of a gun turret, in case the train comes under attack. Golfers destroyed my gun turret. • Golfers destroyed my gun turret, LOL. +1. Yet, it's beating C# and Java. – Adalynn Dec 4 '16 at 3:21 # PHP, 218 211 204 187 183 bytes  o O O<?for(;$y<5;print"\n".["   o     ","  TS__[O]"," {======|","./o--000'"][+$y++])for($p=0;$c=a&$argn[$p++];)echo[" ___ "," |$c | ","  |___| ",'_|"""""|',"\"-0-0-'"][+$y];  Takes input from STDIN; run with -nR. Compressing the engine or wagon would require more code to decompress than it saves on storage. I see no more potential here. • a&$c=$argn instead of ""<$c=$argv[1] – Jörg Hülsermann Apr 29 '17 at 14:09 • @JörgHülsermann Yea this post was ancient. :) – Titus May 2 '17 at 9:12 ## Python 2, 176 bytes lambda i:'\n'.join(map(''.join,zip(*[[" o O O"," o "," TS__[O]"," {======|","./o--000'"]]+[[" ___ ",' | '+x+' | '," |___| ",'_|"""""|',"\"-0-0-'"]for x in i])))  Example: print f('Python')  gives  o O O ___ ___ ___ ___ ___ ___ o | P | | y | | t | | h | | o | | n | TS__[O] |___| |___| |___| |___| |___| |___| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""| ./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'  ## Powershell, 167 166 Bytes $l=($a=$args[0]).Length;"    o O O"+"   ___  "*$l;" o "+($a[0..$l]|%{" |$_ |"});"  TS__[O]"+"  |___| "*$l;" {======|"+'_|"""""|'*$l;"./o--000'"+'"-0-0-'''*$l  Example: .\train.ps1 "PowerShell!" o O O ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ o | P | | o | | w | | e | | r | | S | | h | | e | | l | | l | | ! | TS__[O] |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""| ./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'  Possibly Invalid! If run with no args at all it will try and print one empty string, and look like:  o O O o | | TS__[O] {======| ./o--000'  If run with an empty input string it will return correctly however: .\train.ps1 "" o O O o TS__[O] {======| ./o--000'  (kinda) Ungolfed: $l=($a=$args[0]).Length
"    o O O"+"   ___  "*$l " o "+($a[0..$l]|%{" |$_ |"})
"  TS__[O]"+"  |___| "*$l " {======|"+'_|"""""|'*$l
"./o--000'"+'"-0-0-'''*$l  shortest compression in Powershell is going to be +'c'*x where c is the char and x is the number of repetitions, and that's only for trailing or leading repetitions, any center-string repetitions will require an extra + and an extra " - so there's no point in this where I can see compression saving any space, and the only repeated char set is ___ which is only 3 chars. Explanation: $l=($a=$args[0]).Length Take the first arg, put it into $a, then take the length of$a and put it into $l, these are the only variables you need. " o O O"+" ___ "*$l most of the other bits follow this format of the left-part and then the right part times the number of required chars.

" o "+([char[]]$a|%{" |$_ |"}) loop (|%{}) through $a as a char array, so foreach (char$_ in $a) for a non-pipeline version, then put the char into the text. this is an extremely simple approach, but because I can't find a good way to compress the strings past this it seems like the most useful. saved 1 Byte thanks to briantist! and here I was thinking this wouldn't get any shorter.. • You didn't have to handle no args :). – Magic Octopus Urn Dec 1 '16 at 17:20 • @carusocomputing yay, thanks for letting me know. – colsw Dec 1 '16 at 18:00 • Nice! You can save 1 byte by changing [char[]]$a to $a[0..$l] :) – briantist Dec 3 '16 at 18:04
• ah was using char array before I declared $l and totally forgot about it. thanks for that! – colsw Dec 5 '16 at 11:44 # Java, 361 bytes class C {static void main(String[]v){Scanner q = new Scanner(System.in);String i = q.nextLine();String[] t = {" o O O ", " o ", " TS__[O] ", " {======|", "./o--000'",};for (char c: i.toCharArray()) {t[0]+="___ ";t[1]+="| # | ".replace('#',c);t[2]+="|___| ";t[3]+="_|\"\"\"\"\"|";t[4]+="\"-0-0-'";}for(String p:t) System.out.println(p);}}  class C { static void main(String[]v) { Scanner q = new Scanner(System.in); String i = q.nextLine(); String[] t = { " o O O ", " o ", " TS__[O] ", " {======|", "./o--000'", }; for (char c: i.toCharArray()) { t[0]+="___ "; t[1]+="| # | ".replace('#',c); t[2]+="|___| "; t[3]+="_|\"\"\"\"\"|"; t[4]+="\"-0-0-'"; } for(String p:t) System.out.println(p); } }  Example java o O O ___ ___ ___ ___ o | j | | a | | v | | a | TS__[O] |___| |___| |___| |___| {======|_|"""""|_|"""""|_|"""""|_|"""""| ./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'  • I know it's been halve a year, but you can golf quite a bit (also by removing spaces): interface C{static void main(String[]v){String n="\n",b=" o O O ",c=" o ",d=" TS__[O] ",e=" {======|",f="./o--000'";for(String x:new java.util.Scanner(System.in).nextLine().split("")){b+="___ ";c+="| "+x+" | ";d+="|___| ";e+="_|\"\"\"\"\"|";f+="\"-0-0-'";}System.out.print(b+n+c+n+d+n+e+n+f);}} (318 bytes) Or even more if you replace new java.util.Scanner(System.in).nextLine() with v[0] as alternative input (279 bytes) Try it here. – Kevin Cruijssen May 2 '17 at 9:37 ## Perl, 137 bytes 132 bytes of code + 5 bytes for-pF flags. ascii_train.pl: #!/usr/bin/perl -apF s/./ |$& | /g;$_=" o O O! ___ o$_
TS__[0]!  |___|
{======|!".'_|"""""|'."
./o--000'!\"-0-0-'";s/!(.*)/$1x@F/ge  Note that I added -a flag in the code, but it's only because old versions of Perl require -a when -F is used. To run it: echo -n "code-golf" | perl ascii_train.pl  The input must be supplied without a final newline (with echo -n for instance). Explanations: From what I've seen, it's roughly the same idea as ETHProduction's JavaScript answer. There isn't a lot going on: sadly the patterns are a bit to short to make x operator worth being used. First, s/./ |$& | /g surrounds each character of the input with | (and spaces) to form the second level of the train.
Then inside that long string, everything between a ! and a newline is a pattern we wish to repeat to construct the cars. That repetition is done thanks to the regex s/!(.*)/$1x@F/ge. (I used ! because the input can't contain it). # SOGL V0.12, 57 56 bytes Τ¡ā↓mΛC┌─⁵℮Ƨ⅛□→(š;∞⅟¹°⅔Ζ‽ζ÷⁴‘9n,{"s=Ο!NθæιžGš‼t╬¼Xg‘8n┼  Try it Here! Explanation: ..‘ push a compressed string of the locomotive in a single line 9n split in line lengths of 9 ,{ for each character in the input "..‘ push a compressed string of a wagon in a single line 8n split to line lengths of 8 ┼ add horizontally  # C#, 277 Bytes Golfed: string T(string s){var o=new string[]{" o O O"," o "," TS__[O]"," {======|","./ o--000'" };for(int i=0;i<s.Length;i++){o[0]+=" ___ ";o[1]+="| # | ".Replace("#",s[i]+"");o[2]+=" |___| ";o[3]+="_|\"\"\"\"\"|";o[4]+="\"-0-0-'";}return string.Join("\r\n",o);  Ungolfed: public string T(string s) { var o = new string[] { " o O O", " o ", " TS__[O]", " {======|", "./ o--000'" }; for (int i = 0; i < s.Length; i++) { o[0] += " ___ "; o[1] += "| # | ".Replace("#", s[i] + ""); o[2] += " |___| "; o[3] += "_|\"\"\"\"\"|"; o[4] += "\"-0-0-'"; } return string.Join("\r\n", o); }  Testing: Console.Write(new AllAboardTheASCIITrain().T("")); o O O o TS__[O] {======| ./ o--000'  And... Console.Write(new AllAboardTheASCIITrain().T("Programming Puzzles & Code Golf")); o O O ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ o | P | | r | | o | | g | | r | | a | | m | | m | | i | | n | | g | | | | P | | u | | z | | z | | l | | e | | s | | | | & | | | | C | | o | | d | | e | | | | G | | o | | l | | f | TS__[O] |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| |___| {======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""| ./ o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'  ## C# 221 bytes nothing special happening here.. just creating each line and join them with new lines. s=>{var t=new[]{" o O O"," o "," TS__[O]"," {======|","./o--000'"};foreach(var c in s){t[0]+=" ___ ";t[1]+=$"  | {c} | ";t[2]+="  |___| ";t[3]+="_|\"\"\"\"\"|";t[4]+="\"-0-0-'";}return string.Join("\n",t);};


## C, 217212 208 Bytes

i;f(char*t){char d[]="    o O O   o       TS__[O] {======|./o--000'   ___    | C |   |___| _|\"\"\"\"\"|\"-0-0-'",*p;for(;i<5;i++){printf("%.9s",d+i*9);for(p=t;d[57]=*p++;)printf("%.8s",d+45+i*8);puts("");}}


Try it online

Output:

    o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___
o       | C |   | O |   | D |   | E |   |   |   | G |   | O |   | L |   | F |   |   |   | I |   | N |   |   |   | C |
TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
{======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'


# Jq 1.5, 178 bytes

[["    o O O   o       TS__[O] {======|./o--000'"|_nwise(9)]]+[range(length)as$i|[.[$i:$i+1]|" ___ | \(.) | |___| _|\"\"\"\"\"|\"-0-0-'"|_nwise(8)]]|transpose|map(add)[]  Expanded # engine def E:" o O O o TS__[O] {======|./o--000'"|_nwise(9); # car (note string interpolation) def C:" ___ | \(.) | |___| _|\"\"\"\"\"|\"-0-0-'"|_nwise(8); # generate train [[E]] + [range(length) as$i| [.[$i:$i+1] |C]]

# combine rows and concatenate strings


Sample run

$jq -MRr train.jq <<< "golf" o O O ___ ___ ___ ___ o | g | | o | | l | | f | TS__[O] |___| |___| |___| |___| {======|_|"""""|_|"""""|_|"""""|_|"""""| ./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'$ wc -c < train.jq
178


Try it online

# Excel VBA, 218 Bytes

Anonymous VBE immediate window function that takes input from range [A1] and outputs to the VBE immediate window

[B1]=[Len(A1)]:?"    o O O"[Rept("   ___  ",B1)]:?"   o     ";:For i=1To[B1]:?"  | "Mid([A1],i,1)" | ";:Next:?:?"  TS__[O]"[Rept("  |___| ",B1)]:?" {======|"[Rept("_|""""""""""|",B1)]:?"./o--000'"[Rept("""-0-0-'",B1)]


[B1]=[Len(A1)]
?"    o O O"[Rept("   ___  ",B1)]
?"   o     ";:For i=1To[B1]:?"  | "Mid([A1],i,1)" | ";:Next:?:
?"  TS__[O]"[Rept("  |___| ",B1)]:
?" {======|"[Rept("_|""""""""""|",B1)]:
?"./o--000'"[Rept("""-0-0-'",B1)]


## Sample Output

    o O O   ___     ___     ___     ___     ___     ___     ___     ___     ___     ___     ___
o       | V |   | B |   | A |   |   |   | E |   | x |   | p |   | r |   | e |   | s |   | s |
TS__[O]  |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |___|
{======|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|
./o--000'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'"-0-0-'
`