Disegna una stringa irregolare


26

( Ispirato da questa sfida .)

Diciamo che abbiamo una stringa ABBCBA. Possiamo dire che c'è un aumento tra Ae B, per quanto Bsegue A; possiamo dire che c'è una corsa tra Be B, per nulla cambia; e infine possiamo dire che c'è una caduta tra Ce B. Possiamo disegnare un grafico come questo:

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

Senza le etichette e minimizzando gli spazi bianchi:

o o
 o
   oo

Questo è l'output previsto per l'input ABBCBA.

È possibile utilizzare qualsiasi carattere non bianco per sostituire ol'output. Inoltre, ogni colonna può facoltativamente avere uno spazio aggiuntivo tra loro, in questo modo:

o   o
  o 
      o o

L'input sarà composto da almeno tre caratteri. La stringa sarà composta interamente da lettere maiuscole, ma puoi invece usare lettere minuscole.

Casi 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

Potrebbe esserci uno spazio tra ogni os consecutivo o l'output deve essere compatto?
JungHwan Min

@JHM Certo, va bene.
Conor O'Brien,

Inoltre, l'output deve essere una stringa o deve solo apparire simile all'esempio?
JungHwan Min

@JHM Cosa hai in mente?
Conor O'Brien,

Il codice che ho in mente genera una griglia.
JungHwan Min

Risposte:


6

Gelatina , 11 byte

OIṠ“ o ”ṙZY

Provalo online! o verifica tutti i casi di test .

Come funziona

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.

11

Mathematica, 93 83 68 64 byte

(usa 0, non O)

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

Spiegazione

LetterNumber@#

Ottiene la posizione nell'alfabeto di ciascun carattere dell'input.

Sign@Differences@

Prende la differenza tra ogni elemento consecutivo e prende il segno ( -1per negativo / in calo, 0per 0 / continuo, 1per positivo / in aumento)

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

Inserisce a 0in un elenco di due Nulls, nella prima posizione se in aumento, in mezzo se continua e nella terza posizione in caso di caduta.

Row[Column@ ... ]

Formatta l'output.


Se l'output potrebbe apparire diverso da quello nella domanda, il codice sopra potrebbe essere ridotto a 41 byte:

ListPlot@*Sign@*Differences@*LetterNumber

... che crea qualcosa del genere (per "ABBCBA"):

enter image description here


Come appare il 41 byte?
Conor O'Brien,

@ ConorO'Brien, vedi modifica.
JungHwan Min

10

MATL , 15 , 14 byte

dZSqtQtQv~79*c

Provalo online!

Spiegazione:

Dicono che un'immagine valga più di mille parole, quindi ecco un interprete online beta che ti mostra il valore in cima allo stack mentre si aggiorna. Nota che è ancora in versione beta, quindi potresti dover eseguire la corsa più volte.

Quindi prima chiamiamo dZS. dci dà la differenza tra ogni elemento consecutivo e ZSci dà il segno (-1, 0 o 1) di ciascun elemento. Quindi, con "HELLOWORLD" come input, dopo il primo passo avremo:

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

Ora, usiamo solo qper diminuire questo e ottenere:

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

E poi due volte dupliciamo la parte superiore dello stack e incrementiamo l'array ( tQ) Dopo ciò avremo

-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

Ora tutti gli '0' sono dove vogliamo produrre un personaggio. Quindi, uniamo queste tre matrici in una matrice ( v) e la neghiamo logicamente ( ~). Quindi moltiplichiamo ogni valore nella matrice per il valore ASCII di 'O', ( 79*) e lo visualizziamo come una stringa con c.


Una volta che hai il vettore [-1, 1, 0, 1, ...], puoi usarli come indici di riga di una matrice sparsa con indici di colonna [1,2,3,4, ...], quindi convertilo in una matrice completa.
Nick Alger,

OK non importa, ho provato quel suggerimento, non sembra salvare nulla
Nick Alger,

@NickAlger Grazie comunque per la segnalazione! Per curiosità, posso vedere cosa ti è venuto in mente?
DJMcMayhem

Sicuro. Di seguito sono 19 caratteri, anche se probabilmente potrebbe essere migliorato alcuni, dZS2 + tn: tnZ? XPg79 * c
Nick Alger,

Sono arrivato a 16 con un paio di ottimizzazioni, dZSqq_tn: lZ? 79 * c
Nick Alger,

8

Haskell, 63 byte

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

Restituisce un elenco di tre stringhe, che rappresentano le linee di output. Non contiene messaggi subliminali.

dianne ha salvato tre byte usando la donotazione e maxinvece di una comprensione dell'elenco e last.


3
Fantastico, non contiene messaggi subliminali! Cosa sono quelli?
Conor O'Brien,

5
['o'|b e y]..
izabera,

Sì, mio ​​maestro Aspetta cosa sta succedendo?
Calcolatrice

7

CJam , 19 byte

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

Utilizza 0invece di o.

Provalo online!

Spiegazione

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.

6

Python 2, 76 71 byte

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

Grazie a @xnor per avermi informato che è consentito restituire un elenco di stringhe.

Provalo su Ideone .


Puoi produrre un elenco di tre stringhe, che ti consente di fare un lambda.
xnor

Sono? Questo cambia tutto.
Dennis,

Ho chiesto nei commenti perché la risposta di Haskell di Lynn lo stava facendo.
xnor

6

JavaScript (ES6), 96 95 89 87 82 byte

2 byte salvati utilizzando 0invece di o, come suggerito da Conor O'Brien
2 6 byte salvati grazie a 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"));


1
Dal momento che è possibile utilizzare qualsiasi personaggio, sostituendo 'o'con 0aiuto c'è?
Conor O'Brien,

@ ConorO'Brien - Anzi, lo fa. ;)
Arnauld il

1
Penso s=>[1,0,-1].map(k=>[...s].map(c=>(r=p?(c>p)-(c<p)-k&&' ':'',p=c,r),p=0).join``).join`\n` che funzionerebbe, risparmiando 2 byte.
Produzioni ETH il

È possibile salvare un altro byte afferrando il carattere precedente ogni volta invece di manualmente tenere traccia di esso: s=>[1,0,-1].map(k=>[...s].map((c,i)=>(p=s[i-1])?(c>p)-(c<p)-k&&' ':'').join``).join`\n` . s.replaceti farà anche risparmiare più byte [...s].map().join().
Produzioni ETH il

4

Perl, 47 byte

Include +1 per -p

Dare input su STDIN:

bumpy.pl <<< ABBCBA

bumpy.pl:

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

4

MATL, 16 14 byte

dZSqq_tn:79Z?c

Provalo online!

Questo è nato da una discussione sulla risposta di DJMCMahem . Anche se questa risposta è di 2 caratteri più lunghi della stessa lunghezza, il metodo è leggermente diverso, quindi potrebbe essere di interesse indipendente.

Grazie a Luis Mendo per un suggerimento sul salvataggio di 2 byte (vedi commenti)

Spiegazione:

"dZS" ottiene un vettore in cui ogni voce è il segno delle differenze tra i caratteri successivi, quindi "qq_" diminuisce ogni voce di due e capovolge il segno, quindi ora se il carattere aumenta è 1, se rimane lo stesso 2, e se diminuisce 3. Ad esempio,

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

Successivamente, 't' crea una copia del vettore precedente sulla pila, quindi 'n:' posiziona anche il vettore [1,2,3,4, ...] sulla pila. Quindi '79' posiziona il valore 79 nello stack. Il valore 79 viene scelto perché è il numero per il carattere unicode 'o', che sarà il nostro output in seguito. (Grazie a Luis Mendo per l'idea di inserire qui il valore 79 anziché in seguito)

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

A questo punto abbiamo precisamente gli indici di riga, gli indici di colonna e il valore diverso da zero di una matrice sparsa che ha il valore 79 ovunque desideriamo il carattere di output e 0 dove vogliamo produrre spazi bianchi. Togliamo questi tre elementi dallo stack e creiamo questa matrice sparsa con il comando matrice M "Z?" Di MATL. Questo è,

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]

Non resta che convertire la matrice da numeri in caratteri unicode, cosa che viene fatta dal comando 'c'. I 79 diventano 'o' e gli 0 diventano spazi:

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 risultante di caratteri viene quindi visualizzata implicitamente.


È possibile utilizzare direttamente 79 come valore diverso da zero per la matrice sparsa, risparmiando così due byte. Inoltre, penso che questa sia la prima volta che vengono utilizzate matrici sparse in una risposta MATL :-)
Luis Mendo

@LuisMendo Grazie! Ho modificato il post per apportare la modifica suggerita
Nick Alger,

3

PHP, 95 byte

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

1. Creare una matrice di stringhe con l'indice da 1 a 1 alternativo $b=array_fill(-1,3," ");

2. Riempire le stringhe dipendenti dall'operatore dell'astronave e la posizione dell'ingresso

3.Uscire unire l'array con una nuova riga

Primo modo 111 byte

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

Usa l'operatore dell'astronave <=> dell'astronave


1
Se codifichi il tuo programma in latino-1 , è una scorciatoia utile per "\n". No sul serio!
Lynn,

1
Stessa cosa per " ", che può essere . Esempio.Si desidera impostare la codifica del browser su Latin-1 durante la visualizzazione di questi.
Lynn,

@Lynn o ~ ³ ~ † ~ '~' Grazie per l'idea. Preferirò l'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`
`

Scritto da zero, anche se è stato fortemente ispirato risposta di @ Arnauld . Utilizza la ricorsione per calcolare il contenuto di ogni riga.



2

Java 7, 158 156 byte

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 byte salvati grazie a @Frozn .

Casi non testati e test:

Provalo qui.

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

Produzione:

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

1
Non sono sicuro che funzioni ma a,b,c=b=a=""sarebbe più breve.
Frozn,

@Frozn Grazie, modificato. Funziona davvero. PS: avresti potuto controllarti nell'ideone biforcandolo. ;)
Kevin Cruijssen,

Hai ragione! Sto sempre trascurando i collegamenti e avviando l'eclissi solo per quello non ne vale la pena :)
Frozn,

2

Clora (20 byte)

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

Spiegazione:

Esistono 3 programmi Clora, uno per ogni linea di output.

Primo programma, <IN?o

Controlla se il carattere di input corrente Iè più piccolo <del carattere successivo N. Salva il risultato in una bandiera globale. Controlla il risultato del flag ?e, se è vero, l'outputo genera un altro spazio vuoto (sì, lì c'è uno spazio vuoto.

Tutti gli altri programmi, seguono la stessa regola e sono separati da ; , ogni programma viene eseguito e riceve l'input come argomento.

Puoi testarlo da solo includendo clora.js ed eseguendolo con

(function() {
  var x = new Clora('<IN?o ;=IN?o ;>IN?o ');
  x.execute('EXAMINATION', function(r) {
    console.log(r)
  })
})();

Questo sembra essere rigorosamente non competitivo, poiché è stato creato dopo questa sfida. Sembra però un lang interessante!
Conor O'Brien,

1

Pyth, 21 byte

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

Un programma che accetta l'input di una stringa non quotata su STDIN e stampa il risultato.

Questo utilizza un'idea simile alla risposta CJam di @ MartinEnder .

Provalo online o Verifica tutti i casi di test .

Come funziona

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

1

PHP 7, 81 80 77 byte

Nota: utilizza la codifica Windows-1252

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

Esegui in questo modo:

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

Spiegazione

Esegue un'iterazione sulle linee (numerate 1, 0, -1). Quindi scorre la stringa di input per ogni riga. Quando il risultato del confronto tra astronavi è uguale al numero di riga, emettere uno , altrimenti, genera uno spazio. Dopo ogni riga, stampare una nuova riga.

Ritocchi

  • Smetti di iterare quando lo $xè -1, che possiamo trovare per negazione binaria (risultato 0). Salva un byte rispetto all'aggiunta 1(o 2 con pre-incremento).
  • Salvato 3 byte usando $argn

1
Hai dimenticato di aggiungere -d error_reporting=30709al conteggio dei byte.
Tito,

@Titus Perché nel mondo dovrei aggiungerlo al conteggio dei byte? È solo così che gli avvisi PHP (che sono ignorabili) non vengono stampati!
circa

Potrebbe anche aggiungere 2>/dev/null, ma che sbarazzarsi di tutti gli errori, compresi casi fatali
aross


Qualcosa del genere If you get warnings, set the default value with .... Per favore, scusa il mio pedanteria; Non ho decodificato quel valore.
Tito,

0

Lua 326 303 byte tl = 0 s = io.read () o1, o2, o3 = "", "", "" t = {} per i = 1, # s do t [i] = s: sub (i , i) tl = tl + 1 fine per v = 1, tl-1 se t [v] t [v + 1] allora o1 = o1 .. "" o2 = o2 .. "" o3 = o3 .. " o "end end print (o1 .." \ n ".. o2 .." \ n ".. o3)

Una versione non golfata

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

Penso che tu possa giocare a golf fuori dagli spazi bianchi, diciamo t1 = 0? a t1=0? E posti simili.
Conor O'Brien,

Lo riparerò ora
Alex Allen,

0

R, 114 byte

Una risposta R non competitiva.

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

Spiegazione

  1. Leggi l'input dalla riga di comando e converti in vettore decimale ASCII
  2. Prendi la prima differenza e crea un 3x vettori della stessa lunghezza con spazi bianchi
  3. Quindi sostituire i vettori di spazi bianchi con # se le differenze sono >0, ==0o <0.
  4. Forzare i vettori e stamparli separati da nuove righe

Perché non competere?
Conor O'Brien,

@ ConorO'Brien Immagino sia in competizione con altre risposte R, ma la soluzione originale era troppo lunga e non abbastanza unica da essere interessante in senso generale.
Billywob,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.