| Bytes | Lang | Time | Link |
|---|---|---|---|
| 120 | AWK | 250404T143553Z | xrs |
| 139 | PHP 7 | 170215T172722Z | Titus |
| 105 | SmileBASIC | 170215T000816Z | 12Me21 |
| 084 | QBIC | 170120T203912Z | steenber |
| 061 | TIBASIC | 170118T215435Z | Julian L |
| 111 | Mathematica | 170121T140556Z | LegionMa |
| 081 | Perl 6 | 170119T000146Z | smls |
| 172 | 8th | 170119T221928Z | Chaos Ma |
| nan | 170119T230306Z | Suma | |
| nan | 170118T234705Z | Archmage | |
| 083 | Retina | 170119T104602Z | Leo |
| 094 | Ruby | 170119T104805Z | IMP1 |
| 1812 | sed | 170119T042538Z | Ray |
| 130 | Befunge93 | 170118T235934Z | James Ho |
| 107 | Python 2 | 170119T004443Z | xnor |
| 062 | TIBASIC | 170118T214018Z | Golden R |
| 160 | Python 2 | 170118T204931Z | ElPedro |
| 094 | Perl | 170118T202951Z | Dada |
| 108 | JavaScript ES6 | 170118T194836Z | Luke |
| 230 | Batch | 170118T202156Z | Neil |
AWK, 120 bytes
{for(i=5;i--;print(b="____")"|"(i?" ":a)"|"b"\n"){if(i)printf"%*s"(a="--O--"),5+int($1*i/5),X
for(j=i;j--;)print""}}
{for(i=5;i--; # 5 iterations
print(b="____")"|"(i?" ":a)"|"b"\n") # runway
{if(i)printf"%*s"(a="--O--"), # airplane
5+int($1*i/5),X # padding
for(j=i;j--;)print""}} # air/spacing
PHP 7, 139 bytes
still awfully long
for($x=$argv[1],$d=6;$d--;$x+=5<=>$x)for($i=$p=-1;$i++<$d;print"$s
")for($s=$i<$d?" ":"____| |____
";!$i&++$p<5;)$s[$x+$p]="--O--"[$p];
takes input from command line argument; run with -r.
breakdown
for($x=$argv[1], // take input
$y=6;$y--; // loop height from 5 to 0
$x+=5<=>$x) // post increment/decrement horizontal position
for($i=$p=-1;$i++<$y; // loop $i from 0 to height
print"$s\n") // 3. print
for($s=$i<$y?" ":"____| |____\n"; // 1. template=empty or runway+newline
!$i&++$p<5;)$s[$x+$p]="--O--"[$p]; // 2. if $i=0, paint plane
SmileBASIC, 109 105 bytes
G$="_"*4INPUT X
FOR I=0TO 4?" "*X;"--O--";CHR$(10)*(4-I)?G$;"| |";G$X=X-SGN(X-5)?NEXT?G$;"|--O--|";G$
QBIC, 93 91 84 bytes
:{X=space$(a)+@--O--`┘a=a-sgn(a-5)~t>-1|?X[t|?]t=t-1?@____|`+@ `+_fB|\_xB+A+_fB
Dropped some bytes by replacing the declaration of X$; optimised the FOR loop that prints the distance above-ground. Explanation below is for the old version, but it basically works the same.
For testing (and aesthetics) I had a slightly different version, at 103 bytes:
:{_z.5|_CX=Y[a|X=X+@ `]X=X+@--O--`
a=a-sgn(a-5)
~u>0|?X';`[u|?]u=u-1?@____|`+@ `+_fC|\_xC+_tB+_fC
These are functionally identical. The second one has the addition that the screen gets cleared between frames and that it halts for 0.5 seconds between frames.
Sample output
Note that I've added two newlines between frames. The most golfed code above does not add empty lines between frames, the cooler one clears the screen.
Command line: 10
--O--
____| |____
--O--
____| |____
--O--
____| |____
--O--
____| |____
--O--
____| |____
____|--O--|____
Explanation
Since I feel this touches upon many things I really like about QBIC, and gives a good insight in how some of its functions work under the hood, I've gone a bit overboard on the explanation. Note that QBIC is, at its core, an QBasic interpreter for Codegolf. QBIC code goes in - QBasic code comes out (and is subsequently executed).
:{ get the starting offset (called 'a') from the command line, and start a DO-loop
---- cool code only ----
_z.5|_C At the start of a DO-loop, pause for half a second and clear the screen
---- resume golf-mode ----
---- #1 - The tip of the left wing is anywhere between 0 and 10 positions to the right.
---- Create the plane with the spacing in X$
X=Y Clear X$
[a| For each point in the current offset
X=X+@ `] Add a space to X$
- Every capital letter in QBIC references that letter+$, a variable of type String
- @ and ` start and end a string literal, in this case a literal space.
- ] ends one language construct (an IF, DO or FOR). Here, it's NEXT
X=X+@--O--` Create the actual plane
- @ and `once again create a string literal. Every literal that is created in this
way is assigned its own capital letter. This is our second literal, so the body of
our plane is stored in B$ (A$ contains the space, remember?)
---- #2 Adjust the offset for the next iteration
a=a-sgn(a-5) The clever bit: We have an offset X in the range 0 - 10, and 5 attempts to
get this to be == 5. X - 5 is either positive (X = 6 - 10), negative
(X = 0 - 4) or 0 (X=5). sgn() returns the sign of that subtraction
as a 1, -1 or 0 resp. We then sub the sign from 'a', moving it closer to 5.
---- #3 Draw the plane, the empty airspace and the landing strip
~u>0| Are we there yet?
- ~ is the IF statement in QBIC
- It processes everything until the | as one true/false expression
- All the lower-case letters are (or better, could be) references to numeric
variables. Since QBasic does not need to post-fix those, they double as 'natural'
language: ignored by QBIC and passed as literal code to the QBasic beneath.
- The lower-case letters q-z are kinda special: at the start of QBIC, these
are set to 1 - 10. We haven't modified 'u' yet, so in the first DO-loop, u=5
?X';` If we're still air-borne, print X$ (our plane, incl. spacers)
- ? denotes PRINT, as it does in QBasic.
- ' is a code literal in QBIC: everything until the ` is not parsed, but
passed on to QBasic.
- In this case, we want a literal ; to appear after PRINT X$. This suppresses
QBasic's normal line-break after PRINT. This needs to be a code literal
because it is the command to read a String var from the command Line in QBIC.
[u|?] FOR EACH meter above the ground, print a newline
u=u-1 Descent 1 meter
?@____|` Print the LHS of the landing strip
+@ ` plus 5 spaces
+_fC| plus the LHS reversed.
\ ELSE - touchdown!
_x Terminate the program (effectively escape the infinite DO-loop)
- the _x command has an interesting property: ULX, or Upper/Lowercase Extensibility.
Writing this command with an uppercase _X does something similar, yet different.
The _x command terminates, and prints everything found between _x and | before
quitting. Uppercase _X does not look for |, but only prints something if it is
followed by a character in the ranges a-z and A-Z - it prints the contents of
that variable.
C+B+_fC But before we quit, print C$ (the LHS of the landing strip) and the plane,
and the LHS flipped.
---- #4 QBIC has left the building
- Did I say _x looks for a | ? Well, that gets added implicitly by QBIC at the end of
the program, or when one ( ']' ) or all ( '}' ) opened language constructs are closed.
- Also, all still opened language constructs are automatically closed at EOF.
- Had we stored anything in Z$, that would also be printed at this time.
TI-BASIC, 61 bytes
Input A
A
For(B,1,5
ClrHome
Output(5,1,"----/ /----
Output(B,Ans,"--O--
Ans+6-median({5,7,Ans
End
Mathematica, 111 bytes
If[#<1,"____|--O--|____"," "~Table~#2<>"--O--"<>"
"~Table~#<>"____| |____
"<>#0[#-1,#2+#2~Order~5]]&[5,#]&
Anonymous function. Takes a number as input and returns a string as output. Could probably be golfed further.
Perl 6, 97 90 81 bytes
{say "{"{" "x 15}\n"x 5}____| |____"~|("\0"x$^h+$_*(17-$h/5)~"--O--") for ^6}
Contrary to what it looks like, it outputs the *lower-case version of the plane (--o--), as allowed by the updated task description.
How it works
Bitwise string operators FTW!
{ # Lambda accepting horizontal index $h.
say # Print the following:
"{ "{ " " x 15 }\n" x 5 }____| |____" # The 15x6 background string,
~| # bitwise-OR'd against:
(
"\0" # The NULL-byte,
x $^h + $_*(17 - $h/5) # repeated by the plane's offset,
~ "--O--" # followed by an OR mask for the plane.
)
for ^6 # Do this for all $_ from 0 to 5.
}
It works because bitwise string operators use the codepoint values of the characters at a given position in two strings, to calculate a new character at that position in the output string.
In this case:
space OR O = o
space OR - = -
any OR \0 = any
For an uppercase-O plane, we could have used ~^ (string bitwise XOR), with a plane mask of \r\ro\r\r (+4 bytes for backslashes):
space XOR o = O
space XOR \r = -
any XOR \0 = any
The formula for the plane's offset, h + v*(17 - h/5), was simplified from:
v*16 # rows to the vertical current position
+ h # columns to the horizontal starting position
+ (5 - h)*v/5 # linearly interpolated delta between horizontal start and goal
8th, 177 172 bytes
: f 5 >r 5 repeat over " " swap s:* . "--O--" . ' cr r> times "____| |____\n\n" . over 5 n:cmp rot swap n:- swap n:1- dup >r while "____|--O--|____\n" . 2drop r> drop ;
The word f expects an integer between 0 and 10.
Usage
4 f
Explanation
: f \ n --
5 >r \ Push vertical distance from airport to r-stack
5 repeat
\ Print plane
over " " swap s:* . "--O--" .
\ Print airport
' cr r> times "____| |____\n\n" .
\ Now on the stack we have:
\ distanceFromLeftSide distanceFromAirport
over \ Put distance from left side on TOS
5 n:cmp \ Compare left distance and 5. Return
\ -1 if a<b, 0 if a=b and 1 if a>b
rot \ Put distance from left side on TOS
swap n:- \ Compute new distance from left side
swap n:1- \ Decrement distance from airport
dup >r \ Push new airport-distance on the r-stack
while
"____|--O--|____\n" . \ Print final step
2drop r> drop \ Empty s-stack and r-stack
;
Scala, 177, 163, 159 137 bytes
def p(x:Int,t:Int=5,a:String="\n"):String=a+(if(t>0)
" "*x+"--O--"+"\n"*t+"____| |____\n"+p(x-(x-4).signum,t-1)else"____|--O--|____")
Based on another answer, with significant reductions.
Scala, 224 181 bytes
EDIT: I had no idea you could do "string"*n to repeat it n times! Scala continues to blow my mind. Missing the if(t>0) instead of if(t==0) was a rookie mistake. Thanks for the tips, Suma!
def?(x:Int,t:Int=5):Unit={var(p,o)=("--o--","")
o=s"____|${if(t>0)" "*5 else p}|____\n"
for(i<-0 to t)o=if(i!=0&&i==t)" "*x+p+o else "\n"+o
println(o)
if(t>0)?(x-(x-4).signum,t-1)}
Original remarks:
I figured a recursive solution would be fun to try. I'm relatively new to Scala, so I'm certain this is far from optimal.
Retina, 86 83 bytes
.+
$* --O--¶¶¶¶¶¶____| |____
{*`$
¶
2D`¶
( {5})
$1
}`^ {0,4}-
$&
+
--O--
G`_
There is probably some sort of compression I could have used on the runway and the empty space over it, but anything I tried came up more expensive than plaintext (in Retina ¶ is a newline, so you can see the initial state in plaintext on the second line).
Ruby, 94 bytes
->a{5.times{|i|puts" "*a+"--O--#{?\n*(5-i)}____| |____
";a+=5<=>a};puts"____|--O--|____"}
Prints the plane's position followed by newlines and then the airport. Then it moves the plane by 1, -1, or 0, depending on its position relative to 5.
After looping the above 5 times, it prints the plane in the airport.
sed, 181 bytes + 2 for -nr flags
s/10/X/
:A
s/^/ /;y/0123456789X/-0123456789/;/[0-9]/bA;s/ -/P\n\n\n\n\n____|P|____/
:B
h;s/P([\n|])/--O--\1/;s/P/ /;s/^ *_/_/;p;/^_/q;x;s/\n//
/^ {5}$/bB;/ {6}/s/ //;s/^/ /;bB
Ungolfed
# Add leading spaces
s/10/X/
:A
s/^/ /
y/0123456789X/-0123456789/
/[0-9]/bA
s/ -/P\n\n\n\n\n____|P|____/
:B
# Place plane in appropriate spot
h
s/P([\n|])/--O--\1/
s/P/ /
s/^ *_/_/
p
/^_/q
x
# Movement
s/\n//
/^ {5}$/bB
# move left one extra, since we'll move right next line
/ {6}/s/ //
s/^/ /
bB
Usage: $ echo 2 | sed -nrf flightsim.sed
Befunge-93, 136 130 bytes
&5>00p10p55+v
:::00g>:1-\v>:"____| |_"
>:1-\v^\+55_$"--O--"10g
^\*84_$>:#,_10g::5v>:#,_@
<_v#!:-1g00+`\5\-`<^"____|--O--|____"
Explanation
& Read the plane position.
5 Initialise the plane height.
> Begin the main loop.
00p Save the current height.
10p Save the current position.
55+: Push two linefeed characters.
"____| |_" Push most of the characters for the airport string.
::: Duplicate the last character three times to finish it off.
00g>:1-\v Retrieve the current height, and then push
^\+55_$ that many copies of the linefeed character.
"--O--" Push the characters for the plane.
>:1-\v 10g Retrieve the current position, and then push
^\*84_$ that many copies of the space character.
>:#,_ Output everything on the stack in reverse.
10g:: Retrieve the current position and make two copies to work with.
5v If it's greater than 5
-`< then subtract 1.
+`\5\ If it's less than 5 then add 1.
g00 Retrieve the current height.
-1 Subtract 1.
_v#!: If it's not zero, repeat the main loop.
^"____|--O--|____" Otherwise push the characters for the landed plane.
>:#,_@ Output the string and exit.
Python 2, 107 bytes
n=input();h=5
while h:print' '*n+'--O--'+'\n'*h+'____| |____\n';n-=cmp(n,5);h-=1
print'____|--O--|____'
Simply hardcodes the last line for the landing plane. It can likely be golfed by re-using parts from before or being integrated into the loop.
TI-BASIC, 62 bytes
:Input A
:A
:For(N,3,8
:ClrHome
:Output(8,1,"----I I----
:Output(N,Ans,"--O--
:Ans+(Ans<6)-(Ans>6
:End
Note that TI-BASIC does not support _ or | and therefore I replaced with a capital I and -. This should not effect byte count.
Python 2, 160 bytes
i,s,p,l,r,c,x=input(),' ','--O--','____|','|____',0,4
while x>=0:print'\n'.join([s*i+p]+[s*15]*x+[l+s*5+r])+'\n';c+=1;x-=1;i=((i,i-1)[i>5],i+1)[i<5]
print l+p+r
Here is the reference implementation golfed down to 160 from 384. Still a way to go I think. Just posted for fun and to encourage a better Python answer.
Perl, 94 bytes
93 bytes of code + -p flag.
$\="____| |____
";$p="--O--";for$i(-5..-1){print$"x$_.$p.$/x-$i;$_+=5<=>$_}$\=~s/ +/$p/}{
JavaScript (ES6), 108 bytes
f=(a,b=5)=>b?" ".repeat(a)+`--O--${`
`.repeat(b)}____| |____
`+f(a<5?a+1:a-1,b-1):"____|--O--|____"
Test it
f=
(a,b=5)=>b?" ".repeat(a)+`--O--${`
`.repeat(b)}____| |____
`+f(a<5?a+1:a-1,b-1):"____|--O--|____"
<input type=number min=0 max=10 oninput=o.textContent=f(+this.value)><pre id=o>
Usage
Just call f with the index of the plane.
f(2)
Output
--O--
____| |____
--O--
____| |____
--O--
____| |____
--O--
____| |____
--O--
____| |____
____|--O--|____
Batch, 230 bytes
@echo off
set/ax=10-%1
set s= --O--
for /l %%i in (0,1,4)do call:l %%i
echo ____^|--O--^|____
exit/b
:l
call echo %%s:~%x%%%
for /l %%j in (%1,1,3)do echo(
echo ____^| ^|____
echo(
set/a"x-=x-5>>3,x+=5-x>>3
x is the number of spaces to remove from the beginning of the string s, so I subtract the parameter from 10. The last line is the nearest Batch has to x-=sgn(x-5).