Dessiner une chaîne cahoteuse

26

( Inspiré par ce défi .)

Disons que nous avons une chaîne ABBCBA. On peut dire qu'il y a une montée entre Aet B, pour ce qui Bsuit A; on peut dire qu'il y a une course entre Bet B, pour rien ne change; et enfin nous pouvons dire qu'il y a une chute entre Cet B. Nous pouvons dessiner un graphique comme celui-ci:

             A   B   B   C   B   A
Rising:        o       o
Continuing:        o
Falling:                   o   o

Sans les étiquettes et en minimisant les espaces blancs:

o o
 o
   oo

Il s'agit de la sortie attendue pour l'entrée ABBCBA.

Vous pouvez utiliser n'importe quel caractère non blanc pour remplacer odans la sortie. De plus, chaque colonne peut éventuellement avoir un espace supplémentaire entre elles, comme ceci:

o   o
  o 
      o o

L'entrée comprendra au moins trois caractères. La chaîne sera entièrement composée de lettres majuscules, mais vous pouvez utiliser à la place des lettres minuscules.

Cas de test

TEST CASE
LINE 1
LINE 2
LINE 3

HELLOWORLD
 o oo o
  o
o    o oo

TESTCASE
 oo  o

o  oo o

EXAMINATION
o o o o o

 o o o o o

ZSILENTYOUTH
  o ooo o

oo o   o oo

ABC
oo



ABCBA
oo

  oo
Conor O'Brien
la source
Pourrait-il y avoir un espace entre chaque os consécutif , ou la sortie doit-elle être compacte?
JungHwan Min
@JHM Bien sûr, ça va.
Conor O'Brien
De plus, la sortie doit-elle être une chaîne ou doit-elle uniquement ressembler à l'exemple?
JungHwan Min
@JHM A quoi pensez-vous?
Conor O'Brien
Le code que j'ai en tête génère une grille.
JungHwan Min

Réponses:

6

Gelée , 11 octets

OIṠ“ o ”ṙZY

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

OIṠ“ o ”ṙZY  Main link. Argument: s (string)

O            Ordinal; replace all characters with their code points.
 I           Increments; compute the differences of consecutive code points.
  Ṡ          Sign function.
   “ o ”ṙ    Rotate that string -1, 0, or 1 unit(s) to the left.
         Z   Zip; transpose rows and columns.
          Y  Join, separating by linefeeds.
Dennis
la source
11

Mathematica, 93 83 68 64 octets

(utilise 0, pas O)

Row[Column@Insert[{,},0,2-#]&/@Sign@Differences@LetterNumber@#]&

Explication

LetterNumber@#

Obtient la position dans l'alphabet de chaque caractère de l'entrée.

Sign@Differences@

Prend la différence entre chaque élément consécutif et prend le signe ( -1pour négatif / descendant, 0pour 0 / continu, 1pour positif / montant)

Insert[{,},0,2-#]&

Insère un 0dans une liste de deux Nulls, dans la première position si elle augmente, au milieu si elle continue et la troisième position si elle baisse.

Row[Column@ ... ]

Formate la sortie.


Si la sortie pouvait sembler différente de celle de la question, le code ci-dessus pourrait être raccourci à 41 octets:

ListPlot@*Sign@*Differences@*LetterNumber

... qui crée quelque chose comme ça (pour "ABBCBA"):

entrez la description de l'image ici

JungHwan Min
la source
À quoi ressemble le 41 octets?
Conor O'Brien du
@ ConorO'Brien s'il vous plaît voir modifier.
JungHwan Min
10

MATL , 15 , 14 octets

dZSqtQtQv~79*c

Essayez-le en ligne!

Explication:

Ils disent qu'une image vaut mille mots, alors voici un interprète en ligne bêta qui vous montre la valeur en haut de la pile en direct lors de sa mise à jour. Notez qu'il est toujours en version bêta, vous devrez donc peut-être exécuter plusieurs fois.

Alors d'abord, nous appelons dZS. dnous donne la différence entre chaque élément consécutif et ZSnous donne le signe (-1, 0 ou 1) de chaque élément. Donc, avec «HELLOWORLD» en entrée, après la première étape, nous aurons:

-1  1  0  1  1 -1  1 -1 -1

Maintenant, nous utilisons juste qpour décrémenter cela et obtenir:

-2  0 -1  0  0 -2  0 -2 -2

Et puis deux fois, nous dupliquons le haut de la pile et incrémentons le tableau ( tQ) Après cela, nous aurons

-2  0 -1  0  0 -2  0 -2 -2
-1  1  0  1  1 -1  1 -1 -1
0   2  1  2  2  0  2  0  0

Maintenant, tous les «0» sont là où nous voulons sortir un caractère. Donc, nous joignons ces trois tableaux en une matrice ( v), et la nions logiquement ( ~). Ensuite, nous multiplions chaque valeur de la matrice par la valeur ASCII de «O», ( 79*) et l'affichages sous forme de chaîne avec c.

DJMcMayhem
la source
Une fois que vous avez le vecteur [-1, 1, 0, 1, ...], vous pouvez les utiliser comme indices de ligne d'une matrice clairsemée avec des indices de colonne [1,2,3,4, ...], puis le convertir en une matrice complète.
Nick Alger
OK peu importe, a essayé cette suggestion, ne semble rien sauver
Nick Alger
@NickAlger Merci pour le conseil quand même! Par curiosité, pourrais-je voir ce que vous avez trouvé?
DJMcMayhem
Sûr. Ce qui suit est de 19 caractères, mais il pourrait probablement être amélioré quelques-uns, dZS2 + tn: tnZ? XPg79 * c
Nick Alger
Je suis arrivé à 16 avec quelques optimisations, dZSqq_tn: lZ? 79 * c
Nick Alger
8

Haskell, 63 octets

f w=[do(e,y)<-zip w$tail w;max" "['o'|b e y]|b<-[(<),(==),(>)]]

Renvoie une liste de trois chaînes, représentant les lignes de sortie. Ne contient aucun message subliminal.

dianne a économisé trois octets en utilisant la donotation et maxau lieu d'une compréhension de liste et last.

Lynn
la source
3
Génial, il ne contient aucun message subliminal! Quels sont ces?
Conor O'Brien
5
['o'|b e y]..
izabera
Oui, mon maître Attends ce qui se passe?
CalculatorFeline
7

CJam , 19 octets

l2ew{:-g)S3*0t}%zN*

Utilise 0au lieu de o.

Essayez-le en ligne!

Explication

l      e# Read input.
2ew    e# Get all pairs of consecutive letters.
{      e# Map this block over the pairs...
  :-   e#   Compute the difference between the two letters.
  g    e#   Signum. Gives -1 for rises, 1 for falls, 0 otherwise.
  )    e#   Increment. Gives 0 for rises, 2 for falls, 1 otherwise. Call this i.
  S3*  e#   Push a string with three spaces.
  0t   e#   Replace the i'th space (zero-based) with a zero.
}%
z      e# Transpose.
N*     e# Join with linefeeds.
Martin Ender
la source
6

Python 2, 76 71 octets

lambda s:[''.join(' o'[cmp(*x)==n]for x in zip(s,s[1:]))for n in-1,0,1]

Merci à @xnor de m'avoir informé que le retour d'une liste de chaînes est autorisé.

Testez-le sur Ideone .

Dennis
la source
Vous êtes autorisé à afficher une liste de trois chaînes, ce qui vous permet de faire un lambda.
xnor
Je suis? Cela change tout.
Dennis
J'ai demandé dans les commentaires parce que la réponse de Lynn Haskell le faisait.
xnor
6

JavaScript (ES6), 96 95 89 87 82 octets

2 octets enregistrés en utilisant 0au lieu de o, comme suggéré par Conor O'Brien
2 6 octets enregistrés grâce à ETHproductions

let f =

s=>[1,0,-1].map(k=>s.replace(/./g,(c,i)=>i--?(c>s[i])-(c<s[i])-k&&' ':'')).join`
`

console.log(f("HELLOWORLD"));
console.log(f("EXAMINATION"));

Arnauld
la source
1
Étant donné que vous pouvez utiliser n'importe quel caractère, le remplacement 'o'par une 0aide est-il utile?
Conor O'Brien
@ ConorO'Brien - En effet, c'est le cas. ;)
Arnauld
1
Je pense que s=>[1,0,-1].map(k=>[...s].map(c=>(r=p?(c>p)-(c<p)-k&&' ':'',p=c,r),p=0).join``).join`\n` cela fonctionnerait, économisant 2 octets.
ETHproductions
Vous pouvez enregistrer un autre octet en saisissant le caractère précédent à chaque fois au lieu de garder manuellement trace de celui - ci: s=>[1,0,-1].map(k=>[...s].map((c,i)=>(p=s[i-1])?(c>p)-(c<p)-k&&' ':'').join``).join`\n` . s.replacevous fera également économiser plusieurs octets [...s].map().join().
ETHproductions
4

Perl, 47 octets

Comprend +1 pour -p

Donnez votre avis sur STDIN:

bumpy.pl <<< ABBCBA

bumpy.pl:

#!/usr/bin/perl -p
$_ x=3;s%.%/\G(.)(.)/?$2cmp$1^$.&&$":--$.>0%eg
Ton Hospel
la source
4

MATL, 16 14 octets

dZSqq_tn:79Z?c

Essayez-le en ligne!

Cela est né d'une discussion sur la réponse de DJMCMahem . Même si cette réponse fait 2 caractères de plus sur la même longueur, la méthode est quelque peu différente et peut donc être d'un intérêt indépendant.

Merci à Luis Mendo pour une suggestion économisant 2 octets (voir commentaires)

Explication:

'dZS' obtient un vecteur où chaque entrée est le signe des différences entre les caractères successifs, puis 'qq_' décrémente chaque entrée de deux et retourne le signe, alors maintenant si le caractère augmente il est 1, s'il reste le même 2, et si elle diminue 3. Par exemple,

dZSqq_ applied to 'HELLOWORLD' creates the vector [3 1 2 1 1 3 1 3 3]

Ensuite, 't' fait une copie du vecteur précédent sur la pile, puis 'n:' place également le vecteur [1,2,3,4, ...] sur la pile. Ensuite, «79» place la valeur 79 sur la pile. La valeur 79 est choisie car c'est le numéro du caractère unicode «o», qui sera notre sortie plus tard. (Merci à Luis Mendo pour l'idée de mettre la valeur 79 ici plutôt que plus tard)

tn:79 applied to [3 1 2 1 1 3 1 3 3] creates the following items:
[3 1 2 1 1 3 1 3 3]   <-- first item on the stack
[1 2 3 4 5 6 7 8 9]   <-- second item on the stack
79                    <-- third item on the stack

À ce stade, nous avons précisément les indices de ligne, les indices de colonne et la valeur non nulle d'une matrice clairsemée qui a la valeur 79 partout où nous voulons le caractère de sortie, et 0 partout où nous voulons sortir des espaces. Nous retirons ces trois éléments de la pile et créons cette matrice clairsemée avec la commande de matrice clairsemée de MATL 'Z?'. C'est,

dZSqq_tn:79 Z? applied to 'HELLOWORLD' outputs the following:
[0  79 0  79 79 0  79 0  0 ]
[0  0  79 0  0  0  0  0  0 ]   <-- 3-by-n sparse matrix
[79 0  0  0  0  79 0  79 79]

Il ne reste plus qu'à convertir la matrice des nombres en caractères unicode, ce qui est fait par la commande 'c'. Les 79 deviennent des «o» et les 0 deviennent des espaces:

dZSqq_tn:79Z?c applied to 'HELLOWORLD' outputs:
[  o   o o   o    ]
[    o            ]   <-- 3-by-n sparse matrix of characters.
[o         o   o o]

La matrice résultante de caractères est alors implicitement affichée.

Nick Alger
la source
Vous pouvez directement utiliser 79 comme valeur non nulle pour la matrice creuse, économisant ainsi deux octets. De plus, je pense que c'est la première fois que des matrices clairsemées sont utilisées dans une réponse MATL :-)
Luis Mendo
@LuisMendo Merci! J'ai édité le post pour apporter le changement que vous proposez
Nick Alger
3

PHP, 95 octets

for($b[1]=$b[0]=$b[-1]=" ";($s=$argv[1])[++$i];)$b[$s[$i-1]<=>$s[$i]][$i]=8;echo join("\n",$b);

1.Créez un tableau de chaînes avec l'index -1 à 1 alternatif $b=array_fill(-1,3," ");

Remplissez les chaînes en fonction de l'opérateur du vaisseau spatial et de la position de l'entrée

3.Output rejoindre le tableau avec une nouvelle ligne

Première voie 111 octets

for($o=" ";$i<$l=strlen($s=$argv[1])-1;)$o[$l*(1+($s[$i]<=>$s[$i+1]))+$i++]=8;echo join("\n",str_split($o,$l));

Utilisez l'opérateur de vaisseau spatial opérateur de <=> vaisseau spatial

Jörg Hülsermann
la source
1
Si vous encodez votre programme en Latin-1 , est un raccourci pratique pour "\n". Non sérieusement!
Lynn
1
Même chose pour " ", qui peut l'être . Exemple. Vous souhaitez définir le codage de votre navigateur sur Latin-1 lorsque vous les visualisez.
Lynn
@Lynn ou ~ ³ ~ † ~ '~' Merci pour l'idée. Je préférerai unicode
Jörg Hülsermann
2

JavaScript (ES6), 81 octets

s=>[s,s,s].map(f=([c,...s],n)=>(p=s[0])?((c<p)-(c>p)+n-1&&" ")+f(s,n):"").join`
`

Écrit à partir de zéro, mais il a été fortement inspiré par la réponse de @ Arnauld . Utilise la récursivité pour calculer le contenu de chaque ligne.

ETHproductions
la source
2

Rubis, 66 64 octets

->s{(-1..1).map{|n|s.gsub(/.(?=(.))/){"o  "[n+($1<=>$&)]}.chop}}

Voir sur eval.in: https://eval.in/649503

Jordan
la source
2

Java 7, 158 156 octets

String c(char[]z){String a,b,c=a=b="";for(char i=1,q=z[0],o=79,s=32,x;i<z.length;a+=(x=z[i])>q?o:s,b+=x==q?o:s,c+=x<q?o:s,q=z[i++]);return a+"\n"+b+"\n"+c;}

2 octets enregistrés grâce à @Frozn .

Cas non testés et testés:

Essayez-le ici.

class M{
  static String c(char[] z){
    String a,
           b,
           c = a = b = "";
    for(char i = 1,
             q = z[0],
             o = 79,
             s = 32,
             x; i < z.length; a += (x = z[i]) > q
                                     ? o
                                     : s,
                              b += x == q
                                     ? o
                                     : s,
                              c += x < q
                                     ? o
                                     : s,
                              q = z[i++]);
    return a + "\n" + b + "\n" + c;
  }

  public static void main(String[] a){
    print("HELLOWORLD");
    print("TESTCASE");
    print("EXAMINATION");
    print("ZSILENTYOUTH");
    print("ABC");
    print("ABCBA");
    print("ABBCBA");
    print("UVVWVVUVVWVVUVVW");
  }

  static void print(String s){
    System.out.println(c(s.toCharArray()));
    System.out.println("-------------------------");
  }
}

Sortie:

 O OO O  
  O      
O    O OO
-------------------------
 OO  O 

O  OO O
-------------------------
O O O O O 

 O O O O O
-------------------------
  O OOO O  

OO O   O OO
-------------------------
OO


-------------------------
OO  

  OO
-------------------------
O O  
 O   
   OO
-------------------------
O O   O O   O O
 O  O  O  O  O 
   O O   O O   
-------------------------
Kevin Cruijssen
la source
1
Je ne sais pas si cela fonctionne mais a,b,c=b=a=""serait plus court.
Frozn du
@Frozn Merci, édité. Cela fonctionne en effet. PS: vous auriez pu vous vérifier dans l'idéone en le forçant. ;)
Kevin Cruijssen
Tu as raison! Je néglige toujours les liens et je
lance l'
2

Clora (20 octets)

<IN?o ;=IN?o ;>IN?o

Explication:

Il existe 3 programmes Clora, un pour chaque ligne de sortie.

Premier programme, <IN?o

Vérifiez si le caractère d'entrée actuel Iest plus petit <que le caractère suivant N. Enregistrez le résultat dans un indicateur global. Vérifiez le résultat de l'indicateur ?et si c'est vrai, affichez o, sinon un espace vide (oui, il y a un espace vide là-bas.

Tous les autres programmes suivent la même règle et sont séparés par ;, chaque programme est exécuté et reçoit l'entrée en argument.

Vous pouvez le tester vous-même, y compris clora.js et l'exécuter avec

(function() {
  var x = new Clora('<IN?o ;=IN?o ;>IN?o ');
  x.execute('EXAMINATION', function(r) {
    console.log(r)
  })
})();
OPSXCQ
la source
Cela semble être strictement non concurrentiel, car il a été créé après ce défi. Cela ressemble à une langue intéressante!
Conor O'Brien
1

Pyth, 21 octets

jCmX*3\ h._d0-M.:CMz2

Un programme qui prend l'entrée d'une chaîne non cotée sur STDIN et imprime le résultat.

Cela utilise une idée similaire à la réponse CJam de @ MartinEnder .

Essayez-le en ligne ou vérifiez tous les cas de test .

Comment ça marche

jCmX*3\ h._d0-M.:CMz2  Program. Input: z
                 CMz   Map ordinal over z, yielding the code-points of the characters
               .:   2  Yield all length-2 sublists of that
             -M        Map subtraction over that
  m                    Map the following over that with variable d:
         ._d            Yield the sign of d
        h               Increment that (i)
    *3\                 Yield string literal of 3 spaces, "   "
   X        0           Replace the space at index i with 0
 C                     Transpose that
j                      Join that on newlines
                       Implicitly print
TheBikingViking
la source
1

PHP 7, 81 80 77 octets

Remarque: utilise le codage Windows-1252

for($x=2;~$x--;print~õ)for($a=$argn;$c=$a[$$x+1];)echo$c<=>$a[$$x++]^$x?~ß:o;

Courez comme ceci:

echo HELLOWORLD | php -nR 'for($x=2;~$x--;print"\n")for($a=$argn;$c=$a[$$x+1];)echo$c<=>$a[$$x++]^$x?" ":o;';echo

Explication

Une itération sur les lignes (numérotées 1, 0, -1). Puis itère sur la chaîne d'entrée pour chaque ligne. Lorsque le résultat de la comparaison du vaisseau spatial est égal au numéro de ligne, affichez un o, sinon, affichez un espace. Après chaque ligne, imprimez une nouvelle ligne.

Tweaks

  • Arrêtez d'itérer quand $xest -1, que nous pouvons trouver par négation binaire (résultat 0). Enregistre un octet par rapport à l'ajout 1(ou 2 avec pré-incrémentation).
  • Enregistré 3 octets en utilisant $argn
aross
la source
1
Vous avez oublié d'ajouter -d error_reporting=30709à votre nombre d'octets.
Titus
@Titus Pourquoi diable aurais-je besoin d'ajouter cela au nombre d'octets? C'est seulement pour que les avis PHP (qui sont ignorables) ne soient pas imprimés!
aross
Pourrait également ajouter 2>/dev/null, mais cela supprimera TOUTES les erreurs, y compris fatales
aross
Quelque chose comme If you get warnings, set the default value with .... Veuillez excuser mon pédanterie; Je n'ai pas décodé cette valeur.
Titus
0

Lua 326 303 octets tl = 0 s = io.read () o1, o2, o3 = "", "", "" t = {} for i = 1, # s do t [i] = s: sub (i , i) tl = tl + 1 extrémité pour v = 1, tl-1 si t [v] t [v + 1] alors o1 = o1 .. "" o2 = o2 .. "" o3 = o3 .. " o "end end print (o1 .." \ n ".. o2 .." \ n ".. o3)

Une version non golfée

tl = 0 --set the tables length to 0
s = io.read() --Get the string from input
o1,o2,o3="","","" --Set the 3 output rows to empty strings
t = {} --Make a table for the string to be sent into
for i = 1, #s do --Loop from 1 to the length of the string
    t[i] = s:sub(i, i) --Set the I-th term in the table to the I-th character in the string
    tl = tl+1 --Add 1 to the table length
end --End the loop
for v=1,tl-1, 1 do --Loop from 1 to the tables length - 1, incrementing by 1
    if t[v] < t[v+1] then --Lua supports greater than less than and equals to with charactes, so this if statement detects if the string is rising
        o1=o1.."o" --Adds an o to the end of the first line of output
        o2=o2.." " --Adds a space to the second line
        o3=o3.." " --Adds a space to the third line
    elseif t[v] == t[v+1] then --Detects if the string is continuing
        o1=o1.." " --Adds a space to the first line
        o2=o2.."o" --Adds an o to the second line
        o3=o3.." " --Adds a space to the third line
    elseif t[v] > t[v+1] then --Detects if string is falling
        o1=o1.." " --Adds a space to the first line
        o2=o2.." " --Adds a space to the second line
        o3=o3.."o" --Adds an o to the third line
    end --Ends the if statement
end --Ends the loop
print(o1.."\n"..o2.."\n"..o3) --Prints the output
Alex Allen
la source
Je pense que vous pouvez jouer au golf à partir de, disons t1 = 0,? à t1=0? Et des endroits similaires.
Conor O'Brien
Je vais corriger ça maintenant
Alex Allen
0

R, 114 octets

Une réponse R non concurrente.

v=y=z=rep(" ",length(x<-diff(utf8ToInt(scan(,"")))));v[x>0]="#";y[x==0]="#";z[x<0]="#";cat(v,"\n",y,"\n",z,sep="")

Explication

  1. Lire l'entrée depuis la ligne de commande et convertir en vecteur décimal ascii
  2. Prenez la 1ère différence et créez 3 vecteurs de même longueur avec des espaces blancs
  3. Remplacez ensuite les vecteurs d'espace blanc par #si les différences sont >0, ==0ou <0.
  4. Forcer les vecteurs et les imprimer séparés par des retours à la ligne
Billywob
la source
Pourquoi non compétitif?
Conor O'Brien
@ ConorO'Brien Je suppose que c'est en concurrence avec d'autres réponses R mais la solution originale était trop longue et pas assez unique pour être intéressante au sens général.
Billywob