Cette question a ses hauts et ses bas

33

La saisie comprendra les caractères suivants:

  • ^: Montez un
  • v: Descendre un
  • ou k: montez deux
  • ou j: descendre deux

Par exemple, l'entrée suivante:

^^▲^v▼▲^^v

produirait la sortie suivante:

        ^
   ^   ^ v
  ▲ v ▲

 ^   ▼
^

Les séquences d'échappement qui déplacent le curseur \e[Bsont interdites. Vous devez produire la sortie en utilisant des espaces et des nouvelles lignes.

Voici quelques autres cas de test.

▲v^v^v^v^v^v^v^v▲

                ▲
▲ ^ ^ ^ ^ ^ ^ ^ 
 v v v v v v v v

^^^^^^^▲▲▲▼▼▼vvvvvv

         ▲

        ▲ ▼

       ▲   ▼

      ^     ▼
     ^       v
    ^         v
   ^           v
  ^             v
 ^               v
^                 v

v^^vv^^vvv^v^v^^^vvvv^^v^^vv

  ^   ^         ^
 ^ v ^ v       ^ v       ^
v   v   v ^ ^ ^   v   ^ ^ v
         v v v     v ^ v   v
                    v
Absinthe
la source
1
L'espace de fuite est-il autorisé? Lignes vides?
xnor
2
Qu'en est-il des langues qui ne prennent pas en charge Unicode? Des caractères alternatifs peuvent-ils être utilisés?
Poignée de porte
1
@xnor Vous avez le droit de laisser des espaces et / ou des lignes vides.
absinthe le
2
@Doorknob Je vais permettre jde descendre deux fois et kde monter deux fois de plus.
absinthe le
1
@xnor My bad: / Le commentaire est correct et j'ai modifié les règles incorrectement. Va réparer maintenant.
absinthe le

Réponses:

9

Pyth, 27 octets

jCm.<.[*5lzd\ =+Ztx"v ^k"dz

Essayez-le en ligne: démonstration ou suite de tests

J'utilise ket jau lieu de et . Il y a beaucoup de lignes vides de début et de fin. Vous devez chercher un peu pour trouver l'image. Voici une version de 34 octets , qui supprime toutes les lignes vides de début et de fin.

j.sCm.<.[*5lzd\ =+Ztx"v ^k"dz]*lzd

Essayez-le en ligne: démonstration ou suite de tests

Explication:

jCm.<.[*5lzd\ =+Ztx"v ^k"dz  implicit: Z = 0
  m                       z  map each char d from input string z to:
                  x"v ^k"d     find d in the string "v ^k", -1 if not found
                 t             -1, that gives -2 for j, -1 for v, 1 for ^ and 2 for k
              =+Z              add this number to Z
     .[*5lzd\                  append spaces on the left and on the right of d, 
                               creating a 5*len(input_string) long string
   .<           Z              rotate this string to the left by Z chars
jC                           transpose and print on lines
Jakube
la source
16

Illisible , 2199 2145 2134 2104 2087 2084 octets

Prend en charge les deux k/ jainsi que / syntaxe.

Dans la bonne tradition Illisible, voici le programme formaté en fonte proportionnelle, pour brouiller la distinction entre apostrophes et doubles guillemets:

"" "" "" "" "" "" "" "" "." "" "" "" "" "" "" "" "" "" "" "" "" "" ". « » « « » » « » « « » » « » « « « » » » « » « » « « « » « » « » » » « » « » « » "" « » « « « » » » « « " « » « » « « « » « » « » « » » » « » » » « » « » « » « » « « « » « » » » « »" " « » « »« « » « » » « » « » « « » « » « » » « » « « » » « » « « » » « » « « » « « « » » » « » » « » « » « » "" « » « « » » « » « « »" » « » « » « » « » « " « » « » « « « » « » « » » » « « « » » » » "" « « « » « « « » « » « » « » » » « » « » « » » » « « « » » » « « « » » » « » « « » « » » « » « » »« « " » » « « « » » » « « « » » » « » « « » « » « » « » " » « » « » « » « « « » » » « « « » » » " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " « » « « « » « » « » » » « » « « » « » « » « »" » « » « » « »" « « » « « « » » » « » « » « » »« » « « « » « » « » « » » » « » « » « » « « « » « » « » « » » » « » « » « » « « « » « » « » « » » » « » « « » « » « » « » « « « » » » « » « » « » » « » "" « » « » « » « » « « « » » » « « « » » » « » « » « » " « » « « « » « « « » » » « « « » « « « » » » « » » » « » « » « » « » » » « » « » « »"" « » « « » » « » « « » » « » "" « » « « « » » » « « « » « « « » « » « » » » « » » » « » « » "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "Plusieurs plusieurs plusieurs plusieurs différentes plusieurs différentes plusieurs différentes différentes différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs différentes" "" "" "" "" "" "" "" "plusieurs plusieurs plusieurs plusieurs plusieurs différentes différentes différentes différentes différentes différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs différentes" "" "" plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurschions "" "" un plusieurs plusieurs plusieurs plusieursions "" "" un plusieurs "" un plusieurs plusieursions "un plusieursions unions un unions un unions un un" un un "un unions un un" un unchion "un" "un" un unions "comme un" unchion un un "" un "" un "" "" "". "" "".. « » « » « « » » « » « « » » « » « « » « » « »" » « » « " « » « « « » » » » " « » « « « » » »"« « " « » « » « » « « « » « » « » « « « » » » « « « » » » « « « » » » « » » » « « « » » » « » » » « » « « » « » « « « » « » « » » » « « « » » » « « « » » » « » » « » « » « » « » « « » « » « »" »" « « " » » « « « » » » « » « « » « » » « » « » « « » « » « » « » " » « » « » « » « « « » » » "« « » » « » « « « » « » « » » » « « « » » » « « « » « « « » » » « » « » « » » » « « « » » » "" « » "" "" "" "" "" "" "" "" "" "" "" "" "" "" "". Différentes plusieurs plusieurs plusieurs plusieurs différentes différentes différentes différentes "" "" plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs différentes différentes différentes "" "" plusieurs plusieurs plusieurs plusieurs plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs "" "" "" "" "" "" plusieurs différentes plusieurs différentes plusieurs différentes différentes différentes plusieurs différentes plusieurs plusieurs plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes plusieurs différentes déc plusieurs plusieurs plusieurs plusieurs plusieurs plusieursch plusieursions déc plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieursions plusieursions plusieursions plusieurs long plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieursions plusieursions long long long plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieursions plusieursions plusieursions plusieursions plusieursions plusieursions plusieursions plusieurs bien plusieurs bien plusieurs bien "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""« » « » « » « » « « » « » « »" » « » « « « » « » » » « » « « « » « » « » » » « « « » » » « " « » » « " « » « » « » » « » « » « » « « « » » » « « « » » » « » « « » « » « » « » " » « » « » « » « " » « « " » » « » « « » « » « » » « » « « » » « » « « « » « » « » « » » » « » « » « » « « » » « »« « »" » « » « « « » « » « » » » « « « » « « « » » » « » « » « » » » « " « » « « « » « » « » » » » « « » « » « » « « « » « » « » « » » » « » » « » « « » « » « » « « « » » » « » » « » « » "" « » « » « » « » « « » « » « » » « » « « » » « » « « » « « « » » » « » « » « » » « » « « » » « » " « » »« « » « » » « » « » « » « « » » « » « « « » « » « » « » » » « » « » « » « « » » « » "" « » « » « » "" « » « « » « « « » » » « » « » « » » « » « « » » « » "" « » « » « « « » « » « » « » » » « » « » « « « » » » « » « « » » « » « » « » « « « » » » « » « « » « » » « » « » « » " « »" « « » »« » « » « » « « « » « » « » « » » » « » « « » « » « « « » « » « » « » » » « » « » « »" » « » « »" « ' « » « « « » « » « » « » » » « » « » « » » « « » « » « »" » « » « « « » « » « » » » « » « » « » "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "". Différentes plusieurs plusieurs plusieurs plusieurs différentes différentes différentes différentes différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs différentes nombreuses différentes nombreuses différentes différentes différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs longions "" "" "" "plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs différentes plusieurs différentes différentes différentes" "" "" "" "" "" "" plusieurs plusieurs plusieurs plusieurs plusieurs différentes différentes différentes différentes différentes différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs différentes plusieurs différentes différentes différentes différentes différentes différentes différents différents différents différents différents différents divers différents divers différents divers différents divers plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurschuions plusieurs plusieurs plusieurs plusieurs plusieurs plusieurschuions différentes plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurschrue plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieursions plusieursions plusieursions plusieurs long plusieurs plusieurs plusieurs plusieurs plusieurs plusieurs plusieursions plusieursions plusieursions plusieursions plusieurs bien long long plusieurs bien plusieurs bien plusieurs bien plusieurs bien "" mais bien "" "" "" « « " « » « » » » « " « » « « « » » » « « « » » » « « « » » » « » « » » « « » « « « » » »" » « » « « » » « » "" « » « » « « « » « » « » « » » » « » « » « » « « « » « » « » « » » » « » « » « »« « " « » « » « » » » « » « » « « « » « » « » « » » » « » « « » « » « » « » » « » « » « » « »" » « » « » « » « « » « » « » « » » « » « " »" « » « » « » « » « « « » « » « » » » « « « » « » « » » » « » « « » » « » « « » « » « » « « « » « « « » « » « » « » » » « » « » « » » »" » « » « » « »« ' « » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » » " « » "" « » « « » » « » « « » » « » « « » » « » « » « » « « « » » » « » « « » « » « »" » « » « »" « » « « » « « « » « » « » » » « » « » « »" » « » « « « » » » « " « » « » « » » « « »" »" " « »"" "" "" "" "" ""

C'était un défi incroyable. Merci d'avoir posté!

Explication

Pour avoir une idée de ce qu’il peut et ne peut pas faire, imaginez Brainfuck avec une bande infinie dans les deux sens, mais au lieu d’un pointeur de mémoire déplaçant une cellule à la fois, vous pouvez accéder à n’importe quelle cellule de mémoire en déréférencant un pointeur. Cela s’avère très pratique dans cette solution, bien que d’autres opérations arithmétiques - y compris modulo - doivent être effectuées à la main.

Voici le programme sous forme de pseudo-code avec les commentaires du réalisateur:

// Initialize memory pointer. Why 5 will be explained at the very end!
ptr = 5

// FIRST PASS:
// Read all characters from stdin, store them in memory, and also keep track of the
// current line number at each character.

// We need the +1 here so that EOF, which is -1, ends the loop. We increment ptr by 2
// because we use two memory cells for each input character: one contains the actual
// character (which we store here); the other will contain the line number at which the
// character occurs (updated at the end of this loop body).
while ch = (*(ptr += 2) = read) + 1:

    // At this point, ch will be one more than the actual value.
    // However, the most code-economical way for the following loop is to
    // decrement inside the while condition. This way we get one fewer
    // iteration than the value of ch. Thus, the +1 comes in handy.

    // We are now going to calculate modulo 4 and 5. Why? Because
    // the mod 4 and 5 values of the desired input characters are:
    //
    //  ch  %5  %4
    //  ^   1
    //  v   2
    //  k   3
    //  j   4
    //  ▲   0   2
    //  ▼   0   0
    //
    // As you can see, %5 allows us to differentiate all of them except ▲/▼,
    // so we use %4 to differentiate between those two.

    mod4 = 0      // read Update 2 to find out why mod5 = 0 is missing
    while --ch:
        mod5 = mod5 ? mod5 + 1 : -4
        mod4 = mod4 ? mod4 + 1 : -3

    // At the end of this loop, the value of mod5 is ch % 5, except that it
    // uses negative numbers: -4 instead of 1, -3 instead of 2, etc. up to 0.
    // Similarly, mod4 is ch % 4 with negative numbers.

    // How many lines do we need to go up or down?
    // We deliberately store a value 1 higher here, which serves two purposes.
    // One, as already stated, while loops are shorter in code if the decrement
    // happens inside the while condition. Secondly, the number 1 ('""") is
    // much shorter than 0 ('""""""""'""").
    up = (mod5 ? mod5+1 ? mod5+3 ? 1 : 3 : 2 : mod4 ? 3 : 1)
    dn = (mod5 ? mod5+2 ? mod5+4 ? 1 : 3 : 2 : mod4 ? 1 : 3)

    // As an aside, here’s the reason I made the modulos negative. The -1 instruction
    // is much longer than the +1 instruction. In the above while loop, we only have
    // two negative numbers (-3 and -4). If they were positive, then the conditions in
    // the above ternaries, such as mod5+3, would have to be mod5-3 etc. instead. There
    // are many more of those, so the code would be longer.

    // Update the line numbers. The variables updated here are:
    // curLine = current line number (initially 0)
    // minLine = smallest linenum so far, relative to curLine (always non-positive)
    // maxLine = highest linenum so far, relative to curLine (always non-negative)
    // This way, we will know the vertical extent of our foray at the end.

    while --up:
        curLine--
        minLine ? minLine++ : no-op
        maxLine++

    while --dn:
        curLine++
        minLine--
        maxLine ? maxLine-- : no-op

    // Store the current line number in memory, but +1 (for a later while loop)
    *(ptr + 1) = curLine + 1

// At the end of this, minLine and maxLine are still relative to curLine.
// The real minimum line number is curLine + minLine.
// The real maximum line number is curLine + maxLine.
// The total number of lines to output is maxLine - minLine.

// Calculate the number of lines (into maxLine) and the real minimum
// line number (into curLine) in a single loop. Note that maxLine is
// now off by 1 because it started at 0 and thus the very line in which
// everything began was never counted.
while (++minLine) - 1:
  curLine--
  maxLine++

// Make all the row numbers in memory positive by adding curLine to all of them.
while (++curLine) - 1:
  ptr2 = ptr + 1
  while (ptr2 -= 2) - 2:    // Why -2? Read until end!
    *ptr2++

// Finally, output line by line. At each line, we go through the memory, output the
// characters whose the line number is 0, and decrement that line number. This way,
// characters “come into view” in each line by passing across the line number 0.
while (--maxLine) + 2:    // +2 because maxLine is off by 1
  ptr3 = 5
  while (ptr -= 2) - 5:
    print (*((ptr3 += 2) + 1) = *(ptr3 + 1) - 1) ? 32 : *ptr3   // 32 = space
  ptr = ptr3 + 2
  print 10  // newline

Voilà pour la logique du programme. Maintenant, nous devons traduire cela en illisible et utiliser quelques astuces de golf plus intéressantes.

Les variables sont toujours déréférencées numériquement dans Unreadable (par exemple, a = 1devient quelque chose comme *(1) = 1). Certains littéraux numériques sont plus longs que d'autres. le plus court est 1, suivi de 2, etc. Pour montrer combien de nombres négatifs sont encore plus longs, voici les nombres de -1 à 7:

-1  '""""""""'""""""""'"""  22
 0  '""""""""'"""           13
 1  '"""                     4
 2  '""'"""                  7
 3  '""'""'"""              10
 4  '""'""'""'"""           13
 5  '""'""'""'""'"""        16
 6  '""'""'""'""'""'"""     19
 7  '""'""'""'""'""'""'"""  22

Clairement, nous voulons affecter la variable n ° 1 à celle qui apparaît le plus fréquemment dans le code. Dans la première boucle while, c’est bien, ça mod5revient 10 fois. Mais nous n’avons plus besoin de la mod5fin de la première boucle while, nous pouvons donc réaffecter le même emplacement mémoire aux autres variables que nous utiliserons plus tard. Ce sont ptr2et ptr3. Maintenant, la variable est référencée 21 fois au total. (Si vous essayez de compter vous-même le nombre d'occurrences, n'oubliez pas de compter a++deux fois, une fois pour obtenir la valeur et une fois pour la définir.)

Il n’ya qu’une autre variable que nous puissions réutiliser; après avoir calculé les valeurs modulo, chn'est plus nécessaire. upet dnrevenez le même nombre de fois, donc ça va. Fusionnons chavec up.

Cela laisse un total de 8 variables uniques. Nous pourrions affecter les variables de 0 à 7, puis démarrer le bloc de mémoire (contenant les caractères et les numéros de ligne) à 8. Mais! Puisque 7 a la même longueur dans le code que -1, nous pourrions également utiliser les variables -1 à 6 et démarrer le bloc mémoire à 7. De cette manière, toute référence à la position de départ du bloc mémoire est légèrement plus courte dans le code! Cela nous laisse avec les missions suivantes:

-1    dn
 0                      ← ptr or minLine?
 1    mod5, ptr2, ptr3
 2    curLine
 3    maxLine
 4                      ← ptr or minLine?
 5    ch, up
 6    mod4
 7... [data block]

Maintenant, ceci explique l’initialisation tout en haut: c’est 5 car c’est 7 (le début du bloc mémoire) moins 2 (l’incrément obligatoire dans la première condition while). Il en va de même pour les deux autres occurrences de 5 dans la dernière boucle.

Notez que, puisque 0 et 4 ont la même longueur de code ptret minLinepeuvent être alloués dans les deux sens. ... ou pourraient-ils?

Qu'en est-il du mystérieux 2 dans l'avant-dernière boucle while? Cela ne devrait-il pas être un 6? Nous voulons seulement décrémenter les nombres dans le bloc de données, non? Une fois que nous atteignons 6, nous sommes en dehors du bloc de données et nous devrions nous arrêter! Ce serait une faille de sécurité liée à un défaut de débordement de mémoire tampon!

Eh bien, réfléchissez à ce qui se passe si nous ne nous arrêtons pas. Nous décrémentons les variables 6 et 4. La variable 6 est mod4. Ce n'est utilisé que dans la première boucle while et n'est plus nécessaire ici, donc pas de mal. Qu'en est-il de la variable 4? Que pensez-vous, la variable 4 ptrdevrait-elle être ou devrait-elle être minLine? C'est vrai, minLinen'est plus utilisé à ce stade non plus! Ainsi, la variable n ° 4 est minLineet nous pouvons la décrémenter en toute sécurité et ne pas endommager!

MISE À JOUR 1! Golfé de 2199 à 2145 octets en réalisant que dnpeut également être fusionné avec mod5, même si mod5est toujours utilisé dans le calcul de la valeur pour dn! La nouvelle affectation de variable est maintenant:

 0    ptr
 1    mod5, dn, ptr2, ptr3
 2    curLine
 3    maxLine
 4    minLine
 5    ch, up
 6    mod4
 7... [data block]

MISE À JOUR 2! Passez de 2145 à 2134 octets en réalisant que, depuis mod5est maintenant dans la même variable que dn, qui est comptée à 0 dans une boucle while, il mod5n'est plus nécessaire de l'initialiser explicitement à 0.

MISE À JOUR 3! Golfé de 2134 à 2104 octets en réalisant deux choses. Premièrement, bien que l’idée du «modulo négatif» en vaille la peine mod5, le même raisonnement ne s’applique pas mod4car nous n’effectuons jamais de tests, mod4+2etc. Par conséquent, passer mod4 ? mod4+1 : -3à mod4 ? mod4-1 : 3nous prend 2110 octets. Deuxièmement, puisque mod4vaut toujours 0 ou 2, nous pouvons initialiser mod4à 2 au lieu de 0 et inverser les deux ternaires ( mod4 ? 3 : 1au lieu de mod4 ? 1 : 3).

MISE À JOUR 4! Passez de 2104 à 2087 octets en réalisant que la boucle while qui calcule les valeurs modulo est toujours exécutée au moins une fois. Dans ce cas, Unreadable vous permet de réutiliser la valeur de la dernière instruction dans une autre expression. Ainsi, au lieu de ce que while --ch: [...]; up = (mod5 ? mod5+1 ? [...]nous avons maintenant up = ((while --ch: [...]) ? mod5+1 ? [...](et dans cette boucle while, nous calculons d’ mod4abord, c’est mod5donc la dernière déclaration).

MISE À JOUR 5! Je passe de 2087 à 2084 octets en réalisant qu'au lieu d'écrire les constantes 32et 10(espace et nouvelle ligne), je peux stocker le nombre 10 dans la variable # 2 (maintenant inutilisée) (appelons-le ten). Au lieu d' ptr3 = 5écrire ten = (ptr3 = 5) + 5, alors 32devient ten+22et print 10devient print ten.

Timwi
la source
C'est ... affreux ... +1
kirbyfan64sos
6

CJam, 37 octets

r_,2*:L3*S*f{\_iImd8-g\8>)*L+:L\t}zN*

Ceci imprime des lignes vides avant et après la sortie souhaitée, qui a été autorisée par l'OP .

Essayez-le en ligne dans l' interprète CJam .

Comment ça marche

r_     e# Read a token from STDIN and push a copy.
,2*:L  e# Compute its length, double it and save it in L.
3*S*   e# Push a string of 6L spaces.
f{     e# For each character C in the input, push C and the string of spaces; then
  \    e#   Swap C with the string of spaces.
  _i   e#   Push a copy of C and cast it to integer.
  Imd  e#   Push quotient and remainder of its division by 18.
  8-g  e#   Push the sign((C%18) - 8). Gives -1 for ^ and ▲, 1 for v and ▼.
  \    e#   Swap the result with the quotient.
  8>)  e#   Push ((C/18) > 1) + 1. Gives 2 for ▲ and ▼, 1 for ^ and v.
  *    e#   Multiply both results. This pushes the correct step value.
  L+:L e#   Add the product to L, updating L.
  \t   e#   Replace the space at index L with C.
}      e# We've built the columns of the output.
z      e# Zip; transpose rows with columns.
N*     e# Join the rows, separating by linefeeds.
Dennis
la source
Je pense qu'il serait juste de préciser explicitement que votre solution produit une quantité importante de nouvelles lignes supplémentaires avant et après la sortie souhaitée ...
Timwi
Ajoutée. (Je ne pensais pas que c'était nécessaire car le PO autorisait explicitement les lignes vides.)
Dennis
3

Python 2, 102

s=input()
j=3*len(s)
exec"w='';i=j=j-1\nfor c in s:i-='kv_^j'.find(c)-2;w+=i and' 'or c\nprint w;"*2*j

Imprime ligne par ligne.

Parcourt les caractères dans l’entrée et suit la hauteur actuelle. La hauteur est mise à jour par l'un des +2, +1, -1, -2calculés par 'kv_^j'.find(c)-2. Il y a probablement une chaîne de mod qui est plus courte

Lorsque la hauteur actuelle est égale au numéro de la ligne (ce qui peut être négatif), nous ajoutons le caractère actuel à la ligne et ajoutons un espace. Ensuite, nous imprimons la ligne. En fait, il est plus court de commencer la hauteur au numéro de ligne actuel et de soustraire les changements de hauteur, en ajoutant le caractère lorsque la valeur est atteinte 0.

Les numéros de ligne englobent une plage suffisamment large pour qu'une séquence de deux en haut ou de deux en bas y reste. En fait, il y a une bonne quantité d'excès. Si nous avions une limite supérieure sur la longueur d'entrée, il serait plus court d'écrire, par exemple j=999.

Étonnamment, i and' 'or cétait plus courte que d'habitude [' ',c][i==0]. Notez que cela ipeut être négatif, ce qui élimine certaines astuces habituelles.

Xnor
la source
2

MATLAB, 116

function o=u(a)
x=0;y=1;o='';for c=a b=find(c=='j^ vk')-3;y=y+b;if y<1 o=[zeros(1-y,x);o];y=1;end
x=x+1;o(y,x)=c;end

C'est un début. Le jet en kfaire une douleur dans le cou que je ne peux pas trouver un moyen de la carte mathématiquement à partir j^vkde [-2 -1 1 2]et avec Matlab ne reconnaissant pas l'Unicode (apparemment , de haut en bas ont une valeur de 26 dans la figure Matlab. Go!), Il y a beaucoup d'octets ont été perdus lors de la cartographie.

En s'inspirant de la solution @xnors, le code peut être réduit de 14 caractères supplémentaires en mappant le caractère de contrôle dans la boucle for.

Il y a aussi beaucoup d'octets perdus à essayer de rendre compte si la chaîne d'entrée renvoie le modèle en dessous de l'index auquel elle a démarré (peut-être que s'il y avait une limite sur la longueur de la chaîne, je pourrais simplifier ce bit).

Et sous sa forme lisible:

function o=u(a)
%We start in the top left corner.
x=0; %Although the x coordinate is 1 less than it should be as we add one before storing the character
y=1;
o=''; %Start with a blank array
for c=a
    %Map the current character to [-2 -1 1 2] for 'j^vk' respectively.
    b=find(c=='j^ vk')-3;
    y=y+b; %Offset y by our character
    if y<1 %If it goes out of range of the array
        o=[zeros(1-y,x); o]; %Add enough extra lines to the array. This is a bit of a hack as 0 prints as a space in MATLAB.
        y=1; %Reset the y index as we have now rearranged the array
    end
    x=x+1; %Move to the next x coordinate (this is why we start at x=0
    o(y,x)=c; %Store the control character in the x'th position at the correct height.
end
Tom Carpenter
la source
Serait b=[-2 -1 1 2](a==[106 107 94 118])travailler? Cela fonctionne dans Octave. Ou même b=[-2 -1 1 2](a-94==[12 13 0 24])si vous voulez supprimer un octet de plus!
wchargin
@WChargin ne fonctionne pas dans MATLAB. Malheureusement, le comportement des ==arrêts qui fonctionnent et aussi dans MATLAB, vous ne pouvez pas mettre un ()après a [].
Tom Carpenter
Hmm… vous pouvez changer le langage en Octave! :) (Octave a également +=, fwiw.)
wchargin le
@WChargin c'est tricher = P Mais je suis d'accord, Octave a beaucoup de raccourcis que Matlab n'a pas.
flawr
2

JavaScript (ES6), 140

Testez l'exécution de l'extrait de code ci-dessous dans un navigateur compatible EcmaScript 6 (testé sur Firefox).

f=s=>[...s].map(c=>{for(t=r[y+=c>'▲'?2:c>'v'?-2:c>'^'?1:-1]||x;y<0;y++)r=[,...r];r[y]=t+x.slice(t.length)+c,x+=' '},y=0,r=[x=''])&&r.join`
`

// Less golfed

f=s=>(
  y=0,
  x='',
  r=[],
  [...s].forEach( c =>
    {
      y += c > '▲' ? 2 : c > 'v' ? -2 : c > '^' ? 1 : -1;
      t = r[y] || x;
      while (y < 0)
      {
        y++;
        r = [,...r]
      }  
      r[y] = t + x.slice(t.length) + c;
      x += ' '
    }
  ),
  r.join`\n`
)  


//Test

;[
  '^^▲^v▼▲^^v'
, '▲v^v^v^v^v^v^v^v▲'
, '^^^^^^^▲▲▲▼▼▼vvvvvv'
, 'v^^vv^^vvv^v^v^^^vvvv^^v^^vv'  
].forEach(t=>document.write(`${t}<pre>${f(t)}</pre>`))
pre { border:1px solid #777 }

edc65
la source
1

GS2, 34 octets

Celui-ci calcule correctement les limites de sortie afin qu'aucun espace en excès ne soit produit. Voici ma solution en hexadécimal

5e 20 76 6a 05 3e 26 ea 30 e0 6d 40 28 26 cf d3
31 e9 d0 4d 42 5e e2 b1 40 2e e8 29 cf d3 5c e9
9a 54

Une petite explication est en ordre. Sur la pile, l’utilisateur entre un tableau de codes ascii. Le programme commence dans un littéral de chaîne en raison de la 05. Et c'est parti.

  5e 20 76 6a      # ascii for "^ vj"
  05               # finish string literal and push to stack
  3e               # index - find index in array or -1 if not found
  26               # decrement
ea                 # map array using block of 3 instructions (indented)

  30               # add 
e0                 # create a block of 1 instruction
6d                 # scan (create running total array of array using block)
40                 # duplicate top of stack
28                 # get minimum of array
26                 # decrement
cf                 # pop from stack into register D (this is the "highest" the path goes)

  d3               # push onto stack from register D
  31               # subtract
e9                 # map array using block of 2 instructions

d0                 # push onto stack from register A (unitialized, so it contains stdin)

  4d               # itemize - make singleton array (also is single char string)
  42               # swap top two elements in stack
  5e               # rjust - right justify string
e2                 # make block from 3 instructions
b1                 # zipwith - evaluate block using parallel inputs from two arrays
40                 # duplicate top of stack

  2e               # get length of array/string
e8                 # map array using block of 1 instruction
29                 # get maximum of array
cf                 # pop from stack into register D (this is the "lowest" the path goes)

  d3               # push from register D onto stack
  5c               # ljust - left justify string
e9                 # map array using block of two instructions
9a                 # transpose array of arrays
54                 # show-lines - add a newline to end of each element in array

GS2, 24 octets

J'ai également une solution de 24 octets qui prend moins de soin à calculer la taille de la sortie et aboutit à des espaces supplémentaires. Je préfère celui avec les espaces réduits au minimum.

5e 20 76 6a 05 3e 26 ea 30 e0 6d d0 08 4d 42 d1
30 5e d1 5c 09 b1 9a 54
récursif
la source
1

Crayon , 13 octets (non concurrents)

O"^ vj"\CynIq

Essayez-le en ligne! Utilise les vraies flèches car pourquoi pas.

Non compétitif car Crayon est bien plus récent que ce défi.

Comment ça marche

Crayon est un langage basé sur la pile conçu pour être un tueur lors des défis de l'art ASCII. Il est construit autour de la base d'une sortie "canvas" en 2 dimensions et d'un "crayon", un curseur qui se déplace autour de cette toile. Tout ce qui est envoyé en sortie est dessiné sur la toile à la position du crayon et dans la direction dans laquelle le crayon fait face. Par défaut, le crayon pointe vers l'est (à droite).

O"^ v▼"\CynIq   Implicit: input string is on top of the stack
O               For each char I in the input string:
 "^ v▼"          Push this string.
       \         Swap the top two items (so I is on top).
        C        Take the index of I in the string.
                 This returns 3 for ▼, 2 for v, 0 for ^, and -1 for ▲.
         y       Move the crayon by this number of spaces on the Y-axis (south).
          n      Move the crayon one position north.
                 The crayon has now been translated 2 positions south for ▼,
                 1 south for v, 1 north for ^, and 2 north for ▲.
           Iq    Draw I at the crayon. This automatically moves the crayon forward
                 by the length of I, which is 1 in this case.
ETHproductions
la source
0

pb - 136 octets

^w[B!0]{>}v[3*X]<[X]<b[1]^[Y]^>w[B!0]{t[B]<vw[B=0]{v}>w[T=107]{^^b[T]t[0]}w[T=94]{^b[T]t[0]}w[T=118]{vb[T]t[0]}w[T!0]{vvb[T]t[0]}^[Y]^>}

Usages ket jau lieu de et .

Quelques notes:

  • Escape sequences that move the cursor such as \e[B are not allowed. You must produce the output using spaces and newlines.Je suis cette règle! pb utilise le concept de "pinceau" pour afficher les caractères. La brosse se déplace autour de la "toile" et peut imprimer un caractère juste en dessous. Cependant, l'implémentation réelle imprime le caractère à l'aide d'espaces et de nouvelles lignes.
  • Je n'allais pas m'embêter avec ce défi même si je pensais que ce serait amusant avec pb jusqu'à ce que je voie la décision You are allowed trailing spaces and/or empty lines. Ceci pour deux raisons:
    • pb ne peut pas ne pas avoir d'espaces de fin. Il produit toujours une sortie rectangulaire, en ajoutant des espaces si nécessaire.
    • Ce programme produit beaucoup de lignes vides. Il ne sait pas quelle sera la hauteur de la sortie lorsqu'il commencera à la produire, donc pour une entrée de longueur, nil commence à Y=3n+1. Le -1est parce qu'il va vers le bas à 3npartir Y=-1, et à partir Y=2n-1échoue pour une entrée de tous k.

Vous pouvez regarder ce programme en action sur YouTube! Cette version est légèrement modifiée en ce sens qu'elle ne descend que n-1. Cela fonctionne pour cette entrée, mais échouera pour les autres. Il capture cependant beaucoup mieux.

Avec des commentaires:

^w[B!0]{>}             # Go to the end of the input
v[3*X]                 # Go down 3 times the current X value
<[X]<                  # Go to X=-1 (off screen, won't be printed)
b[1]                   # Leave a non-zero value to find later
^[Y]^>                 # Back to the beginning of the input
w[B!0]{                # For every byte of input:
    t[B]                 # Copy it to T
    <vw[B=0]{v}>         # Go 1 to the right of the character to the left
                         # (either the last one printed or the value at X=-1)
                         # Move the correct amount for each character and print it:
    w[T=107]{^^b[T]t[0]} # k
    w[T=94]{^b[T]t[0]}   # ^
    w[T=118]{vb[T]t[0]}  # v
    w[T!0]{vvb[T]t[0]}   # j (Every other possibility sets T to 0, so if T is not 0
                         #    it must be j. T!0 is shorter than T=106)
    ^[Y]^>               # To the next byte of input to restart the loop
}
métro monorail
la source
0

Ceylan, 447 octets

import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}

Ou avec des sauts de ligne pour "lisibilité": import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}

Cela fonctionne avec les entrées ▲ / ▼ et j / k (si nous devions prendre en charge une seule d'entre elles, le programme serait plus court de 8 octets). La dernière ligne de sortie est vide quand la position de départ était dessus (c’est-à-dire que la première entrée était un ou ^et nous n’avons plus jamais été en dessous plus tard). Les entrées qui ne sont pas l'un des caractères spécifiés seront simplement imprimées telles quelles, sans changer de ligne:

v^^vv^^vvv^v^v^^^Hellovvvv^^v^^vv

  ^   ^         ^Hello
 ^ v ^ v       ^      v       ^
v   v   v ^ ^ ^        v   ^ ^ v
         v v v          v ^ v   v
                         v

Voici une version formatée (753 octets):

shared void y() {
    variable L c;
    variable L f;
    variable L l;
    variable Integer i = 0;
    class L(variable L? p, variable L? n) {
        shared variable String t = "";
        shared L u => p else (f = p = L(null, this));
        shared L d => n else (l = n = L(this, null));
        shared void a(Character c) => t = t + " ".repeat(i - t.size) + c.string;
    }
    f = l = c = L(null, null);
    for (x in process.readLine() else "") {
        switch (x)
        case ('^') { c = c.u; }
        case ('v') { c = c.d; }
        case ('▲' | 'k') { c = c.u.u; }
        case ('▼' | 'j') { c = c.d.d; }
        else {}
        c.a(x);
        i++;
    }
    print(f.t);
    while (f != l) {
        f = f.d;
        print(f.t);
    }
}

Ceci est un programme "orienté objet" presque direct ... la classe (locale) Lstocke une ligne de texte (en t), ainsi que des pointeurs (nullables) vers le next ( n) et le précédent ( p) ligne. Les attributs (non nullables) u(pour up) etd (pour le bas) initialisent ceux si nécessaire (avec un pointeur inversé sur lui-même), et dans ce cas gardent également une trace de la première et de la dernière ligne dans son ensemble (dans les variables fet l).

le a méthode (append) ajoute un caractère à cette ligne, y compris certains espaces éventuellement nécessaires.

cest la ligne actuelle. Nous analysons la chaîne d'entrée (en utilisantreadLine comme entrée devrait être sur une seule ligne) en utilisant une instruction switch qui met à jour la ligne actuelle, puis appelons la méthode append.

Une fois l’analyse terminée, nous parcourons les lignes du premier au dernier en imprimant chacune d’elles. (Ceci détruit lef pointeur, s'il était nécessaire par la suite, nous aurions dû utiliser une variable distincte pour cela.)

Quelques astuces utilisées pour jouer au golf:

  • Certains éléments qui dans d'autres langues seraient des mots-clés ne sont en réalité que des identificateurs dans le ceylon.languagepackage, et peuvent être renommés avec une importation d'alias - nous l'avons utilisé pour les annotations shared(utilisé 5 ×) et variable(utilisé 6 ×), ainsi que pour l'objet null(utilisé 4 ×):

    import ceylon.language{o=null,v=variable,s=shared}
    

    (Jeu-questionnaire: Le formateur de l'IDE de Ceylan formate certaines annotations de langage intégrées, entre elles variableetshared , en les plaçant dans la même ligne que la déclaration annotée, par opposition aux annotations personnalisées, placées sur une ligne distincte au-dessus de la déclaration. rend la version formatée du programme de golf illisible, c'est pourquoi j'ai modifié les importations d'alias pour cette version.)

    this, void, case, elseSont des mots clés réels et ne peuvent pas être renommé ainsi, et Integer, Stringet Characterapparaissent une fois chaque, donc il n'y a rien à gagner par l' importation.

  • A l'origine, j'avais également une classe ScreenBuffer distincte (qui gardait une trace de la liste chaînée des tampons de lignes, de l'index actuel, etc.), mais comme il n'y en avait qu'un seul objet, il était optimisé.

  • Cette classe Screenbuffer avait aussi upet downméthodes, qui ont été appelées à partir de l’analyseur (et viennent de le faire, currentLine = currentLine.uprespectivement currentLine = currentLine.down). Cela montrait que faire cela directement dans le commutateur de l'analyseur est plus court. Il a également permis d'écrire currentLine = currentLine.up.up(qui est devenu plus tard c = c.u.u) au lieu de currentLine = currentLine.up;currentLine = currentLine.up.

  • À l'origine, nous avons passé l'index actuel en tant qu'argument dans la méthode append (et même à l'analyseur syntaxique de la boucle) - le fait de lui attribuer une variable dans la fonction conteneur est plus court.

  • À l'origine, ma méthode printAll utilisait le pointeur actuel et le déplaçait d'abord jusqu'à ce que la ligne en cours soit vide, puis vers le bas pendant l'impression de chaque ligne. Cela cassait lors de l'utilisation de ▲ et ▼ pour sauter par-dessus des lignes, nous avons donc dû ajouter explicitement quelque chose dans ces lignes sautées. Garder une trace de la première / dernière ligne s’est avéré plus facile (bien qu’il ait été nécessaire d’utiliser deux instructions print, car il n’ya pas de boucle continue à Ceylan).

  • À l'origine, j'avais quelque chose comme ça:

      String? input = process.readLine();
      if(exists input) {
         for(x in input) {
             ...
         }
      }
    

    process.readLineretourne nulls'il n'y a pas de ligne pouvant être lue (parce que l'entrée a été fermée), et le compilateur de Ceylan exige que je vérifie cela avant d'accéder input. Comme dans ce cas je ne veux rien faire, je peux utiliser de manière équivalente l' elseopérateur qui renvoie son premier argument sinon null, et sinon son deuxième argument en sauvegardant la variable et l'instruction if. (Cela aussi nous permettrait de coder une entrée par défaut pour tester: for (x in process.readLine() else "^^▲^v▼▲^^v") {)

Paŭlo Ebermann
la source
0

JavaScript (ES6), 228 octets

E=(r,p=(' '[M='repeat'](Z=r.length)+',')[M](Z*4),i=Z*2,k=0)=>Z>k?E(r,(p.split(',').map((o,q)=>q==i?o.slice(0,k)+r[k]+o.slice(k++):o)).join`,`,i+(H={'^':-1,k:-2,j:2,v:1})[r[k]],k):p.split(',').join`
`.replace(/\s+\n$|^\s+\n/g,'')

Eh bien, voici une solution récursive (assez longue) qui passe avec succès tous les cas de test donnés. C'était un beau défi. Cette utilise ket jà la place de et .

Test Snippet

Bien que la soumission elle-même ne puisse gérer que k,j, l'extrait suivant peut gérer à la fois k,jet ▼,▲.

E=(r,p=(' '[M='repeat'](Z=r.length)+',')[M](Z*4),i=Z*2,k=0)=>Z>k?E(r,(p.split(',').map((o,q)=>q==i?o.slice(0,k)+r[k]+o.slice(k++):o)).join`,`,i+(H={'^':-1,k:-2,j:2,v:1})[r[k]],k):p.split(',').join`
`.replace(/\s+\n$|^\s+\n/g,'')
Input: <input type="text" oninput=o.textContent=E(this.value.replace(/▲/g,'k').replace(//g,'j'))></input>
<pre id='o'></pre>

R. Kap
la source