Straßenlängencodierung


21

In den Vereinigten Staaten sind die beiden entgegengesetzten Verkehrsrichtungen auf einer Straße durch eine gestrichelte gelbe Linie getrennt, wenn die Weitergabe zulässig ist, und durch zwei durchgezogene gelbe Linien, wenn die Weitergabe nicht zulässig ist.

Straßenlinie ordnet Grafik an

(Nur eine Seite kann gestrichelt sein, um das Überholen dieser Seite zu ermöglichen, und gelbe Linien können andere Dinge wie Mittelspuren oder umkehrbare Fahrspuren bedeuten, aber wir sind mit keinem dieser Fälle befasst.)

Schreiben Sie ein Programm, das eine lauflängencodierte Zeichenfolge Pzum Übergeben und Nzum Nichtübergeben verwendet und eine ASCII-Version der entsprechenden Straße ausgibt. Abgesehen von der Mittellinie weist die Straße immer das gleiche Muster auf, was aus den folgenden Beispielen leicht abgeleitet werden kann.

Vor Pund Nin der Eingabezeichenfolge steht eine positive Dezimalzahl . Diese Zahl definiert die Länge des vorbeifahrenden oder nicht vorbeifahrenden Bereichs des aktuellen Straßenteils.

Beispiele

Eine Eingabe von 12Nwürde 12 Spalten ohne vorbeifahrende Straße erzeugen (Mittellinie alle =):

____________


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

____________

Eine Eingabe von 12Pwürde 12 Spalten einer vorbeifahrenden Straße erzeugen ( - Wiederholung der Mittellinie ):

____________


- - - - - - 

____________

Bestehen und Nichtbestehen können dann kombiniert werden, zB 4N4P9N7P1N1P2N2Pwürde ergeben:

______________________________


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

______________________________

Dies sind 4 nicht passierende Spalten, dann 4 passierende , dann 9 nicht passierende usw.

Beachten Sie, dass eine vorbeifahrende Zone immer mit einem Bindestrich ( -) ganz links und nicht mit einem Leerzeichen ( ) beginnt . Dies ist erforderlich.

Einzelheiten

  • Der Eingang wird niemals zwei NZonen oder zwei PZonen hintereinander haben. zB 4P5Pwird niemals auftreten.
  • Sie müssen keine Buchstaben ohne führende positive Zahl unterstützen. Einfach Pwird es immer sein 1P, einfach Nwird es immer sein 1N.
  • Es kann nachgestellte Leerzeichen geben, solange diese nicht über die letzte Straßensäule hinausragen. Es kann eine optionale nachgestellte Newline geben.
  • Anstelle eines Programms können Sie eine Funktion schreiben, die die lauflängencodierte Zeichenfolge einliest und die ASCII-Straße ausgibt oder zurückgibt.
  • Übernimmt die Eingabe auf jede Standardart (stdin, Kommandozeile, Funktion arg).

Der kürzeste Code in Bytes gewinnt. Tiebreaker ist früherer Beitrag.


Muss die Straße asymmetrisch sein oder dürfen auf jeder Seite der Linie 4 Straßenabschnitte gedruckt werden?
Orlp

@orlp Wenn Sie fragen, ob die Straße breiter als 5 Zeilen sein kann, dann nein. Wenn Sie fragen, ob Leerzeichen in die Leerzeilen oberhalb oder unterhalb der Mittellinie eingefügt werden können, dann ja, solange sie mit dem Aufzählungszeichen 3 versehen sind.
Calvins Hobbys

Lassen Sie mich anhand eines Beispiels fragen, ob eine dieser beiden Ausgaben gültig ist. gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp

@orlp Weder ist.
Calvins Hobbys

Antworten:


5

CJam, 38 Bytes

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

Wie es funktioniert

Wir weisen Variablen zuerst die richtige Straßenspalte zu Nund Pwerten dann einfach die Eingabezeichenfolge aus. Dies lässt ein Paar der Länge und der Säule auf dem Stapel. Wir gruppieren sie, führen eine RLD darauf aus, um die vollständigen Spalten zu erhalten, transponieren, um sie zu verbinden, und konvertieren schließlich die kontinuierliche --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 "- "

Probieren Sie es hier online aus


6

JavaScript (ES6), 114

Bei Verwendung von Template-Strings müssen die 5 Zeilenvorschübe gezählt werden, die von Bedeutung sind.

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 Zeichen

Obwohl dies möglicherweise nicht zählt, weil ich den Konvergenzoperator vor einer Stunde als Abzocke von Martin Büttners Retina hinzugefügt habe ... Ich bin sowieso nicht wirklich hier, um zu konkurrieren. Es macht einfach Spaß, eine auf Regex basierende Lösung dafür zu entwickeln.

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

Ich habe Zeile 2 von Martins Retina-Antwort für Programmiersprachen im Laufe der Jahre erhalten .

Erläuterung

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

Das macht viel Magie. Weitere Informationen finden Sie in der Antwort, die ich oben verlinkt habe.

Grundsätzlich ist dies mit der Eingabe 4N4P9N7P1N1P2N2Pdas Ergebnis:

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

Nächster:

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

Dies ersetzt die Zahlen vor dem Symbol (N) durch die Gleichheitszeichen. Das Ergebnis mit der vorherigen Eingabe:

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

Dies:

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

Ersetzt die erste Zahl vor einem vorbeiziehenden Symbol (P) durch den ersten Strich. Das Ergebnis:

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

Die nächsten beiden Zeilen folgen demselben Muster:

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

Die erste Zeile ersetzt den Rest der Zeile durch das Bindestrichmuster. Der zweite behandelt eine ungerade Zahl; Es ersetzt den letzten Bindestrich, gefolgt von einer einzelnen Ganzzahl (wie z. B. -5), durch ein Bindestrich-Leerzeichen ( -). Die Ausgabe lautet nun:

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

Jetzt fangen die Dinge an, sich zu fügen. Die nächste Zeile:

#\D/

entfernt einfach das #Nund #P.

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

Richten Sie die Unterstriche oben und unten ein, um Folgendes zu erhalten:

A______________________________


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

A______________________________

Zuletzt entfernen wir die 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

Beispiellauf ( fgibt einen String zurück, um ihn besser anzuzeigen, drucken Sie ihn aus):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Funktionsweise: pGibt die mittlere Zeile zurück, indem die Eingabezeichenfolge rekursiv analysiert und die angegebene Anzahl von Symbolen verkettet wird, die von der Suchfunktion gefunden wurden k. Die Hauptfunktion fverbindet eine Liste mit fünf Elementen mit Zeilenumbrüchen, bestehend aus der obersten Zeile (jedes Zeichen der mittleren Zeile wird durch ersetzt _), einer neuen Zeile, der mittleren Zeile, einer leeren Zeile und der untersten Zeile (wie oben).


2

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

Ziemlich 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

Probieren Sie es hier online aus .


Sie haben vergessen, Ihre Byteanzahl zu aktualisieren.
mbomb007

@ mbomb007 Es hat die Zählung nicht geändert: / Ich kann es nicht unter 169 atm bringen
Tim

Wenn Sie p+=['='*v,('- '*v)[:v]][_[-1]=='P']am Ende der vorherigen Zeile ein vorangestelltes Semikolon einfügen, wird ein Byte gespeichert.
mbomb007

Wenn Sie stattdessen Python 2 verwenden, sparen Sie 1 Byte auf der print.
mbomb007

@ mbomb007 fügte sie hinzu :) Ich habe das Gefühl, Python 2 könnte noch kürzer sein ... Aber ich bin nicht sicher.
Tim

2

Python 2, 136 Bytes

Überraschenderweise rescheint sich der Import hier tatsächlich zu lohnen.

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

Der Code kann in einer einzelnen Zeile stehen bleiben. Es wird hier in mehreren Zeilen angezeigt, um die Lesbarkeit zu verbessern (die für die Formatierung verwendeten Leerzeichen und Zeilenumbrüche wurden nicht gezählt).

Sie können zwei Bytes speichern, indem Sie die nachstehende Zeile nicht drucken. Fünf weitere Bytes können gespeichert werden, indem echte Zeilenumbrüche in den echo()folgenden Bereichen verwendet werden :

echo("$a


$o

$a");

Sechs zusätzliche Bytes können durch Weglassen der Initialisierung von $o( $o='';) gespeichert werden , dies löst jedoch eine Benachrichtigung aus. Der Hinweis kann unterdrückt werden, indem das Skript über die Befehlszeile ausgeführt wird:

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

Das bringt es auf 174 Bytes.


2

Ruby, 137 135 Bytes

Nicht die kürzeste, die ich mir vorstellen konnte, aber die netteste. Teilweise aus der Antwort des Optimierers entlehnt.

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

Sie sollten in der Lage sein, dies um 2 Bytes zu verbessern (und die Antwort auf Python 2 zu unterbieten), indem Sie die letzte Zeile in ändern (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);}

Besser lesbar:

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

Die äußere Schleife zählt Zeilen von 5 bis 0.

Die mittlere Schleife durchläuft Teile der codierten Zeichenfolge:

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

Die innere Schleife decodiert einen Teil wie 7Pund iteriert die erforderliche Anzahl von Malen (z. B. 7).

Jede Iteration gibt eine aus char. Der Wert von charwird durch den Code beschrieben l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Wenn die Zeilennummer 5 oder 0 ist, drucken Sie 95 ( _)
  • Andernfalls drucken Sie ein Leerzeichen, wenn die Zeilennummer ungleich 2 ist
  • Andernfalls, wenn das Symbol 'N' ist, drucken Sie 61 ( =)
  • Andernfalls erhöhen Sie xum 1 (es wurde um auf 2 initialisiert sscanf).
  • Wenn ungerade, drucke 45 ( -), sonst drucke 32 (Leerzeichen)

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

Erster Versuch, könnte noch etwas mehr golfen werden.


0

Ruby, 94 Bytes

Leiht die gsub'--','- 'Idee aus der Antwort von 14mRh4X0r . Ich finde diese Antwort jedoch interessanter, obwohl sie kürzer ist.

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


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

#{n}"}

Testen:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Produziert:

______________________________


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

______________________________

0

Lassen Sie mich meine Matlab- Version aufnehmen

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

Eingang

Eine ascii-formatierte Zeichenfolge, die durch ein Leerzeichen begrenzt ist (da in matlab kein Kettenende '\ 0' vorhanden ist

Beispiel V = '12N13P'


Ausgabe

Musterdarstellung der Straße

_________________________


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

_________________________

Funktion

Die Funktion muss von ihrem Ende 1 aufgerufen werden (das leere Zeichen wird entfernt)

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

Simulation

Probieren Sie es hier online aus


0

R, 132 Bytes

Ich bin damit nicht sehr zufrieden, aber es hat ein bisschen Spaß gemacht :) gsubIch habe versucht, die Mehrfachnennungen loszuwerden , aber meine Bemühungen waren vergebens. Ich vermute, es gibt einen viel besseren Weg, dies zu tun.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanholt die Saiten von STDIN und schnappt sich die vierte. Hinweis dass die leeren Zeilen ein Leerzeichen (oder etwas) enthalten müssen, damit der Scan die Eingabe fortsetzen kann.

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

  • Es ersetzt das =s mit Ns, das -und mit Ps.

    NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP

  • Dann wird zwischen NPund jeweils ein Leerzeichen eingefügtPN

    NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP

  • Der Scan teilt die Zeichenfolge in Leerzeichen auf

    NNNN PPPP NNNNNNNNN PPPPPPP N P NN PP

  • Die Stringlänge wird dann gebunden (rbind mit dem ersten Zeichen jedes Strings )

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

  • Das Array wird dann mit ausgegeben cat.

Testlauf

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.