Zeichnen Sie eine holprige Zeichenfolge

26

( Inspiriert von dieser Herausforderung .)

Nehmen wir an, wir haben eine Zeichenfolge ABBCBA. Wir können sagen , dass es einen Anstieg zwischen Aund Bzum Bfolgt A; wir können sagen, dass es einen Lauf zwischen Bund gibt B, denn nichts ändert sich; und schließlich können wir sagen, dass es einen Abfall zwischen Cund gibt B. Wir können eine Grafik wie diese zeichnen:

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

Ohne die Beschriftungen und Minimieren von Leerzeichen:

o o
 o
   oo

Dies ist die erwartete Ausgabe für die Eingabe ABBCBA.

Sie können ein beliebiges Nicht-Leerzeichen verwenden, um es oin der Ausgabe zu ersetzen . Ferner kann jede Spalte optional einen zusätzlichen Abstand zwischen sich haben, wie z.

o   o
  o 
      o o

Die Eingabe besteht aus mindestens drei Zeichen. Die Zeichenfolge besteht ausschließlich aus Großbuchstaben. Sie können jedoch auch Kleinbuchstaben verwenden.

Testfälle

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
quelle
Kann zwischen den aufeinanderfolgenden os ein Leerzeichen sein oder muss die Ausgabe kompakt sein?
JungHwan Min
@ JHM Sicher, das ist in Ordnung.
Conor O'Brien
Muss die Ausgabe auch eine Zeichenfolge sein oder muss sie nur ähnlich wie im Beispiel aussehen?
JungHwan Min
@JHM Woran denkst du?
Conor O'Brien
Der Code, den ich vorhabe, generiert ein Raster.
JungHwan Min

Antworten:

6

Jelly , 11 Bytes

OIṠ“ o ”ṙZY

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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
quelle
11

Mathematica, 93 83 68 64 Bytes

(verwendet 0, nicht O)

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

Erläuterung

LetterNumber@#

Ruft die Position der einzelnen Zeichen der Eingabe im Alphabet ab.

Sign@Differences@

Nimmt den Unterschied zwischen aufeinanderfolgenden Elementen und nimmt das Vorzeichen ( -1für negativ / fallend, 0für 0 / anhaltend, 1für positiv / steigend)

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

Fügt a 0in eine Liste von zwei Nulls ein, an der ersten Position, wenn es steigt, in der Mitte, wenn es weitergeht, und an der dritten Position, wenn es fällt.

Row[Column@ ... ]

Formatiert die Ausgabe.


Wenn die Ausgabe anders aussehen könnte als in der Frage, könnte der obige Code auf 41 Byte verkürzt werden:

ListPlot@*Sign@*Differences@*LetterNumber

... was so etwas schafft (für "ABBCBA"):

Bildbeschreibung hier eingeben

JungHwan min
quelle
Wie sieht das 41 Byte aus?
Conor O'Brien
@ ConorO'Brien bitte unter bearbeiten.
JungHwan Min
10

MATL , 15 , 14 Bytes

dZSqtQtQv~79*c

Probieren Sie es online!

Erläuterung:

Sie sagen, ein Bild sagt mehr als tausend Worte. Hier ist ein Beta-Online-Interpreter , der Ihnen den Wert auf dem Stapel live anzeigt, wenn er aktualisiert wird. Beachten Sie, dass es sich noch in der Beta-Phase befindet, sodass Sie möglicherweise mehrmals auf Ausführen klicken müssen.

Also rufen wir zuerst an dZS. dgibt uns den Unterschied zwischen jedem aufeinanderfolgenden Element und ZSdas Vorzeichen (-1, 0 oder 1) jedes Elements. Also mit 'HELLOWORLD' als Eingabe haben wir nach dem ersten Schritt:

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

Jetzt qdekrementieren wir dies einfach und erhalten:

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

Und dann duplizieren wir zweimal den oberen Teil des Stapels und erhöhen das Array ( tQ). Danach haben wir

-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

Jetzt wollen wir in allen Nullen ein Zeichen ausgeben. Also fügen wir diese drei Arrays zu einer Matrix zusammen ( v) und negieren sie logisch ( ~). Dann multiplizieren wir jeden Wert in der Matrix mit dem ASCII-Wert von 'O' ( 79*) und zeigen ihn als Zeichenfolge mit an c.

DJMcMayhem
quelle
Sobald Sie den Vektor [-1, 1, 0, 1, ...] haben, können Sie sie als Zeilenindizes einer dünnen Matrix mit Spaltenindizes [1,2,3,4, ...] verwenden wandle es in eine vollständige Matrix um.
Nick Alger
Okay, egal, versucht diesen Vorschlag, scheint nichts zu retten
Nick Alger
@ NickAlger Trotzdem danke für den Tipp! Könnte ich aus Neugier sehen, was Ihnen eingefallen ist?
DJMcMayhem
Sicher. Das Folgende ist 19 Zeichen, obwohl es wahrscheinlich ein paar verbessert werden könnte, dZS2 + tn: tnZ? XPg79 * c
Nick Alger
Mit ein paar Optimierungen auf 16 gekommen, dZSqq_tn: lZ? 79 * c
Nick Alger
8

Haskell, 63 Bytes

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

Gibt eine Liste mit drei Zeichenfolgen zurück, die die Ausgabezeilen darstellen. Enthält keine unterschwelligen Botschaften.

dianne sparte drei bytes mit donotation und maxanstelle eines listenverständnisses und last.

Lynn
quelle
3
Großartig, es enthält keine unterschwelligen Botschaften! Was sind diese?
Conor O'Brien
5
['o'|b e y]..
Izabera
Ja, mein Meister Warten Sie, was los ist?
CalculatorFeline
7

CJam , 19 Bytes

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

Verwendet 0anstelle von o.

Probieren Sie es online!

Erläuterung

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
quelle
6

Python 2, 76 71 Bytes

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

Vielen Dank an @xnor für die Benachrichtigung, dass das Zurückgeben einer Liste von Zeichenfolgen zulässig ist.

Teste es auf Ideone .

Dennis
quelle
Sie können eine Liste mit drei Zeichenfolgen ausgeben, mit denen Sie Folgendes ausführen können: a lambda.
Xnor
Ich bin? Das ändert alles.
Dennis
Ich fragte in den Kommentaren, weil Lynns Haskell-Antwort es tat.
Xnor
6

JavaScript (ES6), 96 95 89 87 82 Byte

2 Bytes gespart durch Verwendung von 0anstelle von o, wie von Conor O'Brien vorgeschlagen,
2 6 Bytes gespart dank 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
quelle
1
Da Sie ein beliebiges Zeichen verwenden können, hilft das Ersetzen 'o'durch ein 0anderes?
Conor O'Brien
@ ConorO'Brien - In der Tat. ;)
Arnauld
1
Ich denke, s=>[1,0,-1].map(k=>[...s].map(c=>(r=p?(c>p)-(c<p)-k&&' ':'',p=c,r),p=0).join``).join`\n` würde funktionieren und 2 Bytes sparen.
ETHproductions
Sie können durch Greifen das vorherige Zeichen jedes Mal ein anderes Byte speichern , anstatt manuell davon zu verfolgen: s=>[1,0,-1].map(k=>[...s].map((c,i)=>(p=s[i-1])?(c>p)-(c<p)-k&&' ':'').join``).join`\n` . s.replacespart Ihnen auch mehrere Bytes [...s].map().join().
ETHproductions
4

Perl, 47 Bytes

Beinhaltet +1 für -p

Geben Sie Input auf STDIN:

bumpy.pl <<< ABBCBA

bumpy.pl:

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

MATL, 16 14 Bytes

dZSqq_tn:79Z?c

Probieren Sie es online!

Dies ergab sich aus einer Diskussion über die Antwort von DJMCMahem . Obwohl diese Antwort 2 Zeichen länger und gleich lang ist, ist die Methode etwas anders, sodass sie von unabhängigem Interesse sein kann.

Danke an Luis Mendo für den Vorschlag, 2 Bytes zu sparen (siehe Kommentare)

Erläuterung:

'dZS' erhält einen Vektor, in dem jeder Eintrag das Vorzeichen der Unterschiede zwischen aufeinanderfolgenden Zeichen ist. Dann dekrementiert 'qq_' jeden Eintrag um zwei und kippt das Vorzeichen um 1, wenn das Zeichen erhöht wird, bleibt es also gleich 2. und wenn es sinkt 3. Zum Beispiel,

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

Als nächstes erstellt 't' eine Kopie des vorherigen Vektors auf dem Stapel, und 'n:' platziert den Vektor [1,2,3,4, ...] ebenfalls auf dem Stapel. Dann setzt '79' den Wert 79 auf den Stapel. Der Wert 79 wird gewählt, da dies die Nummer für das Unicode-Zeichen 'o' ist, das später von uns ausgegeben wird. (Danke an Luis Mendo für die Idee, den Wert 79 hier anstatt später zu setzen)

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

Zu diesem Zeitpunkt haben wir genau die Zeilenindizes, Spaltenindizes und den Wert ungleich Null einer dünnen Matrix, die den Wert 79 hat, wo immer wir das Ausgabezeichen wollen, und 0, wo immer wir das Leerzeichen ausgeben wollen. Wir nehmen diese drei Elemente vom Stapel und erstellen diese Sparse-Matrix mit MATLs Sparse-Matrix-Befehl 'Z?'. Das ist,

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]

Jetzt müssen Sie nur noch die Matrix von Zahlen in Unicode-Zeichen konvertieren, und zwar mit dem Befehl 'c'. Die 79er werden zu 'o' und die 0er werden zu Leerzeichen:

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

Die resultierende Zeichenmatrix wird dann implizit angezeigt.

Nick Alger
quelle
Sie können 79 direkt als Wert ungleich Null für die dünne Matrix verwenden und so zwei Bytes sparen. Außerdem denke ich, dass dies das erste Mal ist, dass spärliche Matrizen in einer MATL-Antwort verwendet werden :-)
Luis Mendo
@ LuisMendo Danke! Ich habe den Beitrag bearbeitet, um die von Ihnen vorgeschlagene Änderung vorzunehmen
Nick Alger
3

PHP, 95 Bytes

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

1.Erstellen Sie ein String-Array mit der Alternative Index -1 bis 1 $b=array_fill(-1,3," ");

2.Füllen Sie die vom Raumschiff-Operator und der Position der Eingabe abhängigen Zeichenfolgen aus

3.Ausgabe verbinden Sie das Array mit einer neuen Zeile

Erster Weg 111 Bytes

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

Verwenden Sie den Raumschiff-Operator <=> Raumschiff-Operator

Jörg Hülsermann
quelle
1
Wenn Sie Ihr Programm in Latin-1 kodieren , ist dies eine praktische Abkürzung für "\n". Nein im Ernst!
Lynn
1
Gleiches für " ", was sein kann . Beispiel. Sie möchten Ihre Browserkodierung auf Latin-1 einstellen, wenn Sie diese anzeigen.
Lynn
@Lynn oder ~ ³ ~ † ~ '~' Danke für die Idee. Ich bevorzuge Unicode
Jörg Hülsermann
2

JavaScript (ES6), 81 Byte

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

Es wurde von Grund auf neu geschrieben, obwohl es stark von der Antwort von @ Arnauld inspiriert war . Verwendet die Rekursion, um den Inhalt jeder Zeile zu berechnen.

ETHproductions
quelle
2

Ruby, 66 64 Bytes

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

Sehen Sie es auf eval.in: https://eval.in/649503

Jordan
quelle
2

Java 7, 158 156 Bytes

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 Bytes gespart dank @Frozn .

Ungolfed & Testfälle:

Probieren Sie es hier aus.

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

Ausgabe:

 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
quelle
1
Ich bin mir nicht sicher, ob das funktioniert, a,b,c=b=a=""würde aber kürzer sein.
Frozn
@Frozn Danke, bearbeitet. Es funktioniert in der Tat. PS: Sie hätten sich in der Idee vergewissern können, indem Sie sie gegabelt hätten. ;)
Kevin Cruijssen
Du hast recht! Ich schaue immer auf die Links und es lohnt sich nicht, Eclipse zu starten :)
Eclipse zu starten Frozn
2

Clora (20 Bytes)

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

Erläuterung:

Es gibt 3 Clora-Programme, eines für jede Ausgabezeile.

Erstes Programm, <IN?o

Überprüfen Sie, ob das aktuelle Eingangszeichen angezeigt wird I kleiner <als das nächste Zeichen ist N. Speichern Sie das Ergebnis in einem globalen Flag. Überprüfen Sie das Ergebnis des Flags ?und geben Sie, falls es wahr ist o, ein Leerzeichen aus (ja, es gibt dort ein Leerzeichen).

Alle anderen Programme folgen der gleichen Regel und werden durch getrennt ;, jedes Programm wird ausgeführt und erhält die Eingabe als Argument.

Sie können es selbst testen, einschließlich clora.js, und es mit ausführen

(function() {
  var x = new Clora('<IN?o ;=IN?o ;>IN?o ');
  x.execute('EXAMINATION', function(r) {
    console.log(r)
  })
})();
OPSXCQ
quelle
Dies scheint absolut konkurrenzlos zu sein, da es nach dieser Herausforderung entstanden ist. Das sieht aber nach einer interessanten Sprache aus!
Conor O'Brien
1

Pyth, 21 Bytes

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

Ein Programm, das die Eingabe eines nicht zitierten Strings in STDIN akzeptiert und das Ergebnis ausgibt.

Dies basiert auf einer ähnlichen Idee wie die Antwort von @ MartinEnder auf CJam .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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
quelle
1

PHP 7, 81 80 77 Bytes

Hinweis: Verwendet die Windows-1252-Codierung

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

Laufen Sie wie folgt:

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

Erläuterung

Iteriert über Leitungen (numeriert 1, 0, -1). Anschließend wird die Eingabezeichenfolge für jede Zeile durchlaufen. Wenn das Ergebnis des Raumschiffvergleichs der Zeilennummer entspricht o, geben Sie andernfalls ein Leerzeichen aus. Drucken Sie nach jeder Zeile eine neue Zeile.

Optimierungen

  • Hör auf zu iterieren, wann $xist -1, was wir durch binäre Negation finden können0 ) finden können. Speichert ein Byte im Vergleich zum Addieren 1(oder 2 mit Vorinkrementierung).
  • 3 Bytes mit gespeichert $argn
aross
quelle
1
Sie haben vergessen -d error_reporting=30709, Ihre Byteanzahl zu erhöhen.
Titus
@Titus Warum in aller Welt muss ich das zur Byteanzahl hinzufügen? Es ist nur so, dass PHP Notices (die ignorierbar sind) nicht gedruckt werden!
Uhr
Könnte auch hinzufügen 2>/dev/null, aber das wird ALLE Fehler beseitigen, einschließlich fatal
aross
So etwas wie If you get warnings, set the default value with .... Bitte entschuldigen Sie meine Pedanterie; Diesen Wert habe ich nicht dekodiert.
Titus
0

Lua 326 303 Bytes tl = 0 s = io.read () o1, o2, o3 = "", "", "" t = {} für i = 1, # s do t [i] = s: sub (i , i) tl = tl + 1 ende für v = 1, tl-1 tue, wenn t [v] t [v + 1], dann ist o1 = o1 .. o2 = o2 .. o3 = o3 .. o "Ende Ende Drucken (o1 .." \ n ".. o2 .." \ n ".. o3)

Eine ungolfed Version

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
quelle
Ich denke, Sie können ein bisschen Leerzeichen ausspielen, sagen wir t1 = 0? zu t1=0? Und ähnliche Orte.
Conor O'Brien
Ich werde das jetzt beheben
Alex Allen
0

R, 114 Bytes

Eine nicht konkurrierende R-Antwort.

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

Erläuterung

  1. Lesen Sie die Eingabe von der Befehlszeile und konvertieren Sie sie in einen ASCII-Dezimalvektor
  2. Nehmen Sie die 1. Differenz und erstellen Sie 3x Vektoren gleicher Länge mit Leerzeichen
  3. Ersetzen Sie dann die Leerraumvektoren durch, #wenn die Unterschiede sind >0, ==0oder <0.
  4. Erzwinge die Vektoren und drucke sie getrennt durch Zeilenumbrüche
Billywob
quelle
Warum nicht konkurrieren?
Conor O'Brien
@ ConorO'Brien Ich denke, es konkurriert mit anderen R-Antworten, aber die ursprüngliche Lösung war viel zu lang und nicht eindeutig genug, um im allgemeinen Sinne interessant zu sein.
Billywob