45
\$\begingroup\$

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.
\$\endgroup\$
10
  • 4
    \$\begingroup\$ Vaguely related. \$\endgroup\$ Nov 30, 2016 at 22:33
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Wheat Wizard
    Dec 1, 2016 at 4:05
  • 5
    \$\begingroup\$ This is beautiful ascii-art \$\endgroup\$
    – CAD97
    Dec 1, 2016 at 5:19
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Dec 1, 2016 at 14:23
  • \$\begingroup\$ 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. \$\endgroup\$ Dec 1, 2016 at 17:46

14 Answers 14

39
\$\begingroup\$

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>

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

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.

\$\endgroup\$
1
  • \$\begingroup\$ Golfers destroyed my gun turret, LOL. +1. Yet, it's beating C# and Java. \$\endgroup\$
    – Adalynn
    Dec 4, 2016 at 3:21
6
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ a&$c=$argn instead of ""<$c=$argv[1] \$\endgroup\$ Apr 29, 2017 at 14:09
  • \$\begingroup\$ @JörgHülsermann Yea this post was ancient. :) \$\endgroup\$
    – Titus
    May 2, 2017 at 9:12
4
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ Well, the code doesn't resemble a train, but it's winning now. \$\endgroup\$ Dec 2, 2016 at 14:27
4
\$\begingroup\$

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-'
\$\endgroup\$
4
\$\begingroup\$

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..

\$\endgroup\$
4
  • \$\begingroup\$ You didn't have to handle no args :). \$\endgroup\$ Dec 1, 2016 at 17:20
  • \$\begingroup\$ @carusocomputing yay, thanks for letting me know. \$\endgroup\$
    – colsw
    Dec 1, 2016 at 18:00
  • \$\begingroup\$ Nice! You can save 1 byte by changing [char[]]$a to $a[0..$l] :) \$\endgroup\$
    – briantist
    Dec 3, 2016 at 18:04
  • \$\begingroup\$ ah was using char array before I declared $l and totally forgot about it. thanks for that! \$\endgroup\$
    – colsw
    Dec 5, 2016 at 11:44
2
\$\begingroup\$

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-'
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ May 2, 2017 at 9:37
2
\$\begingroup\$

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).

\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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-'
\$\endgroup\$
1
\$\begingroup\$

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);};
\$\endgroup\$
1
\$\begingroup\$

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     
| transpose | map(add)[]

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

\$\endgroup\$
1
\$\begingroup\$

C (clang), 217 212 208 193 bytes

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

-4 bytes thanks to ceilingcat!!

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ @ceilingcat, thanks, this one really needed more golfing. Is there a wide character version of write? \$\endgroup\$
    – jdt
    Sep 21, 2021 at 13:59
  • \$\begingroup\$ Perhaps not exactly what you want but there is wprintf() \$\endgroup\$
    – ceilingcat
    Sep 21, 2021 at 14:33
0
\$\begingroup\$

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)]

Formatted for readability

[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-'
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.