La saisie comprendra les caractères suivants:
^
: Montez unv
: Descendre un▲
ouk
: montez deux▼
ouj
: 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[B
sont 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
j
de descendre deux fois etk
de monter deux fois de plus.Réponses:
Pyth, 27 octets
Essayez-le en ligne: démonstration ou suite de tests
J'utilise
k
etj
au 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.Essayez-le en ligne: démonstration ou suite de tests
Explication:
la source
Illisible ,
219921452134210420872084 octetsPrend en charge les deux
k
/j
ainsi que▲
/▼
syntaxe.Dans la bonne tradition Illisible, voici le programme formaté en fonte proportionnelle, pour brouiller la distinction entre apostrophes et doubles guillemets:
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:
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 = 1
devient 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: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
mod5
revient 10 fois. Mais nous n’avons plus besoin de lamod5
fin 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 sontptr2
etptr3
. 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 comptera++
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,
ch
n'est plus nécessaire.up
etdn
revenez le même nombre de fois, donc ça va. Fusionnonsch
avecup
.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:
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
ptr
etminLine
peuvent ê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 4ptr
devrait-elle être ou devrait-elle êtreminLine
? C'est vrai,minLine
n'est plus utilisé à ce stade non plus! Ainsi, la variable n ° 4 estminLine
et 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
dn
peut également être fusionné avecmod5
, même simod5
est toujours utilisé dans le calcul de la valeur pourdn
! La nouvelle affectation de variable est maintenant:MISE À JOUR 2! Passez de 2145 à 2134 octets en réalisant que, depuis
mod5
est maintenant dans la même variable quedn
, qui est comptée à 0 dans une boucle while, ilmod5
n'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 pasmod4
car nous n’effectuons jamais de tests,mod4+2
etc. Par conséquent, passermod4 ? mod4+1 : -3
àmod4 ? mod4-1 : 3
nous prend 2110 octets. Deuxièmement, puisquemod4
vaut toujours 0 ou 2, nous pouvons initialisermod4
à 2 au lieu de 0 et inverser les deux ternaires (mod4 ? 3 : 1
au lieu demod4 ? 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 maintenantup = ((while --ch: [...]) ? mod5+1 ? [...]
(et dans cette boucle while, nous calculons d’mod4
abord, c’estmod5
donc la dernière déclaration).MISE À JOUR 5! Je passe de 2087 à 2084 octets en réalisant qu'au lieu d'écrire les constantes
32
et10
(espace et nouvelle ligne), je peux stocker le nombre 10 dans la variable # 2 (maintenant inutilisée) (appelons-leten
). Au lieu d'ptr3 = 5
écrireten = (ptr3 = 5) + 5
, alors32
devientten+22
etprint 10
devientprint ten
.la source
CJam, 37 octets
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
la source
Python 2, 102
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, -2
calculés par'kv_^j'.find(c)-2
. Il y a probablement une chaîne de mod qui est plus courteLorsque 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 celai
peut être négatif, ce qui élimine certaines astuces habituelles.la source
MATLAB, 116
C'est un début. Le
j
et enk
faire une douleur dans le cou que je ne peux pas trouver un moyen de la carte mathématiquement à partirj^vk
de[-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:
la source
b=[-2 -1 1 2](a==[106 107 94 118])
travailler? Cela fonctionne dans Octave. Ou mêmeb=[-2 -1 1 2](a-94==[12 13 0 24])
si vous voulez supprimer un octet de plus!==
arrêts qui fonctionnent et aussi dans MATLAB, vous ne pouvez pas mettre un()
après a[]
.+=
, fwiw.)JavaScript (ES6), 140
Testez l'exécution de l'extrait de code ci-dessous dans un navigateur compatible EcmaScript 6 (testé sur Firefox).
la source
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
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.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.
la source
Crayon , 13 octets (non concurrents)
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).
la source
pb - 136 octets
Usages
k
etj
au 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.You are allowed trailing spaces and/or empty lines
. Ceci pour deux raisons:n
il commence àY=3n+1
. Le-1
est parce qu'il va vers le bas à3n
partirY=-1
, et à partirY=2n-1
échoue pour une entrée de tousk
.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:
la source
Ceylan, 447 octets
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:→
Voici une version formatée (753 octets):
Ceci est un programme "orienté objet" presque direct ... la classe (locale)
L
stocke une ligne de texte (ent
), 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 variablesf
etl
).le
a
méthode (append) ajoute un caractère à cette ligne, y compris certains espaces éventuellement nécessaires.c
est 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 le
f
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.language
package, et peuvent être renommés avec une importation d'alias - nous l'avons utilisé pour les annotationsshared
(utilisé 5 ×) etvariable
(utilisé 6 ×), ainsi que pour l'objetnull
(utilisé 4 ×):(Jeu-questionnaire: Le formateur de l'IDE de Ceylan formate certaines annotations de langage intégrées, entre elles
variable
etshared
, 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
,else
Sont des mots clés réels et ne peuvent pas être renommé ainsi, etInteger
,String
etCharacter
apparaissent 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
up
etdown
méthodes, qui ont été appelées à partir de l’analyseur (et viennent de le faire,currentLine = currentLine.up
respectivementcurrentLine = currentLine.down
). Cela montrait que faire cela directement dans le commutateur de l'analyseur est plus court. Il a également permis d'écrirecurrentLine = currentLine.up.up
(qui est devenu plus tardc = c.u.u
) au lieu decurrentLine = 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:
process.readLine
retournenull
s'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éderinput
. Comme dans ce cas je ne veux rien faire, je peux utiliser de manière équivalente l'else
opé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") {
)la source
JavaScript (ES6), 228 octets
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
k
etj
à 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 foisk,j
et▼,▲
.la source