Faça uma pausa para fazer uma cobra!

23

Nossa cobra clássica desenvolveu um desequilíbrio dos hormônios do crescimento . Para piorar, seu rabo está congelado no lugar! Dada a entrada direcional conforme especificado em Figure 1, escreva um programa para determinar onde ele crescerá.

wasd

Figura 1. Entrada direcional.

Especificações do programa

  • Leia o caractere de entrada por caractere STDIN.
  • Depois de ler um personagem, coloque a cobra na STDOUT. Inclua uma linha em branco entre cada vez que imprimir uma cobra.
  • A cobra consiste em <>v^e uma cabeça. A cabeça da serpente pode ser qualquer personagem rodada de sua escolha, como o, 0, O, ou .
  • Qualquer combinação de wasdé válida para entrada.
  • Seu programa não deve assumir que a entrada esteja dentro de um determinado comprimento.
  • A cobra pode se sobrepor, sobrescrevendo <>v^. Veja exemplos de mecânica de crescimento de cobras.
  • O espaço em branco à direita é bom, mas sua cobra deve parecer correta.

Pontuação

Isso é . Sua pontuação é o número de caracteres no seu programa. Menor pontuação ganha!

Cobras de exemplo:

Entrada: ddddssaassdddddww

Saída:

>>>>v
    v
  v<<  ☺
  v    ^
  >>>>>^

Entrada: dddsssaaawww

Saída:

☺>>v
^  v
^  v
^<<<

Entrada: dddsssdddddasddddwww

Saída:

>>>v
   v       ☺
   v       ^
   >>>>v<  ^
       >>>>^

Entrada: dddwwdddssssaaaaaaaaawww

Saída:

      >>>v
☺     ^  v
^  >>>^  v
^        v
^<<<<<<<<<

Entrada: ddddssssaawwddddd

Saída:

>>>>v
    v
  >>>>>☺
  ^ v
  ^<<

Entrada: dddddssaawwwwddddd

Saída:

   >>>>>☺
   ^
>>>^>v
   ^ v
   ^<<

Entrada:

ddddaaaasssssdddddddddddwwwwwaaaasssssdddddddddddwwwwwwwwwwsssssaaaasssssdddddddwwwwwddddssaaaasssddddaaaassssssssssdddwwwwwwwddddswaaaassssddaasssaaaaaaaaaawwwwddddssssaaaaaaaaaaawwwwddddsssssssssaaaa

Saída:

                  v
                  v
                  v
                  v
                  v
v<<<<  v<<<<  v<<<<  >>>>v
v      v   ^  v   ^  ^   v
v      v   ^  v   ^  v<<<<
v      v   ^  v   ^  v
v      v   ^  v   ^  v
>>>>>>>>>>>>>>>>>>>>>v<<<<
                     v
                     v
                     v  v<<<<
                     v  v   ^
                     v  v
       >>>>v  >>>>v  v  v
       ^   v  ^   v  v  v<<
       ^   v  ^   v  v  v
       ^   v  ^   v  v  v
       ^<<<v<<<<<<<<<<<<<
           v
           v
           v
           v
       O<<<<
hmatt1
fonte
8
Muito agradável. Mas ... WTH é um "código gofl"?
John Dvorak
2
Eu me livraria do bônus, pois é muito fácil criar sua própria serpente e string de entrada.
Beta Decay
1
@JanDvorak rotfl my bad.
precisa saber é
1
@BetaDecay a escala do avião. No exemplo de código de golfe, ele começou no canto superior esquerdo do c, mas, como d é mais alto, ele se move para baixo.
precisa saber é o seguinte
2
@chilemagic Obrigado! Se ambos forem aceitáveis, você provavelmente deve esclarecer isso na pergunta.
Ingo Bürk

Respostas:

5

Ruby, 207 caracteres

b=[];x=y=0;gets.chars{|c|b[y]||=[];b[y][x]={?\n=>->{?0},?w=>->{y>0?y-=1:b=[[]]+b;?^},?a=>->{x>0?x-=1:b.map!{|r|[' ']+r};b[y][1]=?<},?s=>->{y+=1;?v},?d=>->{x+=1;?>}}[c][]};puts b.map{|r|r.map{|c|c||' '}.join}

Ungolfed:

b=[]  #board
x=y=0 #position
gets.each_char{|c|
  b[y] ||= []
  b[y][x] = {
    "\n" => lambda{0},
    "w"  => lambda{if y>0 then y-=1 else b=[[]]+b; "^"},
    "a"  => lambda{if x>0 then x-=1 else b.map!{|r|[' ']+r}; b[y][1]="<"},
    "s"  => lambda{y+=1; "v"},
    "d"  => lambda{x+=1; ">"}
  }[c].call}
puts b.map{|r|r.map{|c|c||' '}.join}

(o lambda para agravações de volta porque a linha na qual a atribuição acima grava não está mais no quadro)

John Dvorak
fonte
11

ECMAScript 6 Javascript (399 401 431 )

Precisa ser executado em um navegador compatível com o ECMAScript 6 devido às funções de seta.

Aqui estão as violações que foram alteradas para serem executadas em qualquer navegador (comum), não usando as funções de seta. Eles também imprimem em um textarea:

Versão Golfed

i=prompt(),v=[],c=0,x=[0],y=[0],s='unshift',k='slice',t='sort',h=[0,-1,0,1,0]
while(c<i.length){m='wasd'.indexOf(i[c++]);v[s]('^<v>'[m]);x[s](x[0]+h[m]);y[s](y[0]+h[m+1])}f=(a,b)=>a-b
q=x[k]()[t](f)[0],e=x[k]()[t]((a,b)=>b-a)[0],w=y[k]()[t](f)[0],o=[]
while((i=y.pop())!=null){i-=w;j=x.pop()-q;t=(o[i]||Array(e+1-q).join(" ")).split("");t.splice(j,1,v.pop()||"@");o[i]=t.join("")}alert(o.join("\n"))

Gif Animado:

Um dos exemplos do OP:

insira a descrição da imagem aqui

O exemplo do Stretch Maniac :

insira a descrição da imagem aqui

Ungolfed

Aqui está uma versão (ligeiramente) ungolfed de algum tempo antes de eu começar realmente a jogar:

var input = prompt(),
    values = [],
    c = 0,
    x = [0],
    y = [0],
    s = 'unshift';
while (c < input.length) {
    var mapped = 'wasd'.indexOf(input[c++]);
    values[s]('^<v>'[mapped]);
    x[s](x[0]+[0, -1, 0, 1][mapped]);
    y[s](y[0]+[-1, 0, 1, 0][mapped]);
}

var minX = x.slice().sort(function (a,b){return a-b})[0];
var maxX = x.slice().sort(function (a,b){return b-a})[0];
var minY = y.slice().sort(function (a,b){return a-b})[0];

var output = [];
while((i=y.pop())!=null) {
    i-=minY;
    j=x.pop()-minX;
    t=(output[i]||Array(maxX+1-minX).join(" ")).split("");
    t.splice(j,1,values.pop()||"@");
    output[i]=t.join("");    
}

console.log(output.join("\n"));
Ingo Bürk
fonte
Os gifs são muito legais. Eles são feitos automaticamente, por um script que você escreveu?
AndoDaan
1
Obrigado! Com o poder do Google, apenas procurei como fazer um presente a partir de uma gravação de tela no Ubuntu. Ele apenas usa um gravador de tela e convert. Muito fácil :)
Ingo Bürk
3
(gif, não presente)
Ingo Bürk
8

sed, 71

s/w/\^\x1B[D\x1B[A/g
s/a/<\x1B[2D/g
s/s/v\x1B[B\x1B[D/g
s/d/>/g
s/$/@/

Golfscript, 165 126

' '*"\33[":e{e'D'}:-{[e'C'+'<'--]]}:a{[-+'>']]}:d{[e'B'+'^'-e'A']]}:w{[e'A'+'v'-e'B']]}:s{][\[}:+7{;}*''\~[e'H'e'J']\'@'e'20H'

A mesma abordagem da minha resposta anterior, mas posicionando corretamente o cursor antes e depois. Estou bastante orgulhoso da abordagem ao posicionamento do cursor - basicamente, ele primeiro executa a cobra ao contrário, sem imprimir caracteres.

Sneftel
fonte
1
Você pode adicionar um exemplo de chamada? echo "dddddssaawwwwddddd" | sed -e 's/w/\^\x1B[D\x1B[A/g' -e 's/a/<\x1B[2D/g' -e 's/s/v\x1B[S\x1B[D/g' -e 's/d/>/g' -e 's/$/@/'não dá a saída correta para mim.
Ingo Bürk
Seu prompt após a execução provavelmente está substituindo parte da cobra. Cole a cobra diretamente no stdin, em vez de na tubulação, ou adicione alguns \ns após o @comando para que o prompt vá para outro lugar.
Sneftel 31/08/14
1
Isso pode falhar se a cobra subir ou sair da prancha.
tomsmeding
@tomsmeding Sim, eu posso expandi-lo para lidar com isso. Linguagem à parte, porém, eu realmente acho que as seqüências de controle ANSI são o caminho a seguir para obter um código mais curto.
Sneftel 31/08/14
3

Java - 646

Pode muito bem ser o primeiro!

Aposto que todos podem vencer isso.

un (tipo de) jogou golfe

import java.util.*;
public class Snake{
    public static void main(String[]a) {
        int x,y,minX,minY,maxX,maxY;
        x=y=minX=maxX=minY=maxY=0;
        List<Integer>xs,ys=new ArrayList<Integer>();
        xs=new ArrayList<Integer>();
        List<Character>p=new ArrayList<Character>();
        for(int b=0;b<a[0].length();b++){
            int newX=x,newY=y;
            switch(a[0].charAt(b)){
            case'a':newX--;p.add('<');break;
            case's':newY++;p.add('v');break;
            case'd':newX++;p.add('>');break;
            case'w':newY--;p.add('^');break;
            }
            xs.add(x);ys.add(y);
            x=newX;y=newY;
            if(x<minX){minX=x;}
            if(x>maxX){maxX=x;}
            if(y<minY){minY=y;}
            if(y>maxY){maxY=y;}
        }
        char[][]c=new char[maxY-minY+1][maxX-minX+1];
        for(int i=0;i<xs.size();i++)c[ys.get(i)-minY][xs.get(i)-minX]=p.get(i);
        c[y-minY][x-minX]='@';
        for(char[]k:c){for(char l:k){System.out.print(l);}System.out.println();}
    }
}

Menor -

import java.util.*;class S{public static void main(String[]a){int x,y,o,z,s,u;x=y=o=s=z=u=0;List<Integer>j,t=new ArrayList<Integer>();j=new ArrayList<Integer>();List<Character>p=new ArrayList<Character>();for(int b=0;b<a[0].length();b++){int e=x,r=y;switch(a[0].charAt(b)){case'a':e--;p.add('<');break;case's':r++;p.add('v');break;case'd':e++;p.add('>');break;case'w':r--;p.add('^');break;}j.add(x);t.add(y);x=e;y=r;if(x<o)o=x;if(x>s)s=x;if(y<z)z=y;if(y>u)u=y;}char[][]c=new char[u-z+1][s-o+1];for(int i=0;i<j.size();i++)c[t.get(i)-z][j.get(i)-o]=p.get(i);c[y-z][x-o]='@';for(char[]k:c){for(char l:k){System.out.print(l);}System.out.println();}}}

input - dddsssdddwwwwaaaaaaaassssssssssddddddddddddddddd

v<<<<<<<<         
v >>>v  ^         
v    v  ^         
v    v  ^         
v    >>>^         
v                 
v                 
v                 
v                 
v                 
>>>>>>>>>>>>>>>>>@

input - dddsssdddddasddddwww

>>>v        
   v       @
   v       ^
   >>>>v<  ^
       >>>>^

meu favorito - dwdwdwddaasassdddddwdwdwddsdswawaasassdddddddwdwdwddsdswawaasassddddwwwwwwwssssssdsdddwwwwddaassddaassddddsssdddwdwdwddaasasassddddwwwwssssssssasasaaawdwwdwddwwdddddddwdwdwddsdswawaasassddddddddddwwdwwwwaasssassdsdddddddwdwdwwwwasasssssssssssdwwwwwwwddd

                    v                                          
                    v                                          
                    v                                          
                    v   v<<                                    
   v<<   v<<     v<<v   v                                      
  v<    v< ^<   v< ^v   v<<                        v<<     v<  
 >v    >v   ^  >v   >v  v                          v ^    v<^  
>^>>>>>^>>>>>>>^>>>>^>>>>>>>v    v<v               v ^    v ^  
                            v   v< v       v<<    v< ^    v ^  
                            v  v<  v      v< ^<   v >^    v>^  
                            >>>v   v     >v   ^   >v^     v>>>@
                               >>>>>>>>>>^>>>>>>>>>>>>>>>>v^   
                                  ^v                      v^   
                                >>^v                      v^   
                               >^  v                      v^   
                               ^  v<                      v^   
                              >^ v<                       v^   
                              ^<<<                        >^  
Stretch Maniac
fonte
2

C # 607

namespace System{using B=Text.StringBuilder;class P{static void Main(){var f=new Collections.Generic.List<B>(){new B("O")};int w=1,r=0,c=0;for(Action R=()=>f[r].Append(' ',w-f[r].Length+1);1>0;){var key=Console.ReadKey(1>0).KeyChar;if(key=='w'){f[r][c]='^';if(--r<0)f.Insert(r=0,new B());R();f[r][c]='O';}if(key=='a'){f[r][c]='<';if(--c<0){foreach(var s in f)s.Insert(c=0,' ');w++;}R();f[r][c]='O';}if(key=='s'){f[r][c]='v';if(++r>f.Count-1)f.Add(new B());R();f[r][c]='O';}if(key=='d'){f[r][c]='>';if(++c>w++)foreach(var s in f)s.Append(' ');R();f[r][c]='O';}Console.WriteLine(string.Join("\n",f)+"\n");}}}}

"Ungolfed" com espaço em branco (isso não será mantido em sincronia com a versão em golfe):

namespace System
{
    using B = Text.StringBuilder;
    class P
    {
        static void Main()
        {
            var f = new Collections.Generic.List<B>() { new B("O") };
            int w = 1, r = 0, c = 0;
            Action R = () => f[r].Append(' ', w - f[r].Length + 1);
            while (true)
            {
                char key = Console.ReadKey(1>0).KeyChar;
                if (key == 'w')
                {
                    f[r][c] = '^';
                    if (--r < 0) { f.Insert(0, new B()); r = 0; }
                    R();
                    f[r][c] = 'O';
                }
                if (key == 'a')
                {
                    f[r][c] = '<';
                    if (--c < 0)
                    {
                        foreach (var s in f)
                            s.Insert(0, ' ');
                        w++;
                        c = 0;
                    }
                    R();
                    f[r][c] = 'O';
                }
                if (key == 's')
                {
                    f[r][c] = 'v';
                    if (++r > f.Count - 1) f.Add(new B());
                    R();
                    f[r][c] = 'O';
                }
                if (key == 'd')
                {
                    f[r][c] = '>';
                    if (++c > w++)
                    {
                        foreach (var s in f)
                            s.Append(' ');
                    }
                    R();
                    f[r][c] = 'O';
                }

                Console.WriteLine(string.Join("\n", f) + "\n");
            }
        }
    }
}
Prumo
fonte
2

Python 3: 259 bytes

x=y=0
b,p,r={},(0,-1,0,1),range
while 1:
 d='wasd'.index(input());b[(x,y)]='^<v>'[d];x+=p[d];y-=p[~d];b[(x,y)]='☺';l,m=([k[i]for k in b]for i in(0,1))
 for j in r(min(m),max(m)+1):print(''.join(b[(i,j)]if(i,j)in b else' 'for i in r(min(l),max(l)+1)))
 print()

Decidi guardar a cobra em um ditado, com coordenadas para as chaves. Em seguida, encontre e repita o intervalo de saída, substituindo espaços em branco.

x = y = 0
board = {}
while 1:
    d = 'wasd'.index(input())
    board[(x, y)] = '^<v>'[d] # body
    x += (0, -1, 0, 1)[d]
    y -= list(reversed((0, -1, 0, 1)))[d]
    board[(x,y)] = '☺' # head

    xs, ys= ([coord[dim] for coord in board] for dim in(0, 1))
    for j in range(min(ys), max(ys)+1):
        print(''.join(board[(i,j)] if (i,j) in board else ' '
                      for i in range(min(xs), max(xs)+1)))
    print()

PS. Meu primeiro golfe :) Deixe-me saber se minha resposta é inadequada

Gilly
fonte
Usar em Ovez de economiza 2 bytes. é um arenque vermelho.
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ não era contado como 3 bytes.
Martin Ender
@MartinEnder Deve ser , a codificação padrão é UTF-8. Tive a sensação de que não era contado. Tenho a sensação de que foi acidental e deve ser corrigida imediatamente por Gilly.
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Bem, tecnicamente, o atendedor é livre para usar qualquer codificação suportada pelo intérprete (e tenho certeza de que alguma página de código compatível com ASCII contém esse caractere), mas isso não vem ao caso. Estou dizendo que a contagem de bytes já é a mesma do uso O, então não me preocuparia. Está claro no código que ele ainda funcionaria para qualquer outro caractere, mas o uso permite executar convenientemente os casos de teste do desafio sem alterações.
Martin Ender
O @MartinEnder Python usa UTF-8, comprovado por sua capacidade de suportar strings unicode. Para habilitar essa funcionalidade, a primeira ou a segunda linha deve ser #coding=utf-8. Observe que #coding=utf-16não funciona. Portanto, deve ser contado como 3.
Erik the Outgolfer
2

Python 2.7 - 274 bytes

x,y,m,d,r=0,0,{},(0,-1,0,1),range
for c in raw_input():b='wasd'.index(c);m[(x,y)]='^<v>'[b];x+=d[b];y-=d[~b];m[(x,y)]='@';l,n=([k[h] for k in m] for h in (0, 1))
for j in range(min(n),max(n)+1):print(''.join(m[(i,j)] if (i,j) in m else ' 'for i in range(min(l),max(l)+1)))

Versão ungolfed

x,y,matrix,delta = 0,0,{},(0, -1, 0, 1)    
for c in raw_input('Command: '):
    d = 'wasd'.index(c)
    matrix[(x, y)] = '^<v>'[d]
    x += delta[d]
    y -= list(reversed(delta))[d]
    matrix[(x, y)] = '@'    
xs, ys = ([xy[i] for xy in matrix] for i in (0, 1))
for j in range(min(ys), max(ys)+1):
    print(''.join(matrix[(i, j)] if (i, j) in matrix else ' '
                  for i in range(min(xs), max(xs)+1)))
Erasmus Adriaan
fonte
2
Bem-vindo à programação de quebra-cabeças e código de golfe! De acordo com as regras descritas em nossa central de ajuda , todas as soluções para os desafios devem ser um candidato sério aos critérios vencedores em uso. Por exemplo, uma entrada para um concurso de código de golfe precisa ser jogada no golfe.
Dennis
1
Eu adicionei a contagem de bytes para você, mas há muitos espaços desnecessários que você pode remover.
Martin Ender
Obrigado pessoal, fiz as alterações necessárias na minha primeira entrada. Qualquer conselho extra será muito apreciado.
Adriaan Erasmus
Eu realmente jogava golfe .
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Isso apenas imprime SyntaxError: invalid syntax.
Dennis
2

05AB1E , 35 34 30 28 bytes

.•₃º•"<>v^"©‡0ªÐUĀ>sŽO^®XkèΛ

Usa 0como cabeça da cobra.

-4 bytes graças a @Grimy .

Experimente online (não há suíte de testes para todos os casos de teste de uma só vez, porque não há como redefinir o Canvas, portanto as saídas se sobrepõem ..).

Explicação:

.•₃º•          # Push compressed string "adsw"
     "<>v^"    # Push string "<>v^"
           ©   # Save it in variable `r` (without popping)
              # Transliterate the (implicit) input-string,
               # replacing all "adsw" with "<>v^" respectively
               #  i.e. "ddddssaassdddddww" → ">>>>vv<<vv>>>>>^^"
0ª             # Convert the string to a list of characters, and append a 0 (for the head)
               #  → [">",">",">",">","v","v","<","<","v","v",">",">",">",">",">","^","^","0"]
  Ð            # Triplicate this list of characters
   U           # Pop and store one of the three lists in variable `X`
   Ā           # Trutify each character ("0" remains 0; everything else becomes 1)
    >          # And then increase each integer by 1
               #  → [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1]
  s            # Swap the two lists on the stack
      ®Xk      # Get the index of each character of variable `X` in variable `r` ("<>v^")
               #  i.e. [">",">",">",">","v","v","<","<","v","v",">",">",">",">",">","^","^","0"]
               #   → [1,1,1,1,2,2,0,0,2,2,1,1,1,1,1,3,3,-1]
   ŽO^   è     # And use those to index into the compressed number 6240
               #  → [2,2,2,2,4,4,6,6,4,4,2,2,2,2,2,0,0,0]
Λ              # Use the Canvas builtin with these three lists

Veja esta dica 05AB1E (seções Como compactar cadeias de caracteres que não fazem parte do dicionário? E Como compactar números inteiros grandes? ) Para entender por que .•₃º•é "adsw"e ŽO^é 6240.

Quanto a uma breve explicação sobre o Canvas embutido Λe seus três argumentos:

Primeiro argumento: length (s): o tamanho das linhas que queremos desenhar. Como precisamos ter em mente a sobreposição, usamos o tamanho 2 para cada personagem e um 1 adicional para a cabeça da cobra.
Segundo argumento: string (s): os caracteres que queremos exibir. Quais são os caracteres nesse caso, anexados ao caractere de cabeça da cobra.
Terceiro argumento: direção (ões): as direções em que essas linhas de caracteres com o comprimento especificado devem ser traçadas. Em geral, temos as direções [0,7]que mapeiam essas direções:

7   0   1
    
6  X  2
    
5   4   3

É por isso que temos o número inteiro 6240para as direções[,,,] respectivamente.

Consulte esta dica 05AB1E para obter uma explicação mais detalhada sobre o Canvas integrado Λ.

Kevin Cruijssen
fonte
1
Eu posso ter perdido alguma coisa, mas acho que não γé necessário. Isso parece funcionar muito bem.
Grimmy
@ Grimy Obrigado, ele realmente faz; boa abordagem alternativa com a lista de 2s e 1 para a cabeça! E pude salvar mais 2 bytes com base no seu programa.
Kevin Cruijssen 04/06
Obrigado! Atualmente, tenho 23 anos , embora essa seja uma abordagem significativamente diferente, por isso posso fazer sua própria resposta, se você estiver bem.
Grimmy
@ Grimy Essa é realmente uma abordagem bem diferente da minha, então fique à vontade para publicá-la. Eu estava realmente esperando que alguma conversão e módulo unicode pudesse torná-lo mais curto que o transliterado, mas sou honestamente muito ruim com esse tipo de conversão mágica de número inteiro / string. :)
Kevin Cruijssen
1

Perl - 394

Não é o mais curto, mas vence pelo menos Javascript, C # e Java.

use List::Util qw(min max);sub c{()=$_[0]=~/$_[1]/g}%l=(a,['<',-1,0],d,['>',1,0],w,['^',0,-1],s=>['v',0,1]);($s,$x,$y,$w,$h)=($ARGV[0],0,0,max(c($s,a),c($s,d)),max(c($s,w),c($s,'s')));@s=split'',$s;map$x=min($x,$i+=$l{$_}[1]),@s;$i=0;map$y=min($y,$i+=$l{$_}[2]),@s;$x=abs $x;$y=abs $y;map{$m[$y][$x]=$l{$_}[0];$x+=$l{$_}[1];$y+=$l{$_}[2]}@s;$m[$y][$x]='o';map{map{print$_||' '}@$_;print"\n"}@m 

Alguns truques:

  • Avisos e estrito não ativados para permitir palavras de barra e não declarar variáveis ​​antes de usá-las
  • Vírgulas finas em vez de vírgulas gordas para salvar alguns caracteres
  • Não definir valores iniciais para variáveis ​​quando não for necessário
  • Deixar ponto e vírgula quando possível
  • Definir matrizes e hashes não como referências para evitar o uso ->
  • Permitindo largura e altura maiores que o necessário para evitar a necessidade de calculá-las com precisão (o que exigiria código extra)

Coisas que doem:

  • Nenhuma maneira interna de contar o número de caracteres em uma sequência (pode ter sido mais longo de qualquer maneira)
  • Nenhuma função mínima / máxima interna, portanto, é necessário desperdiçar 27 caracteres para importar a biblioteca que faz isso (menos do que definir a nossa)
mcreenan
fonte
1

C - 273 bytes - com entrada interativa!

#define F for(i=w*w
*g,*G,x,i,j,w,W,u;main(w){putch(1);F;j=-~getch();g=G){if(!(x%w&&~-~x%w&&x/w&&x/w^~-w)){W=w+6;G=calloc(W*W,4);F-1;u=i%w+i/w*W-~W*3,i==x?x=u:8,i;)G[u]=g[i--];free(g);w=W;}G[x]="<^X>v"[j%=7];G[x+=1-G[x]%3+W*(!!j-j/2)]=1;F;i;)putch(i--%W?G[i]?G[i]:32:10);}}

O campo é impresso toda vez que um caractere é inserido e cresce se a cabeça da cobra se aproximar da borda. Não sei como é portátil - alguém na Internet disse que o getch () não funciona em plataformas não Windows. Difícil dizer se o ASCII 1 também parecerá um rosto sorridente.

A versão para golfe é bastante irritante, pois não há como sair do programa normalmente. Control-C não funciona para mim. Por outro lado, a versão não-gasta termina se um caractere diferente de 'w', 'a', 's' ou 'd' for inserido.

Os chamados "não destruídos":

#define SMILEYFACE 1
int main()
{
    int o;
    int w = 1;
    int *g = 0, *g2;
    int c, n;
    int x = 0;
    for( putch(SMILEYFACE);c = getch(); ) {
        if(c!='w'&&c!='a'&&c!='s'&&c!='d')
            return 1;
        if(!(x%w) | !(~-~x%w) | !(x/w)  | !(x/w-~-w) ) {
            int wnew = w + 4;
            int off = 2;
            g2 = calloc(wnew*wnew,sizeof(int));
            for(n = w*w; --n; )
                g2[ n%w+off + (n/w+off)*wnew ] = g[n];
            free(g);
            g = g2;
            x = (x/w+off)*wnew + x%w + off;
            w = wnew;
        }
        int i = -~c%7;
        g[x] = "<^X>v"[i];
        int dx = 1-g[x]%3 + w * (!!i-i/2);
        x += dx;
        g[x] = SMILEYFACE;
        for(o = w*w; o; )
            putch(o--%w?g[o]?g[o]:32:10);


    }
    return 0;
}
feersum
fonte
1

05AB1E , 23 bytes

Ç7%DÉ+D"^>>v"ºsè0ªDĀ>rΛ

Experimente online!

Explicação:

                      # implicit input (eg: "wasd")
Ç                     # codepoints (eg: [119, 97, 115, 100])
 7%                   # modulo 7 (eg: [0, 6, 3, 2])
   DÉ+                # plus itself modulo 2 (eg: [0, 6, 4, 2])
# This is the list of directions that will be passed to 05AB1E's canvas function, Λ.
# 0 means up, 6 left, 4 right, 2 down.

 "^>>v"º              # "^>>v", horizontally mirrored (namely "^>>vv<<^")
D       sè            # index into this with a copy of the list of directions
          0ª          # append "0"
# This is the list of strings that will be drawn.

D                     # duplicate the list of strings
 Ā                    # truthify (maps letters to 1, 0 stays 0)
  >                   # increment each
# This is the list of lengths to draw.

r                     # reverse the stack because Λ takes arguments in the opposite order
 Λ                    # draw!

Grimmy
fonte