One Line Aquarium


31

Meus sogros têm um viveiro de peixes no quintal, cheio de carpas. Isso realmente não passou pela minha cabeça até que notei o seguinte extrato do meu código.

',') & '_'

... Eu tinha caras de peixe olhando para mim da minha tela ...

O que me deu uma ótima idéia ...

Minha busca por você, meus queridos golfistas, é criar um aquário ASCII de uma linha, com as seguintes regras:

  • O tamanho do aquário do lado do tanque para o outro lado do tanque não deve ser menor que 60 caracteres e não maior que 80 caracteres. As laterais do tanque precisam ser indicadas usando o caractere pipe / bar ( |).
  • Os peixes devem ser capazes de "nadar" da esquerda para a direita entre as laterais do tanque. Como eles estão girando, é necessária uma vista frontal para a transição de uma direção para a outra.
  • O peixe deve ter a seguinte aparência:

    • }}< }} ',') Peixe nadando direito
    • (',' {{ >{{ Peixe nadando à esquerda
    • }}('_'){{ Peixe virado para a frente
  • Quando um peixe vira para mudar de direção (chance de 30%), ele deve começar de uma direção, ficar de frente para a frente e depois de outra direção ... Verifique se há um amplo espaço para o peixe virar, ou seja, exige seis espaços antes da partida. borda do tanque mínimo ...

  • A menos que um peixe esteja soprando uma bolha ou mudando de direção, ele continuará na direção em que está voltado; se ficar dentro de seis espaços ao lado do tanque, ele mudará de direção.
  • O peixe (voltado para a esquerda ou direita) pode ocasionalmente (10% de chance) parar de soprar bolhas sucessivamente ( .oO*), portanto, é necessário que o peixe tenha um espaço disponível próximo a ele para que a bolha exista, para que um peixe possa nade o mais próximo possível dos lados, economize um espaço. A bolha deve desaparecer antes que o peixe possa seguir em frente ...

Uma série de linhas de exemplo do comportamento do peixe, com -caracteres indicando os espaços, pois o recurso de exibição de código aqui é um pouco rigoroso ... Espero que esses traços sejam substituídos por espaços quando você codificar isso ...

Cada linha aqui pode ser considerada um quadro em lapso de tempo.

|-}}< }} ',')----------|
|--}}< }} ',')---------|
|---}}< }} ',')--------|
|----}}< }} ',')-------|
|-----}}< }} ',')------|
|-----}}< }} ',').-----|
|-----}}< }} ',')o-----|
|-----}}< }} ',')O-----|
|-----}}< }} ',')*-----|
|---------}}('_'){{----|
|-----------(',' {{ >{{|
|----------(',' {{ >{{-|
|---------(',' {{ >{{--|
|--------.(',' {{ >{{--|
|--------o(',' {{ >{{--|
|--------O(',' {{ >{{--|
|--------*(',' {{ >{{--|
|--------(',' {{ >{{---|
|-------(',' {{ >{{----|
|------(',' {{ >{{-----|

etc. O exemplo acima é, como eu disse, pequeno, mas você entende a ideia geral ...

O menor código vence ...

Estou esperando a saída na mesma linha (se possível), se não, exibir quadro após quadro em sucessão é bom ... Se você escolhe uma linha ou várias linhas, é com você. Se você estiver executando várias linhas, elas deverão ser separadas por uma nova linha.

Também é imposto um timer entre quadros, 2000ms. Isso é obrigatório .

Vamos ver o que você tem!


Se o peixe ficar muito perto da borda do aquário, é necessário virar ou ele pode sair da tela? É possível que o peixe faça bolhas nessa situação? Além disso, deve ser possível (ou é proibido, ou é permitido, mas não obrigatório) que o peixe faça bolhas duas vezes seguidas?
John Dvorak

1
Espere, não, não faça alterações como essa! Eu já comecei a codificar! Você se importaria de voltar?
John Dvorak

5
Por favor, use a caixa de areia da próxima vez.
John Dvorak

1
Não está explicitamente declarado, mas acho que deve haver exatamente um peixe no aquário?
John Dvorak

1
É necessário que a bolha de Maio de peixe duas vezes em sucessão, ou estamos autorizados a deixar que isso aconteça? Faz uma diferença de três caracteres para mim.
John Dvorak

Respostas:


11

Python 3 (278)

Anteriormente: 334, 332, 325, 302, 300, 299, 291, 286, 284, 281

import random,time
r=random.random
F="}}('_'){{%s","}}< }} ',')%s","%s(',' {{ >{{"
p,d=9,1
c=b=0
while 1:
 if c:p-=c+c*3*(2*d+c==1);d=c-c*d*d;c-=d
 elif b%5:b+=1
 elif.3>r()or{p*d}<{-5,53}:c=-d
 elif.1>r():b=1
 else:p+=d
 print('|%-70s|'%(' '*p+F[d])%' .oO*'[b%5]);time.sleep(2)

Jogar golfe em Python sempre é difícil devido aos requisitos de indentação das declarações, mas, apesar disso, isso foi incrivelmente bem!

Muito obrigado à Volatility e à DSM por me ajudarem a jogar isso muito mais longe.

Versão limpa

from random import random as r
from time import sleep as s
F = { 1: "}}< }} ',')%s", 0: "}}('_'){{%s", -1: "%s(',' {{ >{{" }

# p: position (from left)
# d: direction (-1: left, +1: right)
# c: changing direction (0: not changing, +1: to right, -1: to left)
# b: bubble (0)
p, d, c, b = 9, 1, 0, 0

while 1:
    if c:
        p -= c*[1,4][2*d+c==1]
        if d:
            d = 0
        else:
            d, c = c, 0
    elif b % 5:
        b += 1
    else:
        # change direction
        if r() < .3 or p * d in (-5,53):
            c = -d
        # start bubbling
        elif r() < .1:
            b = 1
        # move forward
        else:
            p += d

    # print fish and sleep
    print('|{:<70}|'.format(' '*p+(F[d]%' .oO*'[b%5])))
    s(2)

7

Rubi, 291 289

l="(',' {{ >{{";m="    }}('_'){{    ";r="}}< }} ',')";w=?\s;s=w*6;q="|#{r+s*9}|"
f=->*s{(puts q;sleep 2)if q.sub! *s}
loop{rand>0.1||(f[") ",")."]||f[" (",".("];f[?.,?o];f[?o,?O];f[?O,?*];f[?*,w])
q[7]==?(||q[-8]==?)||rand<0.3?f[s+l,m]&&f[m,r+s]||f[r+s,m]&&f[m,s+l]:f[w+l,l+w]||f[r+w,w+r]}

O peixe tem onze caracteres, tornando o aquário com 6 * 9 + 11 + 2 = 67 caracteres, o que se encaixa perfeitamente na tolerância exigida.

A ffunção lambda faz todo o trabalho pesado: aceita uma substituição como um par de argumentos e tenta aplicar a substituição no aquário. Se for bem-sucedido, ele pintará um quadro da animação. Em seguida, ele informa o valor de sucesso como 2(o atraso recebido) ou nil(atraso não executado).

O peixe não soprará bolhas duas vezes seguidas. (Correção: ...while rand>0.1- 4 caracteres)

O peixe pode soprar bolhas antes mesmo de uma curva forçada. (Correção: reorganize a estrutura de ramificação)

Há um quadro em que a bolha desapareceu completamente (incluindo o *), mas o peixe não se moveu para o vazio resultante. Isso segue a letra, mas não o exemplo. (Corrigir: substituir f[?*,w]por q[?*]=w- grátis)

Não limpa o console. Correção: adicione `clear`(Unix) ou system 'cls'(console do Windows) antes puts qpara corrigir ( Ref. ) Ou use em printvez de putse adicione \r-o ao aquário ( sugerido por @manatwork ).

Versão legível:

# l - left fish; m - middle fish + space; r - right fish
# w - single space character; s - six spaces; q - the aquarium
l="(',' {{ >{{"; m="    }}('_'){{    "; r="}}< }} ',')";
w=" "; s=w*6; q="|#{r+s*9}|"
f = ->k,v do
  if q.sub! k,v
    puts q
    sleep 2
    return 2
  else
    return nil
  end
end

loop do
  if rand < 0.1
    f[") ",")."] || f[" (",".("]
    f[?.,?o]; f[?o,?O]; f[?O,?*]; f[?*,' ']
  end
  if q[7] == "(" || q[-8] == ")" || rand < 0.3
    (f[s+l,m] && f[m,r+s]) || (f[r+s,m] && f[m,s+l])
  else
    f[w+l,l+w] || f[r+w,w+r]
  end
end

Eu acrescentaria \rpara o início do q: q="\r|#{r+s*9}|". Em seguida, use em $><<qvez de puts q. Tem 1 caractere mais, mas fica melhor sem usar comandos externos.
precisa saber é

\rlimpa a tela? Não acontece no meu caso. Ou, por que você não gosta puts?
John Dvorak

1
Não, \ré retorno de carro. Ao usar $><<qpara saída, o cursor permanecerá na mesma linha ( putsforça a \napós a saída); assim, iniciar a próxima saída com \rretornará ao início da linha atual e começará a sair a partir daí. Assim, substitui a "imagem" anterior da linha de aquário.
precisa saber é

Infelizmente, isso atrapalha completamente a janela interativa do jRuby, que ignora o \r.
John Dvorak

Oh. Desculpe ouvir isso. E obrigado pela informação. Infelizmente, este é o primeiro fato que aprendi sobre o jRuby. :(
manatwork

3

R, 451 caracteres

Uma primeira tentativa:

f=function(j,p){cat("\r|",rep("-",j),p,rep("-",50-j),"|",sep="");Sys.sleep(2)};d=F;j=5;P=c("--}}(\'_\'){{--","-}}< }} \',\')-","-(\',\' {{ >{{-");B=c("-",".","o","O","*","-");g=Vectorize(gsub,v="replacement");b=list(g("-$",B,P[2]),g("^-",B,P[3]));repeat{if(j<5 & d){d=!d;j=j+1;f(j,P[1])};if(j>44 & !d){d=!d;f(j,P[1]);j=j-1};if(runif(1)<.1){for(i in b[[d+1]])f(j,i)}else{f(j,P[d+2])};if(runif(1)<.3){d=!d;f(j,P[1]);f(j,P[d+2])};if(d){j=j-1}else{j=j+1}}

Recuado:

f=function(j,p){ #Printing function (depends of buffer and kind of fish)
    cat("\r|",rep("-",j),p,rep("-",50-j),"|",sep="")
    Sys.sleep(2)
}
d=F   #Direction: if FALSE left to right, if TRUE right to left.
j=5   #Buffer from left side of tank
P=c("--}}(\'_\'){{--","-}}< }} \',\')-","-(\',\' {{ >{{-") #The fish
B=c("-",".","o","O","*","-") #The bubble sequence
g=Vectorize(gsub,v="replacement")
b=list(g("-$",B,P[2]),g("^-",B,P[3])) #Fish+bubble
repeat{
    if(j<5 & d){ #What happens if too close from left side
        d=!d
        j=j+1
        f(j,P[1])
        }
    if(j>44 & !d){ #What happens if too close from right side
        d=!d
        f(j,P[1])
        j=j-1}
    if(runif(1)<.1){ #If bubble sequence initiated
        for(i in b[[d+1]])f(j,i)
        }else{f(j,P[d+2])} #Otherwise
    if(runif(1)<.3){ #If fish decide to turn
        d=!d
        f(j,P[1])
        f(j,P[d+2])
    }
    if(d){j=j-1}else{j=j+1} #Increment or decrement j depending on direction
}

Ele imprime o aquário como stdout em uma única linha (em seguida, 2s são interrompidos e o retorno de carro antes que o aquário em t + 1 seja impresso).


3

Perl, 281

@f=("s O(',' {{ >{{","s}}('_'){{s","}}< }} ',')O s");$d=1;@o=split//," *Oo. ";{$_="|".$"x$x.$f[$d+1].$"x(44-$x).'|
';s/O/$o[$b]/;s/s/    /g;print;if($b||$t){$b--if$b;if($t){$d+=$t;$t=0if$d}}else{$x+=$d;$t=($x<1)-($x>43);if(!$t){$b=5if.9<rand;if(.7<rand){$t=-$d;$b=0}}}sleep 2;redo}

ou mais claramente

@f = ( "s O(',' {{ >{{", "s}}('_'){{s", "}}< }} ',')O s" );
$d = 1;
@o = split //, " *Oo. ";
{
    $_ = "|" . $" x $x . $f[ $d + 1 ] . $" x ( 44 - $x ) . '|
';
    s/O/$o[$b]/;
    s/s/    /g;
    print;
    if ( $b || $t ) {
        $b-- if $b;
        if ($t) { $d += $t; $t = 0 if $d }
    }
    else {
        $x += $d;
        $t = ( $x < 1 ) - ( $x > 43 );
        if ( !$t ) {
            $b = 5 if .9 < rand;
            if ( .7 < rand ) { $t = -$d; $b = 0 }
        }
    }
    sleep 2;
    redo
}

Peixe girando corretamente. Bolhas soprando.

285 - se você gosta da sensação real do aquário e não da versão de rolagem:

$|=@f=("s O(',' {{ >{{","s}}('_'){{s","}}< }} ',')O s");$d=1;@o=split//," *Oo. ";{$_="\r|".$"x$x.$f[$d+1].$"x(44-$x).'|';s/O/$o[$b]/;s/s/    /g;print;if($b||$t){$b--if$b;if($t){$d+=$t;$t=0if$d}}else{$x+=$d;$t=($x<1)-($x>43);if(!$t){$b=5if.9<rand;if(.7<rand){$t=-$d;$b=0}}}sleep 2;redo}

Onde você vira? Não vejo você definindo $d=0no caso "rotação necessária".
John Dvorak

1
sleep2(sem espaço) não está funcionando para mim; Além disso, quando você está girando, não mantém a cara do peixe alinhada. E as bolhas parecem nunca aparecer.
cutuca

"Também é imposto um timer entre quadros, 2000ms. Isso é obrigatório." - isso não acontece para mim. Além disso, as bolhas não aparecem, o peixe simplesmente fica no lugar. Além disso, a cabeça deve permanecer no local enquanto o peixe está girando, não o centro do corpo (pelo menos é o que mostra o exemplo)
John Dvorak

Drat! Golfed muito duro. Precisa de um espaço extra com o sono! O peixe estava borbulhando muito bem também! aguarde ...
KevinColyer

Oops - esqueci o chefe no meio ao girar nas bordas - necessidade algum retrabalho ...
KevinColyer

2

C, 400 394 373 caracteres

#define p printf
#define a(x) l[5]=r[11]=x;d();
char *l="      (',' {{ >{{",*f="    }}('_'){{    ",*r="}}< }} ',')      ",*c,s=7,i,*T;d(){p("|");for(i=0;i<s;i++)p(" ");p(c);for(i=0;i<70-s;i++)p(" ");puts("|");sleep(2);}b(){a(46)a(111)a(79)a(42)a(32)}t(){T=c;c=f;d();c=T==r?l:r;d();}m(){c==l?s--:s++;d();s>69||s<1?t():0;}main(){c=r;for(d();;)i=rand()%10,i?i>6?t():m():b();} 

Com espaço em branco:

#define p printf
#define a(x) l[5]=r[11]=x;d();
char *l="      (',' {{ >{{",
     *f="    }}('_'){{    ",
     *r="}}< }} ',')      ",
     *c, 
     s=7,
     i,  
    *T; 
d(){
  p("|");
  for(i=0;i<s;i++)
    p(" ");
  p(c);
  for(i=0;i<70-s;i++)
    p(" ");
  puts("|");
  sleep(2);
}
b(){
  a(46)
  a(111)
  a(79)
  a(42)
  a(32)
}
t(){
  T=c;
  c=f;
  d();
  c=T==r?l:r;
  d();
}
m(){
  c==l?s--:s++;
  d();
  s>69||s<1?t():0;
}
main(){
  c=r;
  for(d();;)
    i=rand()%10,
    i?i>6?t():m():b();
}

1
Pode i==l?(c=r):(c=l)ser reduzido para c=i==l?r:l?
John Dvorak

Parece que pode ser. Obrigado!
Josh Josh

Você pode salvar alguns caracteres por#define p printf(
user12205

O @Ace gcc não gosta quando faço isso.
Josh Josh

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.