Codificação de estrada

21

Nos Estados Unidos , as duas direções opostas de tráfego em uma estrada são separadas por uma linha amarela tracejada se a passagem for permitida e duas linhas amarelas sólidas se a passagem não for permitida.

gráfico de regras de linha rodoviária

(Apenas um lado pode ser tracejado para permitir a passagem desse lado, e as linhas amarelas podem significar outras coisas, como faixas centrais ou reversíveis, mas não estamos preocupados com nenhum desses casos.)

Escreva um programa que utilize uma sequência codificada de comprimento de Pexecução de para passagem e Npara não passagem e imprima uma versão ASCII da estrada correspondente. Exceto pela linha central, a estrada sempre tem o mesmo padrão, que pode ser facilmente deduzido dos exemplos abaixo.

Haverá um número decimal positivo antes de cada um Pe Nna sequência de entrada. Este número define o comprimento da região de passagem ou não da parte atual da estrada.

Exemplos

Uma entrada de 12Nproduziria 12 colunas de nenhuma estrada que passa (linha central todas =):

____________


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

____________

Uma entrada de 12Pproduziria 12 colunas de estrada que passa ( - repetição da linha central ):

____________


- - - - - - 

____________

Passagem e não passagem podem então ser combinadas, por exemplo 4N4P9N7P1N1P2N2P, produziriam:

______________________________


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

______________________________

Estas são 4 colunas sem passagem , depois 4 com passagem , depois 9 sem passagem , etc.

Observe que uma zona de passagem sempre começa com um traço ( -) no lado esquerdo, não um espaço ( ). Isso é necessário.

Detalhes

  • A entrada nunca terá duas Nzonas ou duas Pzonas seguidas. por exemplo 4P5P, nunca ocorrerá.
  • Você não precisa apoiar letras sem um número positivo inicial. A planície Psempre será 1P, a planície Nsempre será 1N.
  • Pode haver espaços à direita, desde que não ultrapassem a coluna final da estrada. Pode haver uma nova linha opcional à direita.
  • Em vez de um programa, você pode escrever uma função que aceita a cadeia codificada no comprimento da execução e imprime ou retorna a estrada ASCII.
  • Recebe entrada de qualquer maneira padrão (stdin, linha de comando, função arg).

O código mais curto em bytes vence. O desempatador é um post anterior.

Passatempos de Calvin
fonte
A estrada precisa ser assimétrica ou é permitida a impressão de 4 espaços da estrada em cada lado da linha?
orlp
@ orlp Se você está perguntando se a estrada pode ter mais de 5 linhas, então não. Se você estiver perguntando se os caracteres de espaço podem ser colocados nas linhas vazias acima ou abaixo da linha central, sim, desde que eles se mantenham com o marcador 3.
Calvin's Hobbies
Deixe-me perguntar, por exemplo, é uma saída válida? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp
@orlp Nem é.
Calvin's Hobbies

Respostas:

5

CJam, 38 bytes

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

Como funciona

Nós primeiro atribuir a coluna estrada correta para variáveis Ne Pem seguida, basta avaliar a cadeia de entrada. Isso deixa um par de comprimento e a coluna na pilha. Nós os agrupamos, executamos um RLD nele para obter as colunas completas, transpor para juntá-las e, finalmente, converter o contínuo --em -.

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

Experimente online aqui

Optimizer
fonte
6

JavaScript (ES6), 114

Usando seqüências de caracteres de modelo , os 5 feeds de linha são significativos e devem ser contados.

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


${s}

`+b
edc65
fonte
5

rs , 252 caracteres

Embora isso possa não contar, porque eu adicionei o operador de convergência como uma imitação da Retina de Martin Büttner há uma hora ... Não estou realmente aqui para competir. É divertido criar uma solução baseada em regex para isso.

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

Recebi a linha 2 da resposta de Martin da Retina para Linguagens de programação ao longo dos anos .

Explicação

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

Isso faz muita mágica. Veja a resposta que eu vinculei acima para obter mais informações.

Basicamente, com a entrada 4N4P9N7P1N1P2N2P, este será o resultado:

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

Próximo:

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

Isso substitui os números que precedem o símbolo de não passagem (N) pelos sinais de igual. O resultado com a entrada anterior:

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

Este:

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

substitui o primeiro número que precede um símbolo de passagem (P) pelo primeiro traço. O resultado:

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

As próximas duas linhas continuam o mesmo padrão:

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

A primeira linha substitui o restante da linha pelo padrão de espaço do traço. O segundo lida com um número ímpar; ele substitui o último traço seguido por um único número inteiro (como -5) por um traço-espaço ( -). Agora, a saída é:

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

Agora as coisas estão começando a se encaixar. A próxima linha:

#\D/

apenas remove o #Ne #P.

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

configure os sublinhados na parte superior e inferior para fornecer:

A______________________________


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

A______________________________

Por fim, removemos o A:

A/
kirbyfan64sos
fonte
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

Exemplo de execução ( fretorna uma string, para melhor visualização, imprima-a):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Como funciona: pretorna a linha do meio analisando recursivamente a sequência de entrada e concatenando o número especificado de símbolos encontrados pela função de pesquisa k. A função principal fune uma lista de cinco elementos com novas linhas, consistindo na linha superior (todos os caracteres da linha do meio substituídos por _), uma nova linha, a linha do meio, uma linha vazia e a linha de fundo (o mesmo que na parte superior).

nimi
fonte
2

Python 3, 169 168 bytes. (167 com 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 ungolfed:

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

Experimente online aqui .

Tim
fonte
Você esqueceu de atualizar sua contagem de bytes.
mbomb007
@ mbomb007 Não alterou a contagem: / Não consigo obtê-lo abaixo de 169 atm
Tim
Colocar p+=['='*v,('- '*v)[:v]][_[-1]=='P']no final da linha anterior com um ponto e vírgula anterior economiza um byte.
mbomb007
Além disso, o uso do Python 2 economiza 1 byte no print.
mbomb007
@ mbomb007 os adicionou :) Tenho um pressentimento de que o python 2 pode ser ainda mais curto ... Mas não tenho certeza.
Tim
2

Python 2, 136 bytes

Surpreendentemente, a importação reparece realmente valer a pena aqui.

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
Uri Granta
fonte
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");

O código pode permanecer em uma única linha; ele é exibido aqui em várias linhas para ser mais legível (os espaços em branco e as novas linhas usadas para formatação não foram contados).

É possível salvar dois bytes não imprimindo a nova linha à direita. Mais cinco bytes podem ser salvos usando caracteres de nova linha reais no echo():

echo("$a


$o

$a");

Seis bytes adicionais podem ser salvos, omitindo a inicialização de $o( $o='';), mas isso acionará um aviso. O aviso pode ser suprimido executando o script usando a linha de comando:

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

Isso leva a 174 bytes.

axiac
fonte
2

Ruby, 137 135 bytes

Não é o mais curto que eu pude imaginar, mas quase o melhor. Emprestado parcialmente da resposta do 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(/--/, '- ')
14mRh4X0r
fonte
Você deve conseguir melhorar isso em 2 bytes (e vencer a resposta do python 2) alterando a última linha para (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
Blotange
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);}

Mais legível:

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

O loop externo conta linhas de 5 a 0.

O loop do meio itera sobre partes da string codificada:

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

O loop interno decodifica uma peça, como 7P,, e itera o número necessário de vezes (por exemplo, 7).

Cada iteração imprime uma char. O valor de charé descrito pelo código l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Se o número da linha for 5 ou 0, imprima 95 ( _)
  • Caso contrário, se o número da linha não for igual a 2, imprima um espaço
  • Caso contrário, se o símbolo for 'N', imprima 61 ( =)
  • Caso contrário, aumente xem 1 (foi inicializado em 2 por sscanf)
  • Se ímpar, imprima 45 ( -), senão imprima 32 (espaço)
anatolyg
fonte
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"}

Primeira tentativa, pode ser jogado um pouco mais.

Jacob
fonte
0

Ruby, 94 bytes

Toma emprestada a gsub'--','- 'ideia da resposta de 14mRh4X0r . Eu acho que essa resposta é mais interessante, embora seja mais curta.

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


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

#{n}"}

Teste:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Produz:

______________________________


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

______________________________
blutorange
fonte
0

deixe-me incluir minha versão do 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

Uma cadeia de caracteres formatada em ASCII com um espaço (já que não há fim da cadeia '\ 0' no matlab

exemplo V = '12N13P'


saída

representação padrão da estrada

_________________________


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

_________________________

função

a função deve ser chamada de sua cauda 1 (o caractere vazio é removido)

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

Simulação

experimente online aqui

Abr001am
fonte
0

R, 132 bytes

Não estou muito satisfeito com isso, mas foi um pouco divertido de fazer :) Tentei me livrar dos múltiplos gsubs, mas meus esforços foram em vão. Eu suspeito que há uma maneira muito melhor de fazer isso.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanpega as cordas de STDIN e pega a quarta. Observe que as linhas vazias requerem um espaço (ou algo) nelas para a digitalização continuar recebendo a entrada.

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

  • Substitui =s por Ns, the -e por Ps.

    "NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP"

  • Em seguida, insere um espaço entre cada NP ePN

    "NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP"

  • A varredura divide a string em espaços

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

  • O comprimento da string é então bound ( rbind) com o primeiro caractere de cada string

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

  • A matriz é então emitida usando cat.

Execução de teste

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