Arte ASCII “Flight Simulator”


24

EDITAR

Parece que houve alguma confusão após meu erro de digitação no post original, que usava o minúsculo para definir o plano e depois o maiúsculo. Infelizmente, este bug não foi detectado na Sandbox. Como muitos membros escreveram respostas com ambos e como o erro de digitação foi minha culpa, permitirei maiúsculas ou minúsculas na definição do avião. Eu adicionei uma nova regra para isso.

fundo

Eu gosto de animações de arte ascii, como costumo chamá-las, então aqui está outra. Eu não acho que isso seja muito difícil de implementar, então esperamos obter respostas curtas e interessantes.

Para todos os membros da comunidade

Se você melhorar sua resposta, modifique sua contagem de bytes como

contagem de bytes antigos contagem de bytes novos

para que possamos ver seu progresso. Obrigado!

Desafio

Aqui está um avião ascii

--O--

Aqui está uma pista ascii

____|     |____

O avião começa em 5 novas linhas acima da pista. Para evitar conflitos entre os sistemas métrico e imperial e fazer deste um desafio verdadeiramente internacional, não mencionarei metros ou pés. Exemplo:

        --O--




____|     |____

O avião deve pousar exatamente no meio da pista, como mostrado abaixo:

____|--O--|____

Entrada

A posição horizontal inicial do plano é definida por uma entrada inteira que é usada para referenciar a ponta da asa esquerda, ou seja, está entre 0 e 10 inclusive.

Saída

Cada estágio do voo dos aviões deve ser mostrado. Exemplo abaixo (input = 10):

          --O--




____|     |____

         --O--



____|     |____

        --O--


____|     |____

       --O--

____|     |____

      --O--
____|     |____

____|--O--|____

Para simplificar, estamos ignorando as leis da perspectiva. A pista permanece do mesmo tamanho à medida que você se aproxima.

Regras

  • Atualizar O meio do plano pode ser maiúsculo ou minúsculo, mas o que for escolhido deve ser consistente em todo o código. Se o seu idioma não suportar os caracteres acima, sinta-se à vontade para usar caracteres alternativos ASCII.
  • O plano desce 1 linha por quadro.
  • O avião só pode mover 1 espaço para a esquerda ou direita cada vez que desce uma linha. Não precisa se mover em cada linha de descida. Desde que termine na pista, você decide quando se move para a direita ou para a esquerda. Você é o piloto!
  • Não é necessário tratamento de erros. Você pode assumir que a entrada sempre será um número inteiro válido de 0 a 10, inclusive.
  • A saída deve consistir apenas dos caracteres mostrados acima (se o seu idioma não os suportar, consulte a primeira regra editada) e deve ser do mesmo tamanho, ou seja, deve iniciar 6 linhas de altura por 15 caracteres de largura. A altura pode diminuir à medida que avança, como no exemplo acima.
  • Programa ou função é bom, mas deve produzir uma saída como mostrado acima.
  • Espaços iniciais / finais / novas linhas são ótimos para mim.
  • Sinta-se à vontade para limpar a tela entre os quadros de saída, se desejar. Isso não é um requisito.
  • Falhas padrão proibidas como de costume (embora eu não ache que haja muitas que ajudariam nesse tipo de desafio).
  • Esse é o código do código, portanto a resposta mais curta é obviamente a vencedora e provavelmente obterá a maioria dos votos, mas pode não ser necessariamente aceita como a melhor resposta se alguma solução realmente interessante surgir em algum idioma inesperado, mesmo que seja mais longo. Sinta-se livre para publicar qualquer coisa que atenda às regras, desde que funcione.

Implementação de referência ungolfed em Python 2 disponível em Experimente online! para que você possa ver como ele procura diferentes valores de entrada.


Eu não acho que é complexidade kolmogorov como a saída depende da entrada
ovs 18/01

Obrigado pelo esclarecimento @ovs. Vou remover essa etiqueta então.
ElPedro

Geralmente, a aceitação vai para a resposta que melhor se enquadra no Critério de Vencimento Objetivo. Você pode receber algumas críticas se aceitar outra resposta mais longa.
Level River St

Obrigado @LevelRiverSt. Existe uma meta post para esclarecer isso? Caso contrário, talvez seja melhor não aceitar nenhuma resposta.
ElPedro

Aliás, aceitei uma resposta mais longa antes e dei crédito à resposta mais curta, sem problemas do desafio anterior da comunidade . Por favor, veja o meu comentário Resultado no final da pergunta. Isso estava errado?
ElPedro

Respostas:


5

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

Você conhece um intérprete online ou um download (para Linux) para teste? +1 para a resposta supondo que ele funciona :)
ElPedro

Confira TilEm. É o único que eu poderia começar a trabalhar.
Julian Lachniet

2
+1 para perguntar a alguém que pode ter tido uma resposta diferente. Certamente confira o TilEm e obrigado pela dica.
ElPedro

8

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 que o TI-BASIC não suporta _ ou | e, portanto, substituí por um capital I e ​​-. Isso não deve afetar a contagem de bytes.


OK, estou no Linux. Você pode recomendar um download para testar isso? btw, eu suponho que funciona até que eu encontre um intérprete tão +1 :)
ElPedro

Infelizmente não. Eu tenho o Wabbitemu e o TilEm instalados no meu computador com Windows 10, mas testo o código em uma TI-84 + física. Desculpe
Proporção áurea

Sem problemas! Apenas pedindo :)
ElPedro

Devido a muita edição de código, o mais rápido alternou entre este post e o de Julian Lachniet, até que chegamos à conclusão de 60 bytes, altura em que adicionei clrhome e fiz contagem de bytes 62
Golden Ratio

3
TI-básico ?! Agradável!
Dave Kanter

6

Python 2, 107 bytes

n=input();h=5
while h:print' '*n+'--O--'+'\n'*h+'____|     |____\n';n-=cmp(n,5);h-=1
print'____|--O--|____'

Experimente online

Simplesmente codifica a última linha do avião de pouso. Provavelmente, você pode jogar golfe reutilizando peças de antes ou sendo integrado ao loop.


5

Perl, 94 bytes

93 bytes de código + -psinalizador.

$\="____|     |____
";$p="--O--";for$i(-5..-1){print$"x$_.$p.$/x-$i;$_+=5<=>$_}$\=~s/ +/$p/}{

Experimente online!


@ETHproductions Espero que você goste do }{(e da $"bagunça com o destaque da sintaxe).
Dada

3

JavaScript (ES6), 108 bytes

f=(a,b=5)=>b?" ".repeat(a)+`--O--${`
`.repeat(b)}____|     |____

`+f(a<5?a+1:a-1,b-1):"____|--O--|____"

Teste-o

Uso

Basta ligar fcom o índice do avião.

f(2)

Saída

  --O--




____|     |____

   --O--



____|     |____

    --O--


____|     |____

     --O--

____|     |____

    --O--
____|     |____

____|--O--|____

Você pode adicionar um trecho de pilha <s> lanche </s>
#

Toda vez que faço uma pergunta, a primeira resposta é Javascript! 1
ElPedro

Ei, seria legal se as pessoas postassem uma Tryitonline (não sei se isso é possível com Javascript) ou uma solução diferente para o exemplo 10 mostrado acima. Você pode postar a saída de, por exemplo, 2? :)
ElPedro

@ElPedro, você pode executar o JavaScript no console do navegador, mas também existem alguns consoles online. Vou adicionar um link. Eu também vou mudar o exemplo.
Lucas

Obrigado. Sem probs. Estou no antigo Javascript, onde você precisa de uma página da web para executá-lo. Acho que preciso acompanhar os horários :) Mais servidores atualmente. Respeito pela resposta rápida e legal.
ElPedro

3

Scala, 224181 bytes

Edição : Eu não tinha idéia que você poderia fazer "string"*npara repeti-lo n vezes! Scala continua me surpreendendo. Perder o em if(t>0)vez de if(t==0)foi um erro de novato. Obrigado pelas dicas, 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)}

Observações originais:

Eu achei que uma solução recursiva seria divertida de tentar. Sou relativamente novo no Scala, por isso tenho certeza de que isso está longe de ser o ideal.



Você não precisa do :Unit=. Omitir o sinal de igual definirá o tipo de retorno como Unidade.
precisa saber é o seguinte

Além disso, por que você não inicializou ona primeira linha? E como isempre é> = 0, você pode mudar i!=0&&i==tpara i>0&i==t(terceira linha).
precisa saber é o seguinte

2

Lote, 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é o número de espaços a serem removidos do início da string s, portanto subtraio o parâmetro de 10. A última linha é a que o Lote mais próximo tiver x-=sgn(x-5).


2

sed, 181 bytes + 2 para -nrsinalizadores

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

Uso: $ echo 2 | sed -nrf flightsim.sed


2

Retina , 86 83 bytes

.+
$* --O--¶¶¶¶¶¶____|     |____
{*`$
¶
2D`¶
 ( {5})
$1
}`^ {0,4}-
 $&
 +
--O--
G`_

Experimente online!

Provavelmente existe algum tipo de compactação que eu poderia ter usado na pista e o espaço vazio sobre ela, mas qualquer coisa que eu tentei saiu mais cara que o texto simples (no Retina ¶ é uma nova linha, é possível ver o estado inicial em texto simples no segunda linha).


2

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--|____")

Com base em outra resposta , com reduções significativas.


2

Perl 6 , 97 90 81 bytes

{say "{"{" "x 15}\n"x 5}____|     |____"~|("\0"x$^h+$_*(17-$h/5)~"--O--") for ^6}

Ao contrário do que parece, ele gera a * versão em minúscula do avião ( --o--), conforme permitido pela descrição da tarefa atualizada.

Experimente online!

Como funciona

Operadores de string bit a bit 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.
}

Funciona porque os operadores de cadeia de bits usam os valores de ponto de código dos caracteres em uma determinada posição em duas cadeias, para calcular um novo caractere nessa posição na cadeia de saída.
Nesse caso:

space  OR  O   =  o
space  OR  -   =  -
any    OR  \0  =  any

Para um Oplano em maiúsculas , poderíamos ter usado ~^(string bit a bit XOR), com uma máscara de plano de \r\ro\r\r(+4 bytes para barras invertidas):

space  XOR   o  =  O
space  XOR  \r  =  -
any    XOR  \0  =  any

A fórmula para o deslocamento do avião,, h + v*(17 - h/5)foi simplificada de:

  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

1

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

Experimente online!

Aqui está a implementação de referência que reduziu de 384 para 160 o 160. Acho que ainda há um caminho a percorrer. Apenas postado por diversão e para incentivar uma melhor resposta em Python.


Você pode competir em seu próprio desafio (consulte esta meta post ).
Dada

Você pode apenas fazer while-~x?
FlipTack

Além disso, eu acho que você pode escrever o pedaço de onde você adiciona ou subtrai icomoi+=(i<5)-(i>5)
FlipTack

1

Befunge-93, 136 130 bytes

&5>00p10p55+v
:::00g>:1-\v>:"____|     |_"
>:1-\v^\+55_$"--O--"10g
^\*84_$>:#,_10g::5v>:#,_@
<_v#!:-1g00+`\5\-`<^"____|--O--|____"

Experimente online!

Explicação

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

1

Ruby, 94 bytes

->a{5.times{|i|puts" "*a+"--O--#{?\n*(5-i)}____|     |____

";a+=5<=>a};puts"____|--O--|____"}

Imprime a posição do avião seguida por novas linhas e depois pelo aeroporto. Em seguida, move o plano em 1, -1 ou 0, dependendo da sua posição em relação a 5.

Depois de repetir as 5 etapas acima, ele imprime o avião no aeroporto.


1

8o , 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 ; 

A palavra fespera um número inteiro entre 0 e 10.

Uso

4 f

Explicação

: 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
;

1

Mathematica, 111 bytes

If[#<1,"____|--O--|____"," "~Table~#2<>"--O--"<>"
"~Table~#<>"____|     |____

"<>#0[#-1,#2+#2~Order~5]]&[5,#]&

Função anônima. Pega um número como entrada e retorna uma string como saída. Provavelmente poderia ser jogado ainda mais.


1

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

Descartou alguns bytes substituindo a declaração de X $; otimizou o loop FOR que imprime a distância acima do solo. A explicação abaixo é para a versão antiga, mas basicamente funciona da mesma maneira.

Para testes (e estética), eu tinha uma versão ligeiramente diferente, com 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

Estes são funcionalmente idênticos. O segundo acrescenta que a tela fica limpa entre os quadros e que para por 0,5 segundos entre os quadros.

Saída de amostra

Observe que eu adicionei duas novas linhas entre os quadros. O código mais jogado acima não adiciona linhas vazias entre os quadros; o mais frio limpa a tela.

Command line: 10


          --O--




____|     |____


         --O--



____|     |____


        --O--


____|     |____


       --O--

____|     |____


      --O--
____|     |____


____|--O--|____

Explicação

Como sinto que isso toca em muitas coisas de que realmente gosto no QBIC e fornece uma boa visão de como algumas de suas funções funcionam sob o capô, fiquei um pouco exagerado na explicação. Observe que o QBIC é, em sua essência, um intérprete QBasic para o Codegolf. O código QBIC entra - o código QBasic sai (e é executado posteriormente).

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

1

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$

1

PHP 7, 139 bytes

ainda muito longo

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

recebe entrada do argumento da linha de comando; corra com -r.

demolir

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.