Довжина кодування


21

У Сполучених Штатах два протилежних напрямки руху на дорозі розділені пунктирною жовтою лінією, якщо проїзд дозволений, і двома суцільними жовтими лініями, якщо проїзд не дозволений.

правила дорожньої лінії графічні

(Лише одна сторона може бути штриховою, щоб дозволити проходження по цій стороні. Жовті лінії можуть означати інші речі, як центральні або оборотні смуги руху, але нас жоден із цих випадків не стосується.)

Напишіть програму, яка містить кодовану рядком довжину прогонуP для проходження і Nдля не проходження , і друкує ASCII версію відповідної дороги. За винятком центральної лінії, дорога завжди має той самий малюнок, який легко можна зробити з наведених нижче прикладів.

Перед кожним Pі Nв рядок введення буде додаткове десяткове число . Це число визначає довжину проїжджаючої ділянки дороги, яка проходить, або без неї.

Приклади

Вхід 12Nбуде створювати 12 стовпців не проїзної дороги (центральна лінія всіх =):

____________


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

____________

Вхід 12Pбуде виробляти 12 колон проходження дороги (центральну лінію - повторювану):

____________


- - - - - - 

____________

Проходження та без проходження потім можуть бути об'єднані, наприклад, це 4N4P9N7P1N1P2N2Pпризведе до:

______________________________


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

______________________________

Це 4 немає прохідних стовпців, потім 4 прохідні , потім 9 не прохідних тощо.

Зверніть увагу, що зона проходження завжди починається з тире ( -) на лівій лівій стороні, а не пробілом ( ). Це потрібно.

Деталі

  • На вході ніколи не буде двох Nзон або двох Pзон підряд. наприклад 4P5P, ніколи не відбудеться.
  • Вам не потрібно підтримувати листи без провідної позитивної цифри. Рівнина Pзавжди буде 1P, рівнина Nзавжди буде 1N.
  • Можуть бути пробіли, поки вони не виходять за межі кінцевої колони дороги. Можливо, є один необов'язковий кінцевий новий рядок.
  • Замість програми ви можете написати функцію, яка приймає кодований рядок довжиною пробігу та друкує або повертає дорогу ASCII.
  • Вводиться будь-яким стандартним способом (stdin, командний рядок, функція arg).

Виграє найкоротший код у байтах. Tierereaker - це раніше повідомлення.


Чи має бути дорога несиметричною, чи дозволено друкувати 4 пробіли дороги з кожного боку лінії?
orlp

@orlp Якщо ви запитуєте, чи може дорога бути ширшою за 5 рядків, тоді ні. Якщо ви запитуєте, чи можуть символи пробілу розміщуватись у порожніх рядках над або під центральною лінією, то так, якщо вони містять детальну кулю 3.
Захоплення Кальвіна

Дозвольте запитати на прикладі, чи один із цих дійсних результатів? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp

Відповіді:


5

CJam, 38 байт

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

Як це працює

Ми спочатку призначити правильний стовпець дороги до змінних Nі , Pа потім просто оцінити рядок введення. Це залишає пару довжини і стовпчик на стеці. Ми групуємо їх, запускаємо RLD на ньому, щоб отримати повні стовпці, переносимо, щоб приєднатись до них, а потім, нарешті, перетворити безперервне --на -.

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

Спробуйте його онлайн тут


6

JavaScript (ES6), 114

Використовуючи рядки шаблону , 5 каналів рядків є значущими, їх треба рахувати.

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 символів

Хоча це може не рахуватись, тому що я додав оператора конвергенції як підрив сітківки Мартіна Бюттнера годину тому ... Я насправді тут не змагаюся. Для цього просто цікаво робити рішення на основі регулярних виразів.

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

Я отримав рядок 2 з відповіді Сітківки Мартіна на мови програмування на роки .

Пояснення

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

Це робить багато магії. Дивіться відповідь, яку я пов’язував вище для отримання додаткової інформації.

В основному, з введенням 4N4P9N7P1N1P2N2P, це буде результат:

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

Далі:

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

Це замінює цифри, що передують непрохідному символу (N), знаками рівності. Результат із попереднім введенням:

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

Це:

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

замінює перше число, що передує символу, що проходить (P), першим тире. Результат:

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

Наступні два рядки продовжують той самий візерунок:

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

Перший рядок замінює решту рядка шаблоном пробілу. Другий обробляє непарне число; він замінює останній тире з подальшим одиничним цілим числом (наприклад, -5) пробілом ( -). Тепер вихід:

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

Зараз все починає ставати на свої місця. Наступний рядок:

#\D/

просто видаляє #Nі #P.

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

встановіть підкреслення вгорі та внизу:

A______________________________


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

A______________________________

Нарешті, ми видаляємо A:

A/

2

Haskell, 165 байт

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

Приклад запуску ( fповертає рядок, щоб для кращого відображення роздрукувати її):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Як це працює: pповертає середню лінію шляхом рекурсивного розбору вхідного рядка та об'єднання заданої кількості символів, знайдених функцією пошуку k. Основна функція fпоєднує список п'яти елементів з новими рядками, що складається з верхнього рядка (кожен _знак середньої лінії замінюється ), нового рядка, середньої лінії, порожнього та нижнього рядка (такий же, як і верхній).


2

Пітон 3, 169 168 байт. (167 з 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)

Досить неозорений:

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

Спробуйте його онлайн тут .


Ви забули оновити кількість байтів.
mbomb007

@ mbomb007 Кількість не змінила: / Я не можу отримати його нижче 169 атм
Тім,

Якщо розмістити p+=['='*v,('- '*v)[:v]][_[-1]=='P']в кінці попереднього рядка попередню крапку з комою, зберігається один байт.
mbomb007

Крім того, використання Python 2 замість цього зберігає 1 байт на print.
mbomb007

@ mbomb007 додав їх :) Я маю відчуття, що python 2 може бути ще коротшим ... Але я не впевнений.
Тім

2

Пітон 2, 136 байт

Дивно, але, reздається , імпорт тут насправді вартий.

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 байт

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

Код може залишатися на одному рядку; він відображається тут у кількох рядках, щоб бути більш читабельним (пробіли та нові рядки, що використовуються для форматування, не враховувалися).

Два байти можна зберегти, не надрукувавши новий рядок. Ще п'ять байтів можна зберегти за допомогою реальних символів нового рядка на echo():

echo("$a


$o

$a");

Шість додаткових байтів можна зберегти, опустивши ініціалізацію $o( $o='';), але це спричинить сповіщення. Повідомлення можна придушити, запустивши скрипт за допомогою командного рядка:

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

Це доводить його до 174 байт.


2

Рубі, 137 135 байт

Не найкоротший, який я міг придумати, але близький до найприємнішого. Частково запозичено з відповіді оптимізатора.

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

Безголівки:

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

Ви повинні мати можливість покращити це на 2 байти (і перемогти відповідь python 2), змінивши останній рядок на (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
blutorange

1

C, 155 байт

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

Більш зрозумілі:

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

Зовнішня петля рахує лінії від 5 до 0.

Середній цикл перебирає частину кодованого рядка:

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

Внутрішня петля декодує частину, як, 7P , і повторює необхідну кількість разів (наприклад, 7).

Кожна ітерація друкує одну char. Значення charописується кодом l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Якщо номер рядка 5 або 0, надрукуйте 95 (_ )
  • В іншому випадку, якщо номер рядка не дорівнює 2, надрукуйте пробіл
  • В іншому випадку, якщо символ "N", надрукуйте 61 (= )
  • В іншому випадку збільшиться xна 1 (його було ініціалізовано до 2 на sscanf)
  • Якщо непарно, надрукуйте 45 ( -), а друк - 32 (пробіл)

0

Scala, 163 байти

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

Спершу спробуйте, можливо, ще трохи пограти в гольф.


0

Рубін, 94 байти

Позичає gsub'--','- 'ідею від відповіді 14mRh4X0r в . Думаю, що відповідь є цікавішою, хоча ця коротша.

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


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

#{n}"}

Тестування:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Виробляє:

______________________________


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

______________________________

0

дозвольте мені включити мій матлаб версію

МАТЛАБ (267 б)

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

вхід

Рядок у форматі ascii, прошитий пробілом (оскільки в matlab немає кінця ланцюга '\ 0'

приклад V = '12N13P'


вихід

схематичне зображення дороги

_________________________


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

_________________________

функція

функцію потрібно викликати з хвоста-1 (порожній символ видалено)

приклад : p (V, numel (V) -1)

Моделювання

спробуйте в Інтернеті тут


0

R, 132 байти

Не надто задоволений цим, але це було трохи весело робити :) Намагався позбутися кількох gsubс, але мої зусилля були марними. Я підозрюю, що існує набагато кращий спосіб зробити це.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanотримує струни від STDIN і захоплює 4-ю. Зауважте, що порожні рядки потребують пробілу (або чогось іншого) для сканування, щоб продовжувати отримувати введення.

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

  • Він замінює =s на Ns, the -і наP s.

    "NNNNPPPPNNNNNNNNPPPPPPPPNPNNPP"

  • Потім він вставляє пробіл між кожним NPіPN

    "NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP"

  • Сканування розділяє рядок на пробіли

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

  • Потім довжина рядка обмежується (rbind ) з першим символом кожного рядка

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

  • Потім масив виводиться за допомогою cat .

Тестовий запуск

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.