Codificación de longitud de camino


21

En los Estados Unidos , las dos direcciones opuestas del tráfico en una carretera están separadas por una línea amarilla discontinua si se permite el paso y dos líneas amarillas continuas si no se permite el paso.

gráfico de reglas de línea de carretera

(Solo un lado puede ser punteado para permitir pasar por ese lado, y las líneas amarillas pueden significar otras cosas como el centro o los carriles reversibles, pero no nos preocupa ninguno de esos casos).

Escriba un programa que tome una cadena codificada de longitud de ejecución de Ppara pasar y Npara que no pase , e imprime una versión ASCII de la carretera correspondiente. Excepto por la línea central, la carretera siempre tiene el mismo patrón, que puede deducirse fácilmente de los ejemplos a continuación.

Habrá un número decimal positivo antes de cada uno Py Nen la cadena de entrada. Este número define la longitud de la región de paso o no paso de la parte actual de la carretera.

Ejemplos

Una entrada de 12Nproduciría 12 columnas de camino sin paso (línea central todas =):

____________


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

____________

Una entrada de 12Pproduciría 12 columnas de camino de paso (línea central que se - repite):

____________


- - - - - - 

____________

Pasar y no pasar se puede combinar, por ejemplo 4N4P9N7P1N1P2N2P, produciría:

______________________________


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

______________________________

Estas son 4 columnas que no pasan , luego 4 que pasan , luego 9 que no pasan , etc.

Tenga en cuenta que una zona de paso siempre comienza con un guión ( -) en el lado izquierdo, no un espacio ( ). Esto es requerido.

Detalles

  • La entrada nunca tendrá dos Nzonas o dos Pzonas en una fila. por ejemplo 4P5P, nunca ocurrirá.
  • No necesita admitir letras sin un número positivo principal. La llanura Psiempre será 1P, la llanura Nsiempre será 1N.
  • Puede haber espacios finales siempre que no se extiendan más allá de la columna final del camino. Puede haber una nueva línea final opcional.
  • En lugar de un programa, puede escribir una función que tome la cadena codificada de longitud de ejecución e imprima o devuelva el camino ASCII.
  • Toma información de cualquier manera estándar (stdin, línea de comando, función arg).

El código más corto en bytes gana. Tiebreaker es una publicación anterior.


¿El camino tiene que ser asimétrico, o está permitido imprimir 4 espacios de camino a cada lado de la línea?
orlp

@orlp Si está preguntando si el camino puede ser más ancho que 5 filas, entonces no. Si estás preguntando si los caracteres de espacio se pueden poner en las líneas vacías encima o por debajo de la línea central, entonces sí, siempre y cuando sostienen con detalle, punto 3.
Calvin Aficiones

Permítanme preguntar por ejemplo, ¿alguno de estos es un resultado válido? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp

@orlp Tampoco lo es.
Hobbies de Calvin

Respuestas:


5

CJam, 38 bytes

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

Cómo funciona

En primer lugar, asignamos la columna camino correcto para las variables Ny Py luego simplemente evaluamos la cadena de entrada. Esto deja un par de la longitud y la columna en la pila. Los agrupamos, ejecutamos un RLD para obtener las columnas completas, transponemos para unirlos y, finalmente, convertimos el continuo --a -.

:_  - _":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 "- "

Pruébalo en línea aquí


6

JavaScript (ES6), 114

Usando cadenas de plantilla , los 5 avances de línea son significativos y deben contarse.

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 caracteres

Aunque esto podría no contar porque agregué el operador de convergencia como una estafa de la Retina de Martin Büttner hace una hora ... No estoy realmente aquí para competir de todos modos. Es divertido hacer una solución basada en expresiones regulares para esto.

(\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/

Obtuve la línea 2 de la respuesta de Martin Retina para Lenguajes de programación a través de los años .

Explicación

(\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#

Esto hace mucha magia. Vea la respuesta que vinculé arriba para más información.

Básicamente, con la entrada 4N4P9N7P1N1P2N2P, este será el resultado:

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

Próximo:

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

Esto reemplaza los números que preceden al símbolo de no pasar (N) con los signos de igual. El resultado con la entrada anterior:

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

Esta:

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

reemplaza el primer número que precede a un símbolo que pasa (P) con el primer guión. El resultado:

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

Las siguientes dos líneas continúan el mismo patrón:

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

La primera línea reemplaza el resto de la línea con el patrón de espacio en el tablero. El segundo maneja un número impar; reemplaza el último guión seguido de un único entero (como -5) con un guión-espacio ( -). Ahora, la salida es:

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

Ahora las cosas comienzan a encajar. La proxima linea:

#\D/

solo elimina el #Ny #P.

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

configurar los guiones bajos en la parte superior e inferior para dar:

A______________________________


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

A______________________________

Por último, eliminamos A:

A/

2

Haskell, 165 bytes

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

Ejemplo de ejecución ( fdevuelve una cadena, así que para una mejor visualización imprímala):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Cómo funciona: pdevuelve la línea media analizando recursivamente la cadena de entrada y concatenando el número dado de símbolos encontrados por la función de búsqueda k. La función principal se fune a una lista de cinco elementos con nuevas líneas, que consiste en la línea superior (cada carácter de la línea media reemplazada por _), una nueva línea, la línea media, una línea vacía y la línea inferior (igual que la parte superior).


2

Python 3, 169 168 bytes. (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)

Bastante indolente:

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

Pruébelo en línea aquí .


Olvidó actualizar su recuento de bytes.
mbomb007

@ mbomb007 No cambió el recuento: / No puedo obtenerlo por debajo de 169 atm
Tim

Poner p+=['='*v,('- '*v)[:v]][_[-1]=='P']al final de la línea anterior con un punto y coma anterior ahorra un byte.
mbomb007

Además, el uso de Python 2 ahorra 1 byte en print.
mbomb007

@ mbomb007 los agregó :) Tengo el presentimiento de que Python 2 puede ser aún más corto ... Pero no estoy seguro.
Tim

2

Python 2, 136 bytes

Sorprendentemente, importar reparece ser realmente útil aquí.

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 bytes

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

El código puede permanecer en una sola línea; se muestra aquí en varias líneas para que sea más legible (no se contaron los espacios en blanco y las nuevas líneas utilizadas para formatear).

Se pueden guardar dos bytes al no imprimir la nueva línea final. Se pueden guardar cinco bytes más utilizando caracteres de nueva línea reales en echo():

echo("$a


$o

$a");

Se pueden guardar seis bytes adicionales omitiendo la inicialización de $o( $o='';) pero esto activará un aviso. El aviso se puede suprimir ejecutando el script usando la línea de comando:

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

Esto lo lleva a 174 bytes.


2

Ruby, 137 135 bytes

No es el más corto que se me ocurrió, pero está cerca del más bonito. En parte prestado de la respuesta de 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'--','- '

Sin golf:

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(/--/, '- ')

Debería poder mejorar esto en 2 bytes (y superar la respuesta de python 2) cambiando la última línea a (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
blutorange

1

C, 155 bytes

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

Más legible:

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

El bucle externo cuenta líneas del 5 al 0.

El bucle intermedio itera sobre partes de la cadena codificada:

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

El bucle interno decodifica una parte, como, 7Pe itera el número necesario de veces (por ejemplo, 7).

Cada iteración imprime uno char. El valor de la charse describe en el código l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Si el número de línea es 5 o 0, imprima 95 ( _)
  • De lo contrario, si el número de línea no es igual a 2, imprima un espacio
  • De lo contrario, si el símbolo es 'N', imprima 61 ( =)
  • De lo contrario, aumente xen 1 (se inicializó a 2 por sscanf)
  • Si es impar, imprima 45 ( -), de lo contrario imprima 32 (espacio)

0

Scala, 163 bytes

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

Primer intento, podría jugar un poco más de golf.


0

Ruby, 94 bytes

Toma prestada la gsub'--','- 'idea de la respuesta de 14mRh4X0r . Sin embargo, creo que esa respuesta es más interesante, aunque es más corta.

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


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

#{n}"}

Pruebas:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Produce:

______________________________


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

______________________________

0

déjame incluir mi versión 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

entrada

Una cadena con formato ascii seguida por un espacio (ya que no hay un final de cadena '\ 0' en matlab

ejemplo V = '12N13P'


salida

patrón de representación de la carretera

_________________________


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

_________________________

función

la función debe llamarse desde su cola-1 (se elimina el carácter vacío)

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

Simulación

Pruébelo en línea aquí


0

R, 132 bytes

No estoy muy contento con esto, pero fue un poco divertido de hacer :) Intenté deshacerme de los múltiples gsubmensajes, pero mis esfuerzos fueron en vano. Sospecho que hay una manera mucho mejor de hacer esto.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanobtiene las cuerdas de STDIN y toma la cuarta. Nota que las líneas vacías requieren un espacio (o algo) en ellas para que el escaneo continúe recibiendo la entrada.

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

  • Reemplaza la =s con Ns, la -y con Ps.

    "NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP"

  • Luego inserta un espacio entre cada NPyPN

    "NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP"

  • El escaneo divide la cadena en espacios

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

  • La longitud de la cadena se enlaza ( rbind) con el primer carácter de cada cadena

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

  • La matriz se emite usando cat.

Prueba de funcionamiento

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.