The Random Walker Printer

24

Desenhe um programa ou função que escreva às STDOUT nvezes (cada uma para uma etapa) uma sequência que contenha um ponto .no local do caminhante. O programa também precisa escrever uma linha a cada ssegundo (ou esperar ssegundos após cada linha).

Uma caminhada aleatória é uma formalização matemática de um caminho que consiste em uma sucessão de etapas aleatórias ( wiki ), de modo que cada nova etapa será a última etapa mais um novo valor, portanto, qualquer tvalor de etapa é apenas a soma de todos os valores aleatórios antes de ir mais o valor inicial.

O programa deve receber 2 entradas e usará apenas espaços " "e pontos "."na saída. O valor inicial do andador será 20tal que a saída deve ser um ponto após 19 espaços.

                  . #19 spaces then a dot

A cada nova etapa, o valor será o último valor do caminhante mais um deles [-2-1,0,1,2](20% de chance cada). Após a impressão da nova posição, o programa deve aguardar ssegundos e avançar para a próxima etapa. Se a etapa levar o andador fora do alcance, 1 to 40ele deve ser ignorado e a posição do caminhante permanece a mesma. O número de espaços sempre será um número de 0 a 39.

Exemplo

#input
Mywalk(s = 0.1, n = 30)

#output
                     .
                    .
                      .
                        .
                          .
                           .
                            .
                          .
                         .
                          .
                           .
                            .
                           .
                          .
                           .
                           .
                         .
                         .
                          .
                            .
                           .
                          .
                           .
                           .
                           .
                         .
                          .
                         .
                          .
                          .

Considerações

  • Você pode considerar a entrada como qualquer formato razoável

  • O código mais curto vence

  • Tudo bem se o seu programa aceitar apenas os segundos como números inteiros

Mutador
fonte
2
Eu assumo né o número de etapas?
ASCIIThenANSI
Sim, eu esclareci isso, obrigado.
Mutador
Eu acho que você deveria dizer que o intervalo é 1 to 40, porque o número de espaços é sempre position-1.
geokavel
@geokavel que parece melhor, fixo!
Mutador
10
Desenhe um programa ??? ;-)
Digital Trauma

Respostas:

6

Pyth, 39

J19VEK+.d0QW<.d0K)+*d=JhtS[Z39-+O5J2)\.

Toma scomo a primeira linha de entrada e ncomo a segunda. Funciona na linha de comando, mas não com o intérprete online. Meu primeiro programa Pyth de todos os tempos! Dicas de golfe são apreciadas.

Luke
fonte
Bem-vindo ao Pyth! A única dica de golfe que posso ver é que você pode usar Qe Epara as duas entradas em vez de fo hQe eQ, se você separar as entradas de uma nova linha.
Isaacg
13

Matlab, 112

A idéia central é gerar uma lista de possíveis próximas posições e depois desenhar uniformemente uma delas. Se estivermos, por exemplo, na posição $ l = 1 $, as etapas possíveis seriam [-1,0,1,2,3]Obviamente, se escolhermos -1que seria inválido e teríamos que permanecer na mesma posição. É por isso que substituímos as posições inválidas pela posição atual [1,0,1,2,3]e, em seguida, escolhemos aleatoriamente um elemento dessa lista atualizada.

O OP nos pediu para desenhar o programa, então vamos lá:

insira a descrição da imagem aqui

A transcrição:

function c(n,s);
l=19;                             %initialize position
for k=1:n;                          
    disp([ones(1,l)*32,'.']);     %print the line
    z=(-2:2)+l;                   %get vector of possible next steps (for l=1 we get [-1,0,1,2,3])
    z(z<0)=l;                     %prune invalids: here we just replace the the invalid positions with the current position
    z(z>39)=l;                    %   this ensures the same behaivour as staying in the same spot when going outside of the range
    l=z(randi(5));                %draw random sample of those
    pause(s);
end
flawr
fonte
11
-1 usa MathJax em um ambiente que não seja MathJax;)
Conor O'Brien
2
Oo Você sabe, equações que não são escritas em látex não são tão confiáveis, elas podem até não ser verdadeiras! Melhor estar do lado seguro.
flawr
3
Programas elaborados deve ser medido em volume de tinta, em vez de bytes ...
Darrel Hoffman
8

Perl, 136 128 116 106 101 90 86

$p=19;map{say$"x$p.".";sleep $ARGV[0];$x=rand(5)+$p-2;$p=$x>0&&$x<40?$x:$p}1..$ARGV[1]

Requer que os segundos sejam um número inteiro.

Corra com perl <filename> <second delay> <number of steps>.

Pode haver mais potencial de golfe aqui, embora, honestamente, estou surpreso que tenha chegado tão longe. (Vamos lá, apenas mais 6 bytes para vencer a resposta do bash ...)

Alterar

  • Economizou 8 bytes removendo parênteses desnecessários e explicando o ARGV (na verdade, é mais curto dessa maneira)
  • Economizou mais 12 bytes removendo $se $nusando apenas a planície $ARGV[0]e$ARGV[1]
  • Salvei mais 10 bytes quando percebi que podia usar $"e não precisava definir especificamente $ucomo $undef.
  • Economizou mais 5 bytes reorganizando o ternário e como $xé usado e usando em mapvez de for.
  • Salva 11 bytes, deixando de aceitar os segundos como decimais (a especificação do desafio diz que está tudo bem.)
  • Salvo outros 5 bytes usando em sayvez de print.
ASCIIThenANSI
fonte
6

Python 2, 124 119 bytes

@janrn e @Steve Eckert: não tenho reputação suficiente para comentar sua resposta, mas aqui está sua versão resumida. A tarefa é desenhar um programa ou uma função ; portanto, f(s,x)você pode salvar alguns bits e também max(0,min(x,39))evitar uma ifcláusula extra . Resolvi:

import time,random as r
def f(s,x):
 n=19
 while x:print' '*n+'.';time.sleep(s);n=max(0,min(n+r.randint(-2,2),39));x-=1
ბიმო
fonte
5

Bash, 81

for((s=20;i++<$1;t=s,s+=RANDOM%5-2,s=s<0|s>39?t:s)){
printf %${s}s.\\n
sleep $2
}

Editar: Se a etapa levar o andador para fora do intervalo de 1 a 40, ele deverá ser ignorado e a posição do andador permanecerá a mesma manipulada corretamente.

Entrada de opções de linha de comando. Por exemplo:

$ ./randwalk.sh 5 0.5
                    .
                     .
                    .
                  .
                 .
$ 
Trauma Digital
fonte
4

Ruby, 84

def w(s,n)q=19;n.times{puts ' '*q+'.';sleep s;q+=rand(5)-2;q=[[q,0].max,39].min};end
gryzelda
fonte
4

Python 2.7, 198 162 143 133

import time,random as r;p=20;s=0;d=input();w=input()
while s<d:
 print' '*p+'.';s+=1;p=max(1,min(p+r.randint(-2,2),40));time.sleep(w)

Ao chamar o script python script.py, a primeira entrada é a quantidade de etapas; a segunda entrada, o tempo entre as etapas (aceita float ou int). Alguma sugestão para melhorar?

Edições

  • salvou 36 bytes devido ao uso no momento print ' '*p+'.', graças a @corsiKlause Ho Ho Ho
  • para baixo outros 19 bytes removendo os recuos da guia, substituindo-os por um espaço ou sempre ;que possível
  • 10 bytes menos graças à ideia @Bruce_Forte com p=max(1,min(p+r.randint(-2,2),40))(não posso comentar sua resposta também, mas obrigado; não quero copiá-la completamente)
janrn
fonte
Em Python, você não pode simplesmente ' '*prepetir a string?
corsiKa
Na verdade sim, não sabia disso. Editando agora, obrigado
janrn 18/12/2015
4

Processamento, 150 147

void w(int n,int s){int x=20,i,y,c=0;for(;c<n;c++){x+=y=int(random(5)-2);if(x>40||x<0)x-=y;for(i=1;i<x;i++)print(" ");println(".");delay(s*1000);}}

Uso:

void setup() {
    w(10,1);
}

Nota: 1000não pode ser alterado para 1e3por motivos de tipo.

geokavel
fonte
3

Lua, 140 bytes

Nota: Este programa requer o pacote LuaSocket.

require"socket"p=19 for i=1,arg[2]+0 do print((" "):rep(p)..".")p=p+math.random(-2,2)p=p<0 and 0 or p>39 and 39 or p socket.sleep(arg[1])end
Nikolai97
fonte
3

Perl 6 , 92 bytes

my (\n,\s)=@*ARGS;$/=19;for (-2..2).roll(n) {put ' 'x($/+=(40>$/+$_>=0??$_!!0)),'.';sleep s} # 92
my (\n,\s)=@*ARGS;
$/=19;
for (-2..2).roll(n) {
  put ' 'x($/+=(40>$/+$_>=0??$_!!0)),'.';
  sleep s
}

Uso:

$ perl6 -e 'my (\n,\s)=@*ARGS;$/=19;for (-2..2).roll(n) {put " "x($/+=(40>$/+$_>=0??$_!!0)),".",;sleep s}' 10 0.001
                  .
                .
               .
              .
               .
                .
               .
                .
                  .
                 .
Brad Gilbert b2gills
fonte
3

JavaScript (ES6), 125 bytes

(s,n)=>(t=setTimeout)(c=`console.log(" ".repeat(p)+".");p+=m=Math.random()*5|0;p-=p>41|p<2?m:2;--i&&t(c,d)`,d=s*1e3,p=19,i=n)

Explicação

(s,n)=>
  (t=setTimeout)(                     // set inital timeout
    c=`                               // c = code for timeout to execute
      console.log(" ".repeat(p)+"."); // print the current line
      p+=m=Math.random()*5|0;         // move walker 0 - 4 positions to the right
      p-=p>41|p<2?                    // if walker was moved out of bounds (2 - 41 instead
                                      //     of 0 - 39 because the random move of 0 - 4 to
                                      //     the right has not had the 2 subtracted yet)
        m:                            // undo the move
        2;                            // else subtract 2 to make the move -2 to 2
      --i&&t(c,d)                     // while we have steps remaining schedule next one
    `,
    d=s*1e3,                          // d = milliseconds to wait between steps
    p=19,                             // p = position of walker (0 indexed)
    i=n                               // i = steps remaining (needed to make n global)
  )

Teste

user81655
fonte
3

k4, 61 caracteres

f:{y{-1((y:1|40&y+-2+*1?5)#" "),".";."\\sleep ",$x;y}[x]\20;}

amostra de execução:

  f[.1]30
                      .
                    .
                    .
                   .
                   .
                  .
                  .
                   .
                   .
                     .
                    .
                  .
                  .
                    .
                   .
                   .
                 .
                .
               .
               .
              .
            .
          .
         .
         .
          .
            .
              .
              .
                .
Aaron Davies
fonte
3

Mathematica, 122 117 bytes

$RecursionLimit=∞;If[#2>0,Print[Indent[a=Min[#3+RandomInteger@{-2,2},39]~Max~0],"."];Pause@#;#0[#,#2-1,a]]&[##,19]&

Função anônima recursiva, recebe entrada na ordem especificada. Provavelmente poderia ser jogado ainda mais.

LegionMammal978
fonte
2

Python 3, 154 bytes

import time
from random import*
w=int(input())
z=int(input())
g=19
c=6
s=" "
while c:
    c-=1
    s+=s
while z:
    z-=1
    if -1<g<40:
        print(s[:g]+'.')
    time.sleep(w)
    g+=randint(-2,2)

Gere uma sequência de espaços maior que o comprimento máximo necessário, imprima APENAS essa sequência até o caractere no índice 'g' e, em seguida, imprima um '.'. Finalize incrementando g por um valor aleatório no intervalo [-2: 2] e repita.

Se alguém pudesse me ajudar a jogar golfe naquele bloco horrível de entrada, eu agradeceria.

Steve Eckert
fonte
Para jogar golfe, por que não usar sys.argv?
ASCIIThenANSI
11
Além disso, em vez de while z:, por que não usar for i in range(1,z)?
ASCIIThenANSI
Estou curioso, como você conseguiu que isso seja 154 bytes? bytesizematters.com dá uma contagem diferente (mesmo se você desativar a contagem de espaço em branco)
p1xel
@ASCIIThenANSI: Hmm ... no momento em que adiciono a chamada inicial sys.argve a importação, não consigo ver como posso salvar os bytes fazendo isso. E mesmo com as linhas extras para declarar cdepois decréscimo ce z, ainda é mais barato do que fazê-lo desta forma, pelas minhas contas.
21815 Steve Eckert #
@ p1xel: contei os espaços em branco internos à linha, mas não os espaços em branco à esquerda ou à direita. Existe um padrão de pontuação diferente que eu desconheço?
Steve Eckert
1

Função C, 114

s=20,i,t;w(int n,float f){for(;i++<n;t=s,s+=rand()%5-2,s=s<0||s>39?t:s,usleep((int)(f*1e6)))printf("%*c.\n",s,0);}

Praticamente uma tradução direta da minha resposta bash .

Programa de teste completo:

s=20,i,t;w(int n,float f){for(;i++<n;t=s,s+=rand()%5-2,s=s<0||s>39?t:s,usleep((int)(f*1e6)))printf("%*c.\n",s,0);}

int main (int argc, char **argv) {
  w(10, 0.2);
  return 0;
}
Trauma Digital
fonte