Нумерація ієрархічних контурів


18

Напишіть програму, яка містить рядок, де кожен рядок складається з символу, 0відведеного деякою кількістю пробілів. Верхня лінія не є відступною, і будь-який інший рядок буде з відступом як мінімум на один пробіл більше, ніж рядок перед ним.

У жодних рядках не буде пробілів, але, можливо, ви можете припустити, що існує один простий новий рядок.

Наприклад, вхід може виглядати приблизно так:

0
 0
  0
  0
 0
0
 0
 0
 0
  0
0
 0
  0
  0

Ваше завдання - нумерувати його як ієрархічний контур , використовуючи збільшення позитивних цілих чисел як заголовків рядків. Це буде висновок для прикладу:

1
 1
  1
  2
 2
2
 1
 2
 3
  1
3
 1
  1
  2

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

У висновку не повинно бути пробілів, але за бажанням може бути один зворотний новий рядок.

Напишіть повну програму, яка приймає рядок введення через stdin або командний рядок, або напишіть функцію, яка приймає рядок як аргумент. Роздрукуйте результат або поверніть його як рядок.

Виграє найкоротший код у байтах.

Приклади

Якщо введений порожній рядок, слід вивести порожній рядок.

Наступний найбільш тривіальний приклад - введення

0

що має стати

1

Великий приклад - Введення даних:

0
 0
  0
 0
  0
 0
  0
  0
   0
   0
    0
     0
     0
     0
     0
    0
   0
    0
    0
  0
0
 0
  0
 0
  0
  0
  0
  0
  0
  0
  0
  0
  0
  0
  0
   0
    0
     0
  0
   0
0
0
0
 0
  0
   0
    0
     0
      0
      0
     0
    0
   0
  0
 0
  0
  0
   0
   0
0
0

Вихід:

1
 1
  1
 2
  1
 3
  1
  2
   1
   2
    1
     1
     2
     3
     4
    2
   3
    1
    2
  3
2
 1
  1
 2
  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
  11
   1
    1
     1
  12
   1
3
4
5
 1
  1
   1
    1
     1
      1
      2
     2
    2
   2
  2
 2
  1
  2
   1
   2
6
7

Відповіді:


2

Піт, 18 байт

V.z+PNhX0=Y>lN+0Y1

Це точний переклад відповіді @ Sp3000 . Я спробував багато різних підходів і варіацій, але не зміг його скоротити, тому я відзначаю цей CW.

Демонстрація.


8

Пітон 2, 77

S={'0':0}
for w in input().split('\n'):S[w]+=1;S[' '+w]=0;print w[:-1]+`S[w]`

Як відповідь Sp3000 , але зі словником. Дік Sзберігає поточне число для кожного рівня гніздування '0', ' 0', ' 0'тощо. Для кожного рядка на вході збільшуйте відповідний рівень вкладення та скиньте рівень гніздування на один вище до 0.


6

Python 2, 86 85 81 байт

S=[]
for r in input().split("\n"):S=([0]+S)[-len(r):];S[0]+=1;print r[:-1]+`S[0]`

(-5 байт завдяки @xnor)

Приймає введення як рядок через STDIN, наприклад

'0\n 0\n  0\n  0\n 0\n0\n 0\n 0\n 0\n  0\n0\n 0\n  0\n  0'

Крім того, ось функція для 5 додаткових байтів:

def f(I,S=[]):
 for r in I.split("\n"):S=([0]+S)[-len(r):];S[0]+=1;print r[:-1]+`S[0]`

Я виявив, що ви можете зберегти деякі символи, взявши кожен рядок як рядок пробілів, щоб ви могли надрукувати ці пробіли безпосередньоS=[]\nfor w in input()[:-1].split('0\n'):S=([0]+S)[~len(w):];S[0]+=1;print w+`S[0]`
xnor

На насправді, це трохи коротше , щоб взяти в рядку безпосередньо: S=[]\nfor w in input().split('\n'):S=([0]+S)[-len(w):];S[0]+=1;print w[:-1]+`S[0]` .
xnor

@xnor Ще раз спасибі - це набагато простіше :)
Sp3000

4

CJam, 25 байт

LqN/{0+I,<))_IW@toNo+}fI;

Як і в моїй відповіді Python , і цей використовується масив для зберігання, чиє число дорівнює кожному рівню відступу. Однак одна з різниць полягає в тому, що це використовуєтьсяt (набір масивів) для заміни 0 у кожному рядку на потрібне нам число.

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


3

JavaScript ES6, 83 81 байт

f=(z,a=[])=>z.replace(/ *0/g,e=>e.replace(0,a.fill(0,l=e.length)[--l]=a[l]+1||1))

Для цього використовується масив, який містить поточне число для кожного рівня відступу. Все, що минуло цей рівень, скидається до 0, використовуючи fill(). EDIT: 2 байти збережено завдяки підказці vihan1086.

Нижній фрагмент стека нижче може бути використаний для тестування, оскільки він злегка знятий і використовує краще підтримуваний синтаксис ES5. Друга функція - це поліфіл, fill()оскільки не існує короткого способу обійтися без ES6.

f=function(z){
  a=[]
  return z.replace(/ *0/g,function(e){
    return e.replace(0,a.fill(0,l=e.length)[--l]=a[l]+1||1)
  })
}

if(!Array.prototype.fill){
  Array.prototype.fill = function(val, start){
    var res = this;
    for(var i = start; i<this.length; i++){
      res[i] = val;
    }
    return res;
  };
}

run=function(){document.getElementById('output').innerText=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<textarea id="input" rows="15" cols="10">
0
 0
  0
  0
 0
0
 0
 0
 0
  0
0
 0
  0
  0</textarea>
<pre id="output" style="display:inline-block; vertical-align:top; margin:0"></pre><br />
<button id="run">Run</button>


1

Пітон - 191 рік

def p(s,i,v,n=1):
    while i<len(s)and s[i]and'0'not in s[i][:v]:
        if s[i][v]=='0':s[i]=' '*v+str(n);n+=1;i+=1
        else:i=p(s,i,v+1)
    return(s,i)[v!=0]
z=lambda r:'\n'.join(p(r.split('\n'),0,0))

Функція є z.


0

Піп -rn , 31 27 байт

{Wl#<alPU0l@>:-#aaR0++@l}Mg

Введення від stdin. Спробуйте в Інтернеті!

Пояснення

                             g is list of lines of stdin (-r flag); l is []
                             Note that l is a global variable
{                       }Mg  Map this function to each a in g:
 Wl#<a                        While l is less in length than a:
      lPU0                     Push a 0 to (the front of) l
                              (This handles increasing the indent)
          l@>:                Slice and assign back to l...
              -#a              ... its last len(a) elements
                              (This handles decreasing the indent)
                 aR0          In a, replace 0 with
                      @l       the first element of l
                    ++         incremented in-place
                              The function returns the above expression
                             The resulting list from map is printed, newline-separated
                              (-n flag)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.