Faites une pause pour faire un serpent!

23

Notre serpent classique a développé un déséquilibre des hormones de croissance . Pour aggraver les choses, sa queue est gelée en place! Étant donné l'entrée directionnelle spécifiée dans Figure 1, écrivez un programme pour déterminer où il grandira.

wasd

Figure 1. Entrée directionnelle.

Spécifications du programme

  • Lisez le caractère saisi caractère par caractère STDIN.
  • Après avoir lu un personnage, sortez le serpent vers STDOUT. Veuillez inclure une ligne vierge entre chaque fois que vous imprimez un serpent.
  • Le serpent est composé d' <>v^une tête. La tête du serpent peut être un caractère rond de votre choix, tels que o, 0, Oou .
  • Toute combinaison de wasdest valide pour la saisie.
  • Votre programme ne doit pas supposer que l'entrée est dans une certaine longueur.
  • Le serpent peut s'accumuler sur lui-même, écrasant <>v^. Voir des exemples de mécanismes de croissance de serpents.
  • La fin des espaces blancs est acceptable, mais votre serpent doit avoir l'air correct.

Notation

C'est du . Votre score est le nombre de caractères de votre programme. Le score le plus bas gagne!

Exemples de serpents:

Contribution: ddddssaassdddddww

Sortie:

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

Contribution: dddsssaaawww

Sortie:

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

Contribution: dddsssdddddasddddwww

Sortie:

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

Contribution: dddwwdddssssaaaaaaaaawww

Sortie:

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

Contribution: ddddssssaawwddddd

Sortie:

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

Contribution: dddddssaawwwwddddd

Sortie:

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

Contribution:

ddddaaaasssssdddddddddddwwwwwaaaasssssdddddddddddwwwwwwwwwwsssssaaaasssssdddddddwwwwwddddssaaaasssddddaaaassssssssssdddwwwwwwwddddswaaaassssddaasssaaaaaaaaaawwwwddddssssaaaaaaaaaaawwwwddddsssssssssaaaa

Sortie:

                  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
la source
8
Très agréable. Mais ... WTH est un "code gofl"?
John Dvorak
2
Je me débarrasserais du bonus car il est beaucoup trop facile de créer votre propre serpent et votre chaîne d'entrée.
Beta Decay
1
@JanDvorak rotfl my bad.
hmatt1
1
@BetaDecay les échelles de l'avion. Dans l'exemple de code golf, il a commencé en haut à gauche du c, mais comme le d est plus grand, il descend.
hmatt1
2
@chilemagic Merci! Si les deux sont acceptables, vous devriez probablement clarifier cela dans la question.
Ingo Bürk

Réponses:

5

Ruby, 207 caractères

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}

Non golfé:

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}

(le lambda pour aréécrit parce que la ligne à laquelle l'affectation ci-dessus écrit n'est plus sur le tableau)

John Dvorak
la source
11

ECMAScript 6 Javascript (399 401 431 )

Doit être exécuté dans un navigateur prenant en charge ECMAScript 6 en raison des fonctions fléchées.

Voici des violons qui ont été modifiés pour fonctionner dans n'importe quel navigateur (commun) en n'utilisant pas les fonctions fléchées. Ils impriment également à la textareaplace:

Version golfée

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 animé:

Un des exemples du PO:

entrez la description de l'image ici

L'exemple de Stretch Maniac :

entrez la description de l'image ici

Non golfé

Voici une version (légèrement) non golfée de quelque temps avant que je ne commence vraiment à jouer au golf:

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
la source
Les gifs sont très cool. Sont-ils créés automatiquement par un script que vous avez écrit?
AndoDaan
1
Merci! Avec la puissance de Google, je viens de chercher comment faire un cadeau à partir d'un enregistrement d'écran dans Ubuntu. Il utilise simplement un enregistreur d'écran et convert. Assez facile :)
Ingo Bürk
3
(gif, pas cadeau)
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'

Même approche que ma réponse précédente, mais en positionnant correctement le curseur avant et après. Je suis assez fier de l'approche du positionnement du curseur - en gros, il exécute d'abord le serpent à l'envers, sans imprimer de caractères.

Sneftel
la source
1
Pouvez-vous ajouter un exemple d'appel? 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/$/@/'ne donne pas la sortie correcte pour moi.
Ingo Bürk
Votre invite après l'exécution écrase probablement une partie du serpent. Collez le serpent directement dans stdin au lieu de la tuyauterie, ou ajoutez quelques \ns après le @afin que votre invite aille ailleurs.
Sneftel
1
Cela peut échouer si le serpent monte ou quitte la planche.
tomsmeding
@tomsmeding Ouais, je pourrais l'étendre pour y faire face. En dehors du langage, cependant, je pense vraiment que les séquences de contrôle ANSI sont la voie à suivre pour un code plus court.
Sneftel
3

Java - 646

Autant être le premier!

Je parie que vous pouvez tous battre cela.

un (sorte de) golfé

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();}
    }
}

Plus petit -

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();}}}

entrée - dddsssdddwwwwaaaaaaaassssssssssddddddddddddddddd

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

entrée - dddsssdddddasddddwww

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

mon préféré - 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
la source
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" avec des espaces (cela ne sera pas synchronisé avec la version golfée):

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");
            }
        }
    }
}
Bob
la source
2

Python 3: 259 octets

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()

J'ai décidé de stocker le serpent dans un dict, avec les coordonnées des clés. Recherchez et parcourez ensuite la plage de sortie en remplaçant les espaces vides.

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. Mon premier golf :) Faites-moi savoir si ma réponse est inappropriée

Gilly
la source
L'utilisation Oau lieu de vous permet d' économiser 2 octets. est un hareng rouge.
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ n'était en fait pas compté comme 3 octets.
Martin Ender
@MartinEnder Cela doit être , l'encodage par défaut est UTF-8. J'avais le sentiment que ce n'était pas compté. J'ai le sentiment que c'était accidentel et doit être immédiatement réparé par Gilly.
Erik the Outgolfer le
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Eh bien, techniquement, le répondeur est libre d'utiliser n'importe quel encodage pris en charge par son interprète (et je suis presque sûr qu'une page de code compatible ASCII contient ce caractère), mais ce n'est pas la question. Je dis que le nombre d'octets est déjà le même que celui de l'utilisation O, donc je ne m'en inquiéterais pas. Il est clair d'après le code que cela fonctionnerait toujours pour tout autre personnage, mais l'utilisation vous permet d'exécuter facilement les cas de test du défi sans modifications.
Martin Ender
@MartinEnder Python utilise UTF-8, prouvé par sa capacité à prendre en charge les chaînes unicode. Pour activer cette fonctionnalité, la première ou la deuxième ligne doit être #coding=utf-8. Notez que #coding=utf-16cela ne fonctionne pas. Il faut donc compter comme 3.
Erik the Outgolfer
2

Python 2.7 - 274 octets

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

Version non golfée

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)))
Adriaan Erasmus
la source
2
Bienvenue sur Programmation Puzzles & Code Golf! Selon les règles énoncées dans notre centre d'aide , toutes les solutions aux défis doivent être un candidat sérieux aux critères gagnants utilisés. Par exemple, une entrée à un concours de golf à code doit être jouée.
Dennis
1
J'ai ajouté le nombre d'octets pour vous, mais il y a beaucoup d'espaces inutiles que vous voudrez peut-être supprimer.
Martin Ender
Merci les gars, j'ai apporté les modifications nécessaires à ma première entrée. Tout conseil supplémentaire sera grandement apprécié.
Adriaan Erasmus
Je l'ai vraiment joué au golf .
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Cela ne fait qu'imprimer SyntaxError: invalid syntax.
Dennis
2

05AB1E , 35 34 30 28 octets

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

Utilise 0comme tête de serpent.

-4 octets grâce à @Grimy .

Essayez-le en ligne (pas de suite de tests pour tous les cas de test à la fois, car il n'y a aucun moyen de réinitialiser le Canvas, donc les sorties se chevauchent ..).

Explication:

.•₃º•          # 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

Voir cette 05AB1E pointe de mes (sections Comment les chaînes de Compresser ne font pas partie du dictionnaire? Et Comment compresser les grands entiers? ) Pour comprendre pourquoi .•₃º•est "adsw"etŽO^ est 6240.

Quant à une brève explication de la toile intégrée Λet de ses trois arguments:

Premier argument: longueur (s): la taille des lignes que nous voulons tracer. Puisque nous devons garder à l'esprit le chevauchement, nous utilisons la taille 2 pour chaque personnage et 1 supplémentaire pour la tête du serpent.
Deuxième argument: chaîne (s): les caractères que nous voulons afficher. Quels sont les personnages dans ce cas, ajoutés au personnage principal du serpent.
Troisième argument: direction (s): les directions dans lesquelles ces lignes de caractères de la longueur donnée doivent être dessinées. En général, nous avons les directions [0,7]qui correspondent à ces directions:

7   0   1
    
6  X  2
    
5   4   3

C'est pourquoi nous avons l'entier 6240pour les directions[,,,] respectivement.

Voir cette astuce 05AB1E pour une explication plus détaillée sur le Canvas intégré Λ.

Kevin Cruijssen
la source
1
J'ai peut-être manqué quelque chose, mais je ne pense pas que ce γsoit nécessaire du tout. Cela semble très bien fonctionner.
Grimmy
@Grimy Merci, c'est vrai; belle approche alternative avec la liste des 2 et 1 pour la tête! Et j'ai pu enregistrer 2 octets supplémentaires en fonction de votre programme.
Kevin Cruijssen
Merci! Je suis actuellement à 23 ans , bien que ce soit une approche très différente, donc je pourrais en faire sa propre réponse si cela vous convient.
Grimmy
@Grimy C'est en effet une approche assez différente de la mienne, alors n'hésitez pas à la poster. Je m'attendais en effet à une conversion unicode et modulo pourrait rendre cela plus court que le translittéré, mais je suis honnêtement assez mauvais avec ce genre de conversions magiques d'entiers / chaînes. :)
Kevin Cruijssen
1

Perl - 394

Pas le plus court, mais il bat au moins Javascript, C # et 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 

Quelques astuces:

  • Avertissements et strict non activés pour autoriser les mots nus et ne pas déclarer de variables avant de les utiliser
  • Des virgules minces au lieu de grosses virgules pour enregistrer quelques caractères
  • Ne pas définir de valeurs initiales pour les variables lorsque cela n'est pas nécessaire
  • Oublier les points-virgules lorsque cela est possible
  • Définir les tableaux et les hachages non comme des références pour éviter d'avoir à utiliser ->
  • Permettre à la largeur et à la hauteur d'être plus grandes que nécessaire pour éviter d'avoir à les calculer avec précision (ce qui nécessiterait du code supplémentaire)

Choses qui font mal:

  • Aucun moyen intégré de compter le nombre de caractères dans une chaîne (peut-être plus long de toute façon)
  • Aucune fonction min / max intégrée, donc besoin de gaspiller 27 caractères pour importer la bibliothèque qui le fait (moins que de définir la nôtre)
mcreenan
la source
1

C - 273 octets - avec entrée interactive!

#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);}}

Le champ est imprimé à chaque fois qu'un caractère est entré et s'agrandit si la tête du serpent s'approche du bord. Je ne sais pas à quel point c'est portable - quelqu'un sur Internet a dit que getch () ne fonctionne pas sur les plates-formes non Windows. Difficile de dire si ASCII 1 ressemblera à un visage souriant non plus.

La version golfée est assez ennuyeuse car il n'y a aucun moyen de quitter le programme avec grâce. Control-C ne fonctionne pas pour moi. En revanche, la version non golfée se termine si un caractère autre que «w», «a», «s» ou «d» est entré.

Soi-disant "non golfé":

#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
la source
1

05AB1E , 23 octets

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

Essayez-le en ligne!

Explication:

                      # 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
la source