Converti esponenti in arte ASCII


28

Compito

Il tuo compito è convertire le stringhe in questo modo:

abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

A stringhe come questa:

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

Che è un'approssimazione di abc d + ef g + hijk l - M N O P (Ag + )

In parole, solleva i personaggi direttamente accanto ai punti di inserimento nella riga superiore, un carattere per un punto di inserimento.

Specifiche

  • Sono consentiti spazi bianchi finali aggiuntivi nell'output.
  • Nessun input incatenato m^n^overrà fornito come input.
  • Un cursore non sarà immediatamente seguito da uno spazio o da un altro cursore.
  • Un punto di inserimento non sarà preceduto immediatamente da uno spazio.
  • Tutti i punti di inserimento saranno preceduti da almeno un carattere e seguiti da almeno un carattere.
  • La stringa di input conterrà solo caratteri ASCII stampabili (U + 0020 - U + 007E)
  • Invece di due righe di output, è possibile generare una matrice di due stringhe.

A coloro che parlano regex: la stringa di input corrisponderà a questa regex:

/^(?!.*(\^.\^|\^\^|\^ | \^))(?!\^)[ -~]*(?<!\^)$/

Classifica


2
@TimmyD "La stringa di input conterrà solo caratteri ASCII stampabili (U + 0020 - U + 007E)"
Leaky Nun,

3
Perché fermarsi agli esponenti? Voglio qualcosa che gestisca H_2O!
Neil,

1
@Neil Allora fai la tua sfida e potrei chiudere questa sfida come duplicata di quella. :)
Leaky Nun,

1
Sulla base del tuo esempio direi che sono superindici , non necessariamente esponenti
Luis Mendo,

4
Coloro che parlano regex provengono da un paese altamente regolare in cui l'espressione è strettamente limitata. La principale causa di morte è il catastrofico backtracking.
David Conrad,

Risposte:


19

V , 15 14 byte

ÄÒ +òf^xxé kPj

Provalo online!

Una soluzione abbastanza semplice. La sfida perfetta per V!

Spiegazione:

Ä                "Duplicate this current line
 Ò               "Replace this line with spaces
   +             "Move to the beginning of the next line
    ò         ò  "Recursively (The second ò is implicit):
     f^          "  Find a caret
       xx        "  Delete two characters. The second will be saved into the main register
         é       "  Insert a space
           k     "  Move up
            P    "  Paste from the main register
             j   "  Move down

Convenientemente, in base a come funziona la ricorsione, questo verrà eseguito una volta per ogni singolo cursore.


2
vim è il linguaggio perfetto per questa sfida. +1
Downgoat,

18

Cheddar, 77 72 67 byte

l->l.chars.vfuse.replace("^\n"," ").lines.map(j->"%-2s"%j).turn(3)

Nessun regex!

Adoro questa risposta in quanto è una meravigliosa dimostrazione delle abilità di Cheddar. Principalmente grazie alla funzione di sostituzione aggiunta da Conor. Il PR da sviluppare non è mai stato creato, quindi la funzione di sostituzione esiste solo su questo ramo (aggiornamento: ho creato il PR e ora è sull'ultimo ramo beta che puoi installare con npm install -g cheddar-lang)

Ho trovato un modo per giocare a golf, ma sfortunatamente una svista si verifica in questo caso quando la lunghezza degli oggetti non è la stessa:

["   denifednud   denifednug       denifednul    denifednuN denifednuP    denifednu+ ", "abcdenifednu +efdenifednu  + hijkdenifednu  - Mdenifednu Odenifednu  (Agdenifednu )"]

Avrei potuto salvare molti byte usando regex, e in effetti ho appena creato regex per Cheddar ... l'unico problema è che non ci sono funzioni regex: /

Spiegazione

l->                    // Function take input as `l`
   l.chars             // Get array of chars in input
   .vfuse              // Join with newlines
   .replace("^\n"," ") // Replace `^\n` with a space globally
   .lines              // Get the lines (see below for more details on what this returns)
   .map(j->            // Loop through each "line" `j` is arg
       "%-2s"          // C-like printf format.
                       // think of as: padRight(j, " ", 2)
                       // see below for more details
        % j            // Pass j as the string to insert
   ).turn(3)           // Turn the string 270 degrees (see below)
   .vfuse              // Vertically fuse to get result (this is not needed as we can output an array of the lines)

Per capire meglio. Questo è ciò che .linesritorna1^2

["1", " 2"]

il .turncon ruotare questo:

1
 2

in:

 2
1

Un altro esempio che renderà più chiaro:

1
 2
2
 2

diventa:

 2 2
1 2

Perché formattare?

Quello che %-2ssta facendo è piuttosto semplice. %specifica che stiamo iniziando un "formato" o che una variabile verrà inserita in questa stringa a questo punto. -significa padare a destra la stringa ed 2è la lunghezza massima. Di default si riempie di spazi. sspecifica solo che è una stringa. Per vedere cosa fa:

"%-2s" % "a"  == "a "
"%-2s" % " a" == " a"

2
: DI sempre vota cheddar.
DJMcMayhem

@DrGreenEggsandIronMan: D grazie
Downgoat,

1
Cheddar ha un turnmetodo per le stringhe?
TuxCrafting

6
-1 il nome di questa lingua mi fa sempre venire fame.
cessò di girare in senso antiorario il

@ TùxCräftîñg solo per array 2D, ecco perché ho usato .lines per ottenere le linee.
Downgoat,

10

Perl, 21 + 1 = 22 byte

say'';s/\^(.)/♥[A\1↓/

Corri con la -pbandiera. Sostituisci con un ESCbyte non elaborato ( 0x1b) e con una scheda verticale ( 0x0b).

La scheda verticale è un'idea di Martin Ender. Ha salvato due byte! Grazie.


Non avresti bisogno di spostare il cursore in basso di una riga all'inizio in modo che gli esponenti non si sovrappongano all'ultimo prompt della console?
Martin Ender,

Non ne ero sicuro, sì. Ho ipotizzato di avere tutto lo spazio di cui ho bisogno, ma forse è un po 'economico. (In generale, non sono molto orgoglioso di usare i movimenti del cursore per risolvere questo tipo di problema, ma è la prima cosa che mi è venuta in mente ...)
Lynn,

2
Penso che sia una buona soluzione, ma il risultato dovrebbe essere visivamente indistinguibile dalla stampa della stringa come previsto.
Martin Ender,

1
Che bella soluzione
Thomas Weller,

7

JavaScript (ES6), 56 55 byte

s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))

Ritorna in soccorso ovviamente. Il primo sostituisce tutti i personaggi con spazi, a meno che non trovi un cursore, nel qual caso cancella il cursore e mantiene il personaggio dopo di esso. (Questi personaggi sono garantiti per esistere.) Il secondo è quello ovvio in cui sostituire ogni cursore e il suo personaggio successivo con uno spazio.

Modifica: salvato 1 byte grazie a @Lynn che ha ideato un modo per riutilizzare la stringa di sostituzione per la seconda sostituzione consentendo di mappare la sostituzione su una matrice di regexps.


2
Sembra s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))un byte più corto.
Lynn,

@Lynn Questa è un'acrobazia davvero astuta!
Neil,

7

Python 3, 157 101 98 85 83 74 byte

Questa soluzione tiene traccia del carattere precedente ^, quindi decide se eseguire l'output sulla prima o sulla seconda riga in base a quello.

Output come una matrice di ['firstline', 'secondline'].

a=['']*2
l=0
for c in input():x=c=='^';a[l]+=c*x;a[~l]+=' '*x;l=x
print(a)

Risparmiato 13 15 byte grazie a @LeakyNun!

Salvato 7 byte grazie a @Joffan!


1
Bel automa a stati finiti.
Leaky Nun,

Sarebbe meglio avere a=['','']e concatenare ' 'e cdirettamente in a[l]e a[~l]?
Joffan,

6

Python 2, 73 byte

l=['']*2;p=1
for c in input():b=c!='^';l[p]+=c*b;l[~p]+=' '*b;p=b
print l

Nessuna regex. Ricorda se il personaggio precedente era ^e inserisci il carattere corrente nella riga superiore o inferiore in base a quello e uno spazio nell'altro.


4

Pyth, 17 byte

CcsmX~Z1j;d;cQ\^2

             Q      input string
            c \^    split on '^'
   m                map for sections d:
    X      ;          insert a space at index:
     ~Z1                the old value of Z (initially 0), before setting Z to 1
                      into:
        j;d             the section joined on spaces
  s                 concatenate
 c              2   chop into groups of 2
C                   transpose

Restituisce un array di 2 stringhe. (Preparati ja unirti a loro con una nuova riga.)

Provalo online .


1
Non riesco a smettere di chiedermi come si pronuncia il tuo cognome. : D
Lynn,

4

MATL , 18 byte

94=t1YSt~&vG*cw~Z)

Provalo online!

94=    % Take input implicitly. Create logical array of the same size that contains
       % true for carets, false otherwise
t      % Push a copy of this array
1YS    % Circularly shift 1 unit to the right. This gives an array that contains true
       % for the elements right after a caret (superindices), and false for the rest 
t~     % Push a copy and negate
&v     % Concatenate vertically. This gives a 2D, 2-row array
G*     % Push the input again, multiply with broadcast. This gives a 2D array in
       % which the first row contains the superindices (characters after a caret)
       % and 0 for the rest; and the second row contains the non-superindices and
       % 0 for the superindices
c      % Convert to char
w      % Swap. Brings to top the array containing true for carets and false otherwise
~      % Negate
Z)     % Use as logical index to remove rows that contain carets. Display implicitly

4

Rubino, 47 + 1 ( -nbandiera) = 48 byte

puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")

Eseguilo così: ruby -ne 'puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")'


Penso che puoi salvare 1 byte usando $_=$_.gsub(/\^(.)|./){$1||" "}+gsub(/\^./," ")e -pinvece di -n.
Dom Hastings,

1
@DomHastings indipendentemente dal fatto che funzioni o meno, il tuo codice non sembra avere una nuova riga e l'aggiunta +$/significa che non salverà byte. putsgenera automaticamente la nuova riga quando ,è presente tra gli argomenti.
Value Ink

Oh ... ho provato usando ruby -p ... <<< 'input'ma sono d'accordo, se manca la newline non va bene! In realtà, avrei potuto aggiungere una nuova riga ai miei test prima ... Era al lavoro, quindi non posso controllare!
Dom Hastings,

@DomHastings Guardandolo di nuovo, la mia ipotesi è che è perché getsinclude la nuova riga finale per la maggior parte del tempo, ma se installi un file che non contiene la nuova riga finale, allora non verrà visualizzato e l'output sarà errato . Prova il tuo codice con ruby -p ... inputfilepoiché Ruby reindirizza getsal file se si tratta di un argomento della riga di comando.
Value Ink,

Capito, ha perfettamente senso. Immagino che anche una nuova riga finale nel file risolva il problema. Non sono un esperto rubyista, quindi mi sento come se avessi imparato qualcosa in più oggi. Grazie!
Dom Hastings,

3

Python (2), 76 68 67 byte

-5 byte grazie a @LeakyNun

-3 byte grazie a @ KevinLau-notKenny

-1 Byte grazie a @ValueInk

-0 byte grazie a @DrGreenEggsandIronMan

import re
lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]

Questa funzione Lambda anonima prende la stringa di input come unico argomento e restituisce le due linee di output separate da una nuova riga. Per chiamarlo, dagli un nome scrivendo "f =" prima di esso.

Regex piuttosto semplice: la prima parte sostituisce quanto segue con uno spazio: qualsiasi personaggio e un cursore di carota o solo un carattere, ma solo se prima non c'è un cursore. La seconda parte sostituisce qualsiasi punto di inserimento nella stringa e il carattere dopo di essa con uno spazio.


@LeakyNun: per qualche motivo mi chiedevo se 1. vale anche se importare librerie. Stavo copiando 2. in questa domanda proprio ora che ho visto il tuo commento. Grazie a te e Kevin!
KarlKastor,

Potresti toglierti un byte confrom re import*
DJMcMayhem

@DrGreenEggsandIronMan Questo sembra usare esattamente lo stesso numero di byte. (vedi sopra)
KarlKastor,

Conservare la vecchia istruzione di importazione e procedere lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]per -1 byte
Valore inchiostro


2

Retina, 16 byte

S`^
\^(.)
♥[A$1↓

Una porta della mia risposta Perl, sottolineata da Martin Ender. Sostituisci con un ESCbyte non elaborato ( 0x1b) e con una scheda verticale ( 0x0b).


2

shell + TeX + catdvi, 51 43 byte

tex '\empty$'$1'$\end'>n;catdvi *i|head -n2

Usa texper comporre alcune meravigliose matematiche, quindi usa catdviper creare una rappresentazione testuale. Il comando head rimuove la posta indesiderata (numerazione delle pagine, nuove righe finali) che è altrimenti presente.

Modifica: Perché il lungo, corretto, cosa e reindirizzare a /dev/nullquando è possibile ignorare gli effetti collaterali e scrivere in un file a lettera singola?


Esempio

Ingresso: abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

Uscita TeX (ritagliata all'equazione): Matematica "bella"! Uscita finale:

   d   g     l  N P   +
abc +ef +hijk -M O (Ag )

Presupposti: iniziare con una directory vuota (o specificamente una directory senza nome che termina con "i"). L'input è un singolo argomento per lo script della shell. L'input non è una stringa vuota.

Qualcuno mi dice se si tratta di abuso di regole, in particolare catdvi.


2

Haskell, 74 56 55 byte

g('^':c:r)=(c,' '):g r
g(c:r)=(' ',c):g r
g x=x
unzip.g

Restituisce una coppia di stringhe. Esempio di utilizzo: unzip.g $ "abc^d+e:qf^g + hijk^l - M^NO^P: (Ag^+)"->(" d g l N P + ","abc +e:qf + hijk - M O : (Ag )")

gcrea un elenco di coppie, in cui il primo elemento è il carattere nella riga superiore e il secondo elemento è il carattere nella riga inferiore. unziplo trasforma in una coppia di liste.

Modifica: suggerito @xnor unzipche consente di risparmiare 18 byte. @Laikoni ha trovato un altro byte da salvare. Grazie!


Si può fare j=unzip.g?
xnor

@xnor: oh, che stupido da parte mia non vederlo da solo! Molte grazie!
nimi,

È possibile sostituire g[]=[]con g x=xper salvare un byte.
Laikoni,

@Laikoni: ben individuato! Grazie!
nimi,

1

Perl, 35 byte

34 byte codice + 1 per -p

$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr

uso

perl -pe '$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

Nota: questa è esattamente la stessa della risposta di Value Ink che ho spiato in seguito. Se necessario, verrà rimosso in quanto ciò non si aggiunge alla soluzione Ruby.


1

Java 8 lambda, 132 128 112 caratteri

i->{String[]r={"",""};for(char j=0,c;j<i.length();j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}

La versione non giocata è simile alla seguente:

public class Q86647 {

    static String[] printExponents(char[] input) {
        String[] result = {"",""};
        for (char j = 0, c; j < input.length(); j++) {
            c = input[j];
            result[0] += c == 94 ? input[++j] : 32;
            result[1] += c == 94 ? 32 : c;
        }
        return result;
    }
}

Emette come un array, controllando semplicemente se c'è un cursore e in tal caso il carattere successivo verrà inserito nella riga superiore, altrimenti ci sarà uno spazio.


aggiornamenti

Sostituiti i caratteri con i loro valori ASCII per salvare 4 caratteri.

Grazie a @LeakyLun per aver sottolineato di utilizzare invece un array di caratteri come input.

Anche grazie a @KevinCruijssen per aver cambiato il intin charper salvare altri personaggi.


Puoi provare a inserire char[]e usare for(char c:i)per vedere se il conteggio dei byte può essere ridotto.
Leaky Nun,

Puoi giocare un po 'fino a 110 byte usando: i->{String[]r={"",""};for(char j=0,c;j<i.length;j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}con "abc^d+ef^g + hijk^l - M^NO^P (Ag^+)".toCharArray()come input. ( Ideone di questi cambiamenti. )
Kevin Cruijssen,

1

Noce di cocco , 122 114 96 byte

Modifica: 8 26 byte in giù con l'aiuto di Leaky Nun.

def e(s,l)=''==l and s or"^"==l[0]and l[1]+e(s+' ',l[2:])or' '+e(s+l[0],l[1:])
f=print..e$('\n')

Quindi, come ho appreso oggi, Python ha un operatore condizionale ternario, o in effetti due di essi: <true_expr> if <condition> else <false_expr>e <condition> and <true_expr> or <false_expr>con l'ultimo arrivato con un carattere in meno.
Una versione conforme a Python può essere ideonizzata .


Primo tentativo:

def e(s,l):
 case l:
  match['^',c]+r:return c+e(s+' ',r)
  match[c]+r:return' '+e(s+c,r)
 else:return s
f=print..e$('\n')

Chiamata con f("abc^d+ef^g + hijk^l - M^NO^P (Ag^+)")stampe

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

Qualcuno ha ancora provato a giocare a golf nel cocco? Arricchisce Python con concetti di programmazione più funzionali come il pattern matching e la concatenazione di funzioni (con ..) usate sopra. Dato che questo è il mio primo tentativo di cocco, qualsiasi consiglio sarebbe apprezzato.

Questo potrebbe sicuramente essere abbreviato in quanto qualsiasi codice python valido è anche valido e sono state pubblicate risposte python più brevi, tuttavia ho cercato di trovare una soluzione puramente funzionale.


Penso che puoi usare gli operatori ternari ( x and y or z) per sostituire il case.
Leaky Nun,

Puoi anche usare s[0]=="^"invece dimatch['^',c]+r in l
Leaky Nun,

@LeakyNun Quando lo sostituisco match['^',c]+rcon s[0]=="^", quindi ce rnon sono più associati. Come sarebbe d'aiuto?
Laikoni,

È possibile utilizzare s[1]per sostituire ce s[2:]sostituire r.
Leaky Nun,

allora puoi usare ternary ora.
Leaky Nun,

0

Dyalog APL, 34 byte

{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}

Restituisce un vettore a due elementi con le due linee

Esecuzione del campione (il rettangolo davanti è per formattare il vettore a due el per il consumo umano):

      ↑{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}'abc∧d+ef∧g + hijk∧l - M∧NO∧P (Ag∧+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

Al tuo commento sulla mia domanda sul codice che non fa nulla: sì, quel codice che metti conta.
Hayakam,

0

PowerShell v2 +, 88 83 byte

-join([char[]]$args[0]|%{if($c){$_;$b+=' '}elseif($_-94){$b+=$_;' '}$c=$_-eq94});$b

Un po 'più lungo degli altri, ma mostra un po' di magia di PowerShell e una logica leggermente diversa.

Sostanzialmente lo stesso concetto di Python risponde: ripetiamo l'inserimento carattere per carattere, ricordiamo se il precedente era un punto di inserimento ( $c) e posizioniamo il carattere corrente nel punto appropriato. Tuttavia, la logica e il metodo per determinare dove produrre l'output sono gestiti in modo leggermente diverso, e senza una tupla o variabili separate - testiamo se il carattere precedente era un cursore, e in tal caso output il personaggio alla pipeline e concateniamo uno spazio su $b. Altrimenti controlliamo se il personaggio attuale è un punto di inserimento elseif($_-94)e fino a quando non lo è, concateniamo il personaggio corrente $be generiamo uno spazio sulla pipeline. Infine, stabiliamo se il personaggio attuale è un cursore per il prossimo round.

Raccogliamo quei personaggi della pipeline insieme in parentesi, li incapsuliamo in uno -joinche li trasforma in una stringa e li lasciamo insieme $balla pipeline. L'output alla fine è implicito con una nuova riga tra.

Per fare un confronto, ecco una porta diretta della risposta Python di @ xnor , a 85 byte :

$a=,''*2;[char[]]$args[($l=0)]|%{$a[!$l]+="$_"*($c=$_-ne94);$a[$l]+=' '*$c;$l=!$c};$a

0

Gema, 42 41 caratteri

\^?=?@set{s;$s }
?=\ @append{s;?}
\Z=\n$s

Gema elabora l'input come stream, quindi è necessario risolverlo in un passaggio: la prima riga viene scritta immediatamente come elaborata, la seconda riga viene raccolta in $ s variabili, quindi alla fine viene emessa.

Esecuzione di esempio:

bash-4.3$ gema '\^?=?@set{s;$s };?=\ @append{s;?};\Z=\n$s' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    +  
abc +ef  + hijk  - M O  (Ag )

0

Gomma alla cannella, 21 byte

0000000: 5306 6533 bd92 d1db 8899 8381 a2f8 8f8c  S.e3............
0000010: 1230 249e a1                             .0$..

Fuori concorso. Provalo online.

Spiegazione

Non sono un golfista regex quindi probabilmente c'è un modo migliore per farlo.

La stringa si decomprime in:

S(?<!\^)[^^]& &\^&`S\^.& 

(notare lo spazio finale)

Il primo Sstadio riceve input e usa un lookbehind negativo per sostituire tutti i personaggi diversi dai punti di inserimento senza punto precedente con uno spazio, quindi elimina tutti i punti di inserimento. Quindi emette immediatamente la stringa di input modificata con una nuova riga e rimuove quella Sfase. Poiché STDIN è ora esaurito e la fase precedente non ha fornito alcun input, la Sfase successiva riceve di nuovo l'ultima riga di STDIN e quindi sostituisce tutti i punti di inserimento seguiti da qualsiasi personaggio con uno spazio e lo emette.

Nel codice pslico Perl:

$first_stage_sub_1 = ($input =~ s/(?<!\^)[^^]/ /gr);
$first_stage_sub_2 = ($first_stage_sub_1 =~ s/\^//gr);
print $first_stage_sub_2, "\n";

$second_stage_sub = ($input =~ s/\^./ /gr);
print $second_stage_sub, "\n";

0

J , 28 27 byte

0|:t#]{."0~_1-_1|.t=.'^'~:]

Provalo online!

                  t=.'^'~:]    0 for ^, 1 for the rest, define t
              _1|.             Shift right, now zeroes are for superscripts         
     ]{."0~_1-                 Prepend that many spaces to each character
   t#                          Remove the rows with carets
0|:                            Transpose

Deve esserci un modo migliore ...

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.