Codifica Road-Length


21

Negli Stati Uniti , le due direzioni opposte del traffico su una strada sono separate da una linea gialla tratteggiata se il passaggio è consentito e due linee gialle continue se il passaggio non è consentito.

grafico delle regole della linea stradale

(Solo un lato può essere tratteggiato per consentire il passaggio su quel lato e le linee gialle possono significare altre cose come corsie centrali o reversibili, ma non ci occupiamo di nessuno di questi casi.)

Scrivere un programma che prende in un run-length codificato serie di Pper il passaggio e Nper nessun passaggio , e stampa una versione ASCII della strada corrispondente. Ad eccezione della linea centrale, la strada ha sempre lo stesso modello, che può essere facilmente dedotto dagli esempi seguenti.

Ci sarà un numero decimale positivo prima di ciascuno Pe Nnella stringa di input. Questo numero definisce la lunghezza della regione che passa o che non passa nella parte corrente della strada.

Esempi

Un input di 12Nprodurrebbe 12 colonne senza strada di passaggio (linea centrale tutta =):

____________


============

____________

Un input di 12Pprodurrebbe 12 colonne di passaggio (linea centrale che si - ripete):

____________


- - - - - - 

____________

Il passaggio e il non passaggio possono quindi essere combinati, ad esempio 4N4P9N7P1N1P2N2Pprodurrebbe:

______________________________


====- - =========- - - -=-==- 

______________________________

Queste sono 4 colonne senza passaggio , quindi 4 passaggi , quindi 9 nessun passaggio , ecc.

Si noti che una zona di passaggio inizia sempre con un trattino ( -) sul lato più a sinistra, non uno spazio ( ). Questo è richiesto

Dettagli

  • L'input non avrà mai due Nzone o due Pzone di fila. ad es. 4P5Pnon accadrà mai.
  • Non è necessario supportare le lettere senza un numero positivo iniziale. La pianura Psarà sempre 1P, la pianura Nsarà sempre 1N.
  • Potrebbero esserci spazi finali purché non si estendano oltre l'ultima colonna della strada. Potrebbe esserci una nuova riga finale opzionale.
  • Invece di un programma, è possibile scrivere una funzione che accetta la stringa codificata di lunghezza e stampa o restituisce la strada ASCII.
  • Accetta input in qualsiasi modo standard (stdin, riga di comando, funzione arg).

Vince il codice più breve in byte. Tiebreaker è post precedente.


La strada deve essere asimmetrica o è consentito stampare 4 spazi di strada su ciascun lato della linea?
orlp,

@orlp Se stai chiedendo se la strada può essere più larga di 5 file, allora no. Se stai chiedendo se i caratteri spaziali possono essere inseriti nelle righe vuote sopra o sotto la linea centrale, allora sì purché rimangano con il dettaglio bullet 3.
Calvin's Hobbies

Consentitemi di chiedere, per esempio, uno di questi è un output valido? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp

@orlp Neanche lo è.
Calvin's Hobbies,

Risposte:


5

CJam, 38 byte

"_  - _":N3'=t:P;q~]2/e~z'
*"--"/"- "*

Come funziona

Abbiamo prima assegniamo colonna strada corretta alle variabili Ne Pquindi semplicemente valutare la stringa di input. Questo lascia una coppia della lunghezza e della colonna in pila. Li raggruppiamo, eseguiamo un RLD su di esso per ottenere le colonne complete, trasporre per unirle e infine convertire il continuo --in -.

:_  - _":N                    e# This is the no passing column. We assign it to N
          3'=t:P              e# Replace the '-' in N with '=" and assign it to P
                q~]2/         e# Read the input, evaluate it and then group it in pairs
                     e~       e# Run a run-length-decoder on the pairs
                       z'
*                             e# Transpose and join with new lines.
 "--"/                        e# Split on two continuous occurrence of -
      "- "*                   e# Join by an alternate "- "

Provalo online qui


6

JavaScript (ES6), 114

Utilizzando le stringhe modello , i 5 avanzamenti riga sono significativi e devono essere conteggiati.

f=s=>(b=(s=s.replace(/(\d+)(.)/g,(x,n,b)=>(b<'P'?'=':'- ').repeat(n).slice(0,n))).replace(/./g,'_'))+`


${s}

`+b

5

rs , 252 caratteri

Anche se questo potrebbe non valere perché ho aggiunto l'operatore di convergenza come una fregatura della Retina di Martin Büttner un'ora fa ... Non sono davvero qui per competere comunque. È divertente creare una soluzione basata su regex per questo.

(\d+\D)/#\1
+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)(?=\d*\D)/\1\1\1\1\1\1\1\1\1\1\2\3\4\5\6\7\8\9\10#
\d(?=\d*#N)/=
(^|(?<=\D))\d(?=\d*#P)/-
+(?<=-)\d\d(?=\d*#P)/ -
(?<=-)\d(?=\d*#P)/ 
#\D/
((?:(=|-| ))+)/A\1\n\n\n\1\n\nA\1\n
+(A_*)(.)/\1_
A/

Ho ricevuto la riga 2 dalla risposta Retina di Martin per Linguaggi di programmazione attraverso gli anni .

Spiegazione

(\d+\D)/#\1
+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)(?=\d*\D)/\1\1\1\1\1\1\1\1\1\1\2\3\4\5\6\7\8\9\10#

Questo fa molta magia. Vedi la risposta che ho linkato sopra per maggiori informazioni.

Fondamentalmente, con l'input 4N4P9N7P1N1P2N2P, questo sarà il risultato:

4444#N4444#P999999999#N7777777#P1#N1#P22#N22#P

Il prossimo:

\d(?=\d*#N)/=

Questo sostituisce i numeri che precedono il simbolo del non passaggio (N) con i segni uguali. Il risultato con l'input precedente:

====#N4444#P=========#N7777777#P=#N1#P==#N22#P

Questo:

(^|(?<=\D))\d(?=\d*#P)/-

sostituisce il primo numero che precede un simbolo che passa (P) con il primo trattino. Il risultato:

====#N-444#P=========#N-777777#P=#N-#P==#N-2#P

Le due righe successive continuano lo stesso modello:

+(?<=-)\d\d(?=\d*#P)/ -
(?<=-)\d(?=\d*#P)/ 

La prima riga sostituisce il resto della linea con il motivo tratto-spazio. Il secondo gestisce un numero dispari; sostituisce l'ultimo trattino seguito da un singolo numero intero (come -5) con un trattino-spazio ( -). Ora, l'output è:

====#N- - #P=========#N- - - -#P=#N-#P==#N- #P

Ora le cose stanno iniziando a sistemarsi. La prossima riga:

#\D/

rimuove solo il #Ne #P.

((?:(=|-| ))+)/A\1\n\n\n\1\n\nA\1\n
+(A_*)(.)/\1_

imposta i trattini bassi in alto e in basso per dare:

A______________________________


====- - =========- - - -=-==- 

A______________________________

Infine, rimuoviamo A:

A/

2

Haskell, 165 byte

k 'N'="="
k _="- "
d c=c>'/'&&c<':'
p[]=[]
p s=take(read$takeWhile d s)(cycle$k a)++p r where(a:r)=dropWhile d s
f s=unlines[q,"\n",p s,"",q]where q=map(\x->'_')$p s

Esempio di esecuzione ( frestituisce una stringa, quindi per una migliore visualizzazione stamparla):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


====- - =========- - - -=-==- 

______________________________

Come funziona: prestituisce la linea mediana analizzando ricorsivamente la stringa di input e concatenando il numero dato di simboli trovati dalla funzione di ricerca k. La funzione principale funisce un elenco di cinque elementi con newline, costituito dalla riga superiore (ogni carattere della riga centrale è sostituito da _), una riga nuova, la riga centrale, una riga vuota e la riga inferiore (uguale alla parte superiore).


2

Python 3, 169 168 byte. (167 con Python 2)

p,s='',str.split
for _ in s('N '.join(s('P '.join(s(input(),'P')),'N'))):
 v=int(_[:-1]);p+=['='*v,('- '*v)[:v]][_[-1]=='P']
l=len(p)
u='_'*l
print(u+'\n'*3+p+'\n\n'+u)

Abbastanza non golfato:

p=''
for i in'N '.join('P '.join(input().split('P')).split('N')).split():

  v=int(i[:-1])         # Get the number from the input section

  if i[-1]=='N':        # Check the letter (last char) from the input section
      p+=('='*v)        # Repeat `=` the number from input (v)
  else:
      p+=('- '*v)[:v]   #Repeat `- ` v times, then take first v chars (half)
l=len(p)                #Get the length of the final line markings
print('_'*l+'\n\n\n'+p+'\n\n'+'_'*l)

print('_'*l                          # Print _ repeated the length of p
           +'\n\n\n'                 # 3 new lines
                    +p+              # print out p (the markings)
                       '\n\n'        # 2 new lines
                             +'_'*l) # Print _ repeated the length of p

for i in
        'N '.join(
                  'P '.join(
                            input().split('P'))
                                               .split('N'))
                                                           .split():
                            # Split the input into items of list at P
                  # Join together with P and ' '
                                                # Split at N...
         # Join with N and ' '
                                                           # Split at space
# Loop through produced list

Provalo online qui .


Hai dimenticato di aggiornare il conteggio dei byte.
mbomb007,

@ mbomb007 Non ha cambiato il conteggio: / Non riesco a farlo al di sotto di 169 atm
Tim

Mettere p+=['='*v,('- '*v)[:v]][_[-1]=='P']alla fine della riga precedente con un punto e virgola precedente si salva un byte.
mbomb007,

Inoltre, usando Python 2 si salva invece 1 byte sul print.
mbomb007,

@ mbomb007 li ha aggiunti :) Ho la sensazione che Python 2 potrebbe essere ancora più breve ... Ma non ne sono sicuro.
Tim

2

Python 2, 136 byte

Sorprendentemente, l'importazione resembra essere davvero utile qui.

import re
s=""
for x,y in re.findall("(\d+)(.)",input()):s+=(("- ","==")[y=="N"]*int(x))[:int(x)]
t="_"*len(s);print t+"\n"*3+s+"\n"*2+t

2

PHP, 187 byte

preg_match_all('/(\d+)(\w)/',$argv[1],$m,2);
$o='';
foreach($m as $p)
    $o.=str_replace('--','- ',str_repeat($p[2]<'P'?'=':'-',$p[1]));
$a=preg_replace('/./','_',$o);
echo("$a\n\n\n$o\n\n$a\n");

Il codice può rimanere su una sola riga; viene visualizzato qui su più righe per essere più leggibile (gli spazi bianchi e le nuove righe utilizzate per la formattazione non sono stati conteggiati).

È possibile salvare due byte non stampando la nuova riga finale. Altri cinque byte possono essere salvati utilizzando caratteri di nuova riga reali sul echo():

echo("$a


$o

$a");

Sei byte aggiuntivi possono essere salvati omettendo l'inizializzazione di $o( $o='';) ma ciò attiverà un avviso. L'avviso può essere soppresso eseguendo lo script utilizzando la riga di comando:

$ php -d error_reporting=0 <script_name> 4N4P9N7P1N1P2N2P

Questo lo porta a 174 byte.


2

Rubino, 137 135 byte

Non il più breve che potessi inventare, ma vicino al più bello. In parte preso in prestito dalla risposta di Optimizer.

require'scanf'
N='_  = _'
P='_  - _'
a=[]
scanf('%d%c'){|l,t|a+=[eval(t).chars]*l}
puts (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '

Ungolfed:

require 'scanf'

N = '_  = _'
P = '_  - _'
columns = [] # array of columns
# scan stdin for a number followed by a single char
scanf('%d%c') do |length, type|
  columns += [eval(type).chars] * length
done

# Convert to an array of rows, and join into a string
rows = columns.shift.zip(*columns).map(&:join)
str = rows * "\n" # join lines

# Replace '--' by '- ' and print
puts str.gsub(/--/, '- ')

Dovresti essere in grado di migliorarlo di 2 byte (e battere la risposta di Python 2) cambiando l'ultima riga in (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
blutorange,

1

C, 155 byte

main(l,v,k,n,x,s,c)char*s,**v,c;{for(l=6;l--;puts(s))for(s=v[1];*s;s+=k)for(x=sscanf(s,"%d%c%n",&n,&c,&k);n--;)putchar(l%5?l^2?32:c^78?++x&1?45:32:61:95);}

Più leggibile:

main(l,v,k,n,x,s,c)
    char*s,**v,c;
{
    for(l=6;l--;puts(s))
        for(s=v[1];*s;s+=k)
            for(x=sscanf(s,"%d%c%n",&n,&c,&k);n--;)
                putchar(l%5?l^2?32:c^78?++x&1?45:32:61:95);
}

Il loop esterno conta le righe da 5 a 0.

Il ciclo centrale scorre ripetutamente parti della stringa codificata:

4N4P9N7P1N1P2N2P
4P9N7P1N1P2N2P
9N7P1N1P2N2P
7P1N1P2N2P
1N1P2N2P
1P2N2P
2N2P
2P
string is empty - exit

Il ciclo interno decodifica una parte, come, 7Pe scorre il numero necessario di volte (ad es. 7).

Ogni iterazione ne stampa una char. Il valore di charè descritto dal codice l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Se il numero di riga è 5 o 0, stampa 95 ( _)
  • Altrimenti, se il numero di riga non è uguale a 2, stampare uno spazio
  • Altrimenti, se il simbolo è 'N', stampa 61 ( =)
  • Altrimenti, aumenta xdi 1 (è stato inizializzato a 2 di sscanf)
  • Se dispari, stampa 45 ( -), altrimenti stampa 32 (spazio)

0

Scala, 163 byte

(s:String)=>{val r=(("\\d+(P|N)"r) findAllIn(s) map(r=>{val l=r.init.toInt;if(r.last=='N')"="*l else ("- "*l).take(l)})).mkString;val k="_"*r.length;s"$k\n\n\n$r\n\n$k"}

Primo tentativo, potrebbe essere un po 'più golfato.


0

Rubino, 94 byte

Prendegsub'--','- ' in prestito l' idea dalla risposta di 14mRh4X0r . Penso che questa risposta sia più interessante, sebbene sia più breve.

f=->x{n=?_*x.gsub!(/(\d+)(.)/){($2==?P??-:?=)*$1.to_i}.size
"#{n}


#{x.gsub'--','- '}

#{n}"}

test:

f=->x{n=?_*x.gsub!(/(\d+)(.)/){($2==?P??-:?=)*$1.to_i}.size
"#{n}


#{x.gsub'--','- '}

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

produce:

______________________________


====- - =========- - - -=-==- 

______________________________

0

lasciami includere la mia versione di matlab

MATLAB (267 b)

function d=p(V,a),j=numel(V)-1;if (a==0),d=0;return; end,d=(V(a)-48+10*p(V,a-1))*(V(a)<64);fprintf('%c%.*s%c%.*s',(a>=j)*10,(a==j|a==1)*eval(strcat(regexprep(V,'[NP]','+'),48)),ones(99)*'_',(a<3)*10,(V(a+1)>64)*d,repmat((V(a+1)==78)*'=='+(V(a+1)==80)*'- ',[1 99]));end

ingresso

Una stringa in formato ASCII seguita da uno spazio (poiché non esiste una fine della catena '\ 0' in matlab

esempio V = '12N13P'


produzione

rappresentazione del modello della strada

_________________________


============- - - - - - -

_________________________

funzione

la funzione deve essere chiamata dalla sua coda-1 (il carattere vuoto viene rimosso)

esempio : p (V, numel (V) -1)

Simulazione

provalo online qui


0

R, 132 byte

Non molto contento di questo, ma è stato un po 'divertente da fare :) Ho provato a sbarazzarmi delle molteplici gsubs, ma i miei sforzi sono stati vani. Sospetto che ci sia un modo molto migliore per farlo.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanprende le corde da STDIN e afferra la quarta. Nota che le righe vuote richiedono uno spazio (o qualcosa) in esse affinché la scansione possa continuare a ricevere l'input.

    "==== - - ========= - - - - = - == -"

  • Sostituisce il = s con Ns, la -e con Ps.

    "NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP"

  • Quindi inserisce uno spazio tra ciascuno NPePN

    "NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP"

  • La scansione divide la stringa in spazi

    "NNNN" "PPPP" "NNNNNNNNN" "PPPPPPP" "N" "P" "NN" "PP"

  • La lunghezza della stringa viene quindi associata (rbind ) al primo carattere di ciascuna stringa

    4 4 9 7 1 1 2 2
    "N" "P" "N" "P" "N" "P" "N" "P"

  • L'array viene quindi emesso utilizzando cat.

Prova

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
1: ____________
2:  
3:  
4: ============
5:  
6: ____________
7: 
Read 6 items
Read 1 item
12N
> 
> cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
1: ____________
2:  
3:  
4: - - - - - - 
5:  
6: ____________
7: 
Read 6 items
Read 1 item
12P
> cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
1: ______________________________
2:  
3:  
4: ====- - =========- - - -=-==- 
5:  
6: ______________________________
7: 
Read 6 items
Read 8 items
4N4P9N7P1N1P2N2P
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.