Encodage sur toute la longueur de la route

21

Aux États-Unis , les deux sens de circulation opposés sur une route sont séparés par une ligne jaune en pointillés si le dépassement est autorisé et deux lignes jaunes continues si le dépassement n'est pas autorisé.

graphique des règles de route

(Un seul côté peut être pointillé pour permettre de passer de ce côté, et les lignes jaunes peuvent signifier d'autres choses comme les voies centrales ou réversibles, mais nous ne sommes concernés par aucun de ces cas.)

Écrivez un programme qui accepte une chaîne codée de longueurP pour passer et Npour ne pas passer , et imprime une version ASCII de la route correspondante. À l'exception de la ligne médiane, la route a toujours le même schéma, ce qui peut être facilement déduit des exemples ci-dessous.

Il y aura un nombre décimal positif avant chaque Pet Ndans la chaîne d'entrée. Ce nombre définit la longueur de la zone de passage ou pas de passage de la partie actuelle de la route.

Exemples

Une entrée de 12Nproduirait 12 colonnes de route sans passage (ligne centrale toutes =):

____________


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

____________

Une entrée de 12Pproduirait 12 colonnes de route de passage ( - répétition de la ligne médiane ):

____________


- - - - - - 

____________

La réussite et la non-réussite peuvent alors être combinées, par exemple 4N4P9N7P1N1P2N2Pproduiraient:

______________________________


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

______________________________

Ce sont 4 colonnes sans passage , puis 4 sans passage , puis 9 sans passage , etc.

Notez qu'une zone de passage commence toujours par un tiret ( -) sur le côté le plus à gauche, pas un espace ( ). Ceci est nécessaire.

Détails

  • L'entrée n'aura jamais deux Nzones ou deux Pzones d'affilée. par exemple 4P5P, ne se produira jamais.
  • Vous n'avez pas besoin de prendre en charge les lettres sans un nombre positif en tête. La plaine Psera toujours 1P, la plaine Nsera toujours 1N.
  • Il peut y avoir des espaces de fuite tant qu'ils ne s'étendent pas au-delà de la dernière colonne de la route. Il peut y avoir une nouvelle ligne de fin facultative.
  • Au lieu d'un programme, vous pouvez écrire une fonction qui prend la chaîne encodée de longueur d'exécution et imprime ou renvoie la route ASCII.
  • Prend l'entrée de n'importe quelle manière standard (stdin, ligne de commande, fonction arg).

Le code le plus court en octets gagne. Tiebreaker est un post antérieur.

Loisirs de Calvin
la source
La route doit-elle être asymétrique, ou est-il autorisé d'imprimer 4 espaces de route de chaque côté de la ligne?
orlp
@orlp Si vous demandez si la route peut être plus large que 5 rangées, alors non. Si vous demandez si des caractères d'espace peuvent être placés dans les lignes vides au-dessus ou en dessous de la ligne médiane, alors oui tant qu'ils tiennent avec la puce de détail 3.
Calvin's Hobbies
Permettez-moi de demander par exemple, est-ce que l'un ou l'autre est une sortie valide? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp
@orlp Ni l'un ni l'autre.
Calvin's Hobbies

Réponses:

5

CJam, 38 octets

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

Comment ça marche

Nous avons d' abord attribuons la colonne de route correcte aux variables Net Ppuis évaluer simplement la chaîne d'entrée. Cela laisse une paire de la longueur et de la colonne sur la pile. Nous les regroupons, exécutons un RLD dessus pour obtenir les colonnes complètes, transposons pour les rejoindre, puis convertissons le continu --en -.

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

Essayez-le en ligne ici

Optimiseur
la source
6

JavaScript (ES6), 114

En utilisant des chaînes de modèle , les 5 sauts de ligne sont significatifs et doivent être comptés.

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


${s}

`+b
edc65
la source
5

rs , 252 caractères

Bien que cela puisse ne pas compter parce que j'ai ajouté l'opérateur de convergence comme arnaque à la rétine de Martin Büttner il y a une heure ... Je ne suis pas vraiment là pour concurrencer de toute façon. C'est juste amusant de créer une solution basée sur des expressions rationnelles pour cela.

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

J'ai reçu la ligne 2 de la réponse Retina de Martin pour les langages de programmation à travers les années .

Explication

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

Cela fait beaucoup de magie. Voir la réponse que j'ai liée ci-dessus pour plus d'informations.

Fondamentalement, avec l'entrée 4N4P9N7P1N1P2N2P, ce sera le résultat:

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

Prochain:

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

Cela remplace les chiffres précédant le symbole d'interdiction de passage (N) par les signes égaux. Le résultat avec l'entrée précédente:

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

Cette:

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

remplace le premier chiffre précédant un symbole passant (P) par le premier tiret. Le résultat:

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

Les deux lignes suivantes poursuivent le même schéma:

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

La première ligne remplace le reste de la ligne par le motif d'espace de tiret. Le second gère un nombre impair; il remplace le dernier tiret suivi d'un seul entier (comme -5) par un tiret-espace ( -). Maintenant, la sortie est:

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

Maintenant, les choses commencent à se mettre en place. La ligne suivante:

#\D/

supprime simplement le #Net #P.

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

placez les traits de soulignement en haut et en bas pour donner:

A______________________________


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

A______________________________

Enfin, nous supprimons A:

A/
kirbyfan64sos
la source
2

Haskell, 165 octets

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

Exemple d'exécution ( frenvoie une chaîne, donc pour un meilleur affichage, imprimez-la):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Comment cela fonctionne: prenvoie la ligne médiane en analysant récursivement la chaîne d'entrée et en concaténant le nombre donné de symboles trouvés par la fonction de recherche k. La fonction principale frejoint une liste de cinq éléments avec des sauts de ligne, comprenant la ligne du haut (chaque caractère de la ligne du milieu remplacé par _), un retour à la ligne, la ligne du milieu, une ligne vide et la ligne du bas (comme en haut).

nimi
la source
2

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

Assez non golfé:

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

Essayez-le en ligne ici .

Tim
la source
Vous avez oublié de mettre à jour votre nombre d'octets.
mbomb007
@ mbomb007 Cela n'a pas changé le nombre: / Je ne peux pas le faire en dessous de 169 atm
Tim
Mettre p+=['='*v,('- '*v)[:v]][_[-1]=='P']à la fin de la ligne précédente avec un point-virgule précédent enregistre un octet.
mbomb007
En outre, l'utilisation de Python 2 permet d'économiser 1 octet sur le print.
mbomb007
@ mbomb007 les a ajoutés :) J'ai l'impression que python 2 c'est peut-être encore plus court ... Mais je ne suis pas sûr.
Tim
2

Python 2, 136 octets

Étonnamment, l'importation resemble en fait valoir la peine ici.

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
la source
2

PHP, 187 octets

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

Le code peut rester sur une seule ligne; il est affiché ici sur plusieurs lignes pour être plus lisible (les espaces blancs et les nouvelles lignes utilisés pour le formatage n'ont pas été comptés).

Deux octets peuvent être enregistrés en n'imprimant pas la nouvelle ligne de fin. Cinq octets supplémentaires peuvent être enregistrés en utilisant de vrais caractères de nouvelle ligne sur echo():

echo("$a


$o

$a");

Six octets supplémentaires peuvent être enregistrés en omettant l'initialisation de $o( $o='';) mais cela déclenchera une notification. L'avis peut être supprimé en exécutant le script à l'aide de la ligne de commande:

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

Cela porte à 174 octets.

axiaque
la source
2

Rubis, 137 135 octets

Pas le plus court possible, mais proche du plus beau. En partie emprunté à la réponse d'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'--','- '

Non 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(/--/, '- ')
14mRh4X0r
la source
Vous devriez pouvoir améliorer cela de 2 octets (et battre la réponse python 2) en changeant la dernière ligne en (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
blutorange
1

C, 155 octets

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

Plus lisible:

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

La boucle externe compte les lignes de 5 à 0.

La boucle du milieu itère sur des parties de la chaîne codée:

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

La boucle intérieure décode une partie, comme, 7Pet itère le nombre de fois nécessaire (par exemple 7).

Chaque itération en imprime un char. La valeur de charest décrite par le code l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Si le numéro de ligne est 5 ou 0, imprimez 95 ( _)
  • Sinon, si le numéro de ligne n'est pas égal à 2, imprimez un espace
  • Sinon, si le symbole est 'N', imprimer 61 ( =)
  • Sinon, augmentez xde 1 (il a été initialisé à 2 par sscanf)
  • Si impair, imprimer 45 ( -), sinon imprimer 32 (espace)
anatolyg
la source
0

Scala, 163 octets

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

D'abord, essayez de jouer au golf un peu plus.

Jacob
la source
0

Rubis, 94 octets

Emprunte l' gsub'--','- 'idée de la réponse de 14mRh4X0r . Je pense que cette réponse est plus intéressante, bien qu'elle soit plus courte.

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


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

#{n}"}

Essai:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Produit:

______________________________


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

______________________________
blutorange
la source
0

permettez-moi d'inclure ma version 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

contribution

Une chaîne au format ascii entourée d'un espace (car il n'y a pas de fin de chaîne '\ 0' dans matlab

exemple V = '12N13P'


production

représentation du motif de la route

_________________________


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

_________________________

une fonction

la fonction doit être appelée depuis sa queue-1 (le caractère vide est supprimé)

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

Simulation

essayez-le en ligne ici

Abr001am
la source
0

R, 132 octets

Pas très satisfait de cela, mais c'était un peu amusant à faire :) J'ai essayé de me débarrasser des multiples gsub, mais mes efforts ont été vains. Je soupçonne qu'il existe une bien meilleure façon de procéder.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanobtient les cordes de STDIN et attrape la 4ème. Remarque que les lignes vides nécessitent un espace (ou quelque chose) pour que l'analyse puisse continuer à obtenir l'entrée.

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

  • Il remplace le =s par Ns, le -et par Ps.

    "NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP"

  • Ensuite, il insère un espace entre chacun NPetPN

    "NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP"

  • L'analyse scinde la chaîne sur les espaces

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

  • La longueur de la chaîne est ensuite liée ( rbind) avec le premier caractère de chaque chaîne

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

  • Le tableau est ensuite sorti en utilisant cat.

Essai

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