Kodowanie długości drogi

21

W Stanach Zjednoczonych dwa przeciwne kierunki ruchu na drodze są oddzielone przerywaną żółtą linią, jeśli dozwolone jest przejazd, oraz dwie stałe żółte linie, jeśli przejazd jest niedozwolony.

grafika zasad linii drogi

(Tylko jedna strona może być przerywana, aby umożliwić przejście po tej stronie, a żółte linie mogą oznaczać inne rzeczy, takie jak środkowe lub odwracalne pasy, ale nie zajmujemy się tymi przypadkami.)

Napisz program, który odbywa się w run-length zakodowany ciąg Pna przejściu i Nna żadnym biegiem , a drukuje wersji ASCII odpowiedniej drogi. Z wyjątkiem linii środkowej droga ma zawsze ten sam wzór, co można łatwo wywnioskować z poniższych przykładów.

Przed każdym Piw Nciągu wejściowym będzie dodatnia liczba dziesiętna . Liczba ta określa długość przejeżdżającego lub nie przejeżdżającego regionu bieżącej części drogi.

Przykłady

Dane wejściowe 12Nwygenerowałyby 12 kolumn bez przejeżdżającej drogi (linia środkowa wszystkie =):

____________


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

____________

Dane wejściowe 12Pwygenerowałyby 12 kolumn przejeżdżającej drogi ( - powtarzająca się linia środkowa ):

____________


- - - - - - 

____________

Podanie i brak podania nie mogą być następnie połączone, np. 4N4P9N7P1N1P2N2PSpowoduje

______________________________


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

______________________________

Są to 4 kolumny bez przejścia , następnie 4 przejścia , a następnie 9 brak przejścia itp.

Zauważ, że mijająca strefa zawsze zaczyna się od myślnika ( -) po lewej stronie, a nie spacji ( ). To jest wymagane.

Detale

  • Wejście nigdy nie będzie miało dwóch Nlub dwóch Pstref z rzędu. np. 4P5Pnigdy nie nastąpi.
  • Nie musisz obsługiwać liter bez wiodącej liczby dodatniej. Zwykły Pzawsze będzie 1P, zwykły Nzawsze będzie 1N.
  • Mogą występować spacje końcowe, o ile nie rozciągają się one poza ostatnią kolumnę drogi. Może być jeden opcjonalny znak nowej linii.
  • Zamiast programu możesz napisać funkcję, która pobiera zakodowany ciąg znaków i wypisuje lub zwraca drogę ASCII.
  • Pobiera dane wejściowe w dowolny standardowy sposób (standardowe, wiersz poleceń, funkcja arg).

Najkrótszy kod w bajtach wygrywa. Tiebreaker jest wcześniejszym postem.

Hobby Calvina
źródło
Czy droga musi być asymetryczna, czy może drukować 4 przestrzenie drogi po każdej stronie linii?
orlp
@orlp Jeśli pytasz, czy droga może być szersza niż 5 rzędów, to nie. Jeśli pytasz, czy znaki spacji można umieścić w pustych liniach powyżej lub poniżej linii środkowej, to tak, o ile zawierają szczegółową kulę 3.
Hobby Calvina
Pozwól, że zapytam przez przykład, czy któryś z tych parametrów jest prawidłowy? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp
@orlp Ani nie jest.
Calvin's Hobbies

Odpowiedzi:

5

CJam, 38 bajtów

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

Jak to działa

My najpierw przypisać właściwą kolumnę droga do zmiennych Ni P, a następnie po prostu ocenić ciąg wejściowy. Pozostawia to parę długości i kolumnę na stosie. Grupujemy je, uruchamiamy na nim RLD, aby uzyskać pełne kolumny, transponujemy, aby do nich dołączyć, a następnie przekształcamy ciągłość --na -.

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

Wypróbuj online tutaj

Optymalizator
źródło
6

JavaScript (ES6), 114

Używając ciągów szablonów , należy zliczyć 5 wysuwów linii, które są znaczące.

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


${s}

`+b
edc65
źródło
5

rs , 252 znaki

Chociaż może się to nie liczyć, ponieważ godzinę temu dodałem operatora konwergencji jako zdzierstwo Retiny Martina Büttnera ... Tak naprawdę nie jestem tu, by konkurować. Po prostu fajnie jest tworzyć rozwiązanie oparte na wyrażeniach regularnych.

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

Mam drugą linię od odpowiedzi Martina na siatkówkę dla Programowania języków przez lata .

Wyjaśnienie

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

To robi dużo magii. Aby uzyskać więcej informacji, zobacz odpowiedź, którą zamieściłem powyżej.

Zasadniczo z danymi wejściowymi 4N4P9N7P1N1P2N2Pbędzie to wynik:

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

Kolejny:

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

Zastępuje to liczby poprzedzające nieprzejściowy symbol (N) znakami równości. Wynik z poprzedniego wejścia:

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

To:

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

zastępuje pierwszą liczbę poprzedzającą mijający symbol (P) pierwszym myślnikiem. Wynik:

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

Następne dwie linie kontynuują ten sam wzór:

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

Pierwsza linia zastępuje resztę linii wzorcem odstępu. Drugi obsługuje liczbę nieparzystą; zastępuje ostatni myślnik, po którym następuje pojedyncza liczba całkowita (taka jak -5) znakiem myślnika ( -). Teraz dane wyjściowe to:

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

Teraz sprawy zaczynają się układać. Następna linia:

#\D/

po prostu usuwa #Ni #P.

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

ustaw podkreślenia na górze i na dole, aby uzyskać:

A______________________________


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

A______________________________

Na koniec usuwamy A:

A/
kirbyfan64sos
źródło
2

Haskell, 165 bajtów

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

Przykładowy przebieg ( fzwraca ciąg, więc dla lepszego wyświetlania wydrukuj go):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Jak to działa: pzwraca środkową linię poprzez rekursywną analizę łańcucha wejściowego i konkatenację podanej liczby symboli znalezionych przez funkcję wyszukiwania k. Główna funkcja fłączy pięcioelementową listę z nowymi liniami, składającymi się z górnej linii (każdy znak środkowej linii zastąpiony przez _), nowej linii, środkowej linii, pustej linii i dolnej linii (tak samo jak górna).

nimi
źródło
2

Python 3, 169 168 bajtów. (167 z 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)

Dość nie golfista:

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

Wypróbuj online tutaj .

Tim
źródło
Zapomniałeś zaktualizować swoją liczbę bajtów.
mbomb007
@ mbomb007 To nie zmieniło liczby: / Nie mogę uzyskać poniżej 169 atm
Tim
Umieszczenie p+=['='*v,('- '*v)[:v]][_[-1]=='P']na końcu poprzedniego wiersza poprzedzającego średnika oszczędza jeden bajt.
mbomb007
Ponadto użycie Python 2 zamiast tego oszczędza 1 bajt w pliku print.
mbomb007
@ mbomb007 dodał je :) Mam wrażenie, że python 2 może być jeszcze krótszy ... Ale nie jestem pewien.
Tim
2

Python 2, 136 bajtów

Co zaskakujące, importowanie rewydaje się tutaj naprawdę opłacalne.

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
źródło
2

PHP, 187 bajtów

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

Kod może pozostać w jednej linii; jest on wyświetlany tutaj w wielu wierszach, aby był bardziej czytelny (białe znaki i znaki nowej linii użyte do formatowania nie zostały policzone).

Dwa bajty można zapisać, nie drukując końcowego znaku nowej linii. Pięć kolejnych bajtów można zapisać, używając prawdziwych znaków nowej linii w echo():

echo("$a


$o

$a");

Sześć dodatkowych bajtów można zapisać, pomijając inicjalizację $o( $o='';), ale spowoduje to wyświetlenie powiadomienia. Powiadomienie można ukryć, uruchamiając skrypt za pomocą wiersza polecenia:

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

To prowadzi do 174 bajtów.

aksjomat
źródło
2

Rubin, 137 135 bajtów

Nie najkrótszy, jaki mogłem wymyślić, ale blisko najładniejszego. Częściowo zapożyczone z odpowiedzi Optymalizatora.

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

Nie golfowany:

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
źródło
Powinieneś być w stanie poprawić to o 2 bajty (i pokonać odpowiedź python 2), zmieniając ostatnią linię na (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
blutorange
1

C, 155 bajtów

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

Bardziej czytelny:

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

Zewnętrzna pętla liczy linie od 5 do 0.

Pętla środkowa iteruje części zakodowanego ciągu:

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

Wewnętrzna pętla dekoduje część, na przykład, 7Pi iteruje potrzebną liczbę razy (np. 7).

Każda iteracja drukuje jedną char. Wartość charjest opisana przez kod l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Jeśli numer linii to 5 lub 0, wydrukuj 95 ( _)
  • W przeciwnym razie, jeśli numer linii nie jest równy 2, wydrukuj spację
  • W przeciwnym razie, jeśli symbolem jest „N”, wydrukuj 61 ( =)
  • W przeciwnym razie zwiększ xo 1 (zainicjowano do 2 o sscanf)
  • Jeśli nieparzysty, wydrukuj 45 ( -), w przeciwnym razie wydrukuj 32 (spacja)
anatolig
źródło
0

Scala, 163 bajty

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

Pierwsza próba, może być jeszcze trochę golfa.

Jakub
źródło
0

Ruby, 94 bajty

Pożycza gsub'--','- 'pomysł z odpowiedzi 14mRh4X0r . Myślę, że ta odpowiedź jest bardziej interesująca, chociaż jest krótsza.

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


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

#{n}"}

Testowanie:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Produkuje:

______________________________


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

______________________________
blutorange
źródło
0

pozwól mi dołączyć moją wersję Matlaba

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

wkład

Łańcuch sformatowany w ascii z odstępem (ponieważ w matlabie nie ma końca łańcucha „\ 0”

przykład V = „12N13P”


wydajność

reprezentacja wzoru drogi

_________________________


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

_________________________

funkcjonować

funkcja musi zostać wywołana z ogona-1 (pusty znak jest usuwany)

przykład : p (V, numel (V) -1)

Symulacja

spróbuj tutaj online

Abr001am
źródło
0

R, 132 bajty

Nie bardzo się z tego cieszyłem, ale było trochę fajnie :) Próbowałem pozbyć się wielu gsubs, ale moje wysiłki poszły na marne. Podejrzewam, że jest na to znacznie lepszy sposób.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanpobiera łańcuchy ze STDIN i chwyta 4-ty. Uwaga że puste linie wymagają spacji (lub czegoś) w nich, aby skan mógł nadal pobierać dane wejściowe.

    „==== - - ========= - - - - = - == -”

  • Zastępuje =s Ns, the -i withP s.

    „NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP”

  • Następnie wstawia spację między każdym NPaPN

    „NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP”

  • Skan dzieli ciąg znaków na spacje

    „NNNN” „PPPP” „NNNNNNNNN” „PPPPPPP” „N” „P” „NN” „PP”

  • Długość łańcucha jest następnie związana ( rbind) z pierwszym znakiem każdego łańcucha

    4 4 9 7 1 1 2 2
    „N” „P” „N” „P” „N” „P” „N” „P”

  • Tablica jest następnie wyprowadzana za pomocą cat.

Testowe uruchomienie

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
źródło