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

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

Обратите внимание, что каждый уровень иерархического отступа имеет свой собственный набор увеличивающихся чисел, даже если они доходят только до одного.

В выводе не должно быть завершающих пробелов, но при желании может быть один завершающий перевод строки.

Напишите полную программу, которая принимает входную строку через стандартный ввод или командную строку, или напишите функцию, которая принимает строку в качестве аргумента. Напечатайте результат или верните его в виде строки.

Самый короткий код в байтах побеждает.

Примеры

Если введена пустая строка, пустая строка должна быть выведена.

Следующим самым тривиальным примером является ввод

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

Pyth, 18 байт

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

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

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

оборота Исаак
источник
8

Python 2, 77

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

Как и ответ Sp3000 , но со словарем. В dict Sхранится текущий номер для каждого уровня вложенности '0', ' 0', ' 0'и т. Д. Для каждой строки на входе увеличьте соответствующий уровень вложенности и установите уровень вложенности на единицу выше 0.

XNOR
источник
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]`
Sp3000
источник
Я обнаружил, что вы можете сохранить некоторые символы, взяв каждую строку в виде строки пробелов, чтобы вы могли распечатать эти пробелы напрямую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 в каждой строке на число, которое мы хотим.

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

Sp3000
источник
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(). РЕДАКТИРОВАТЬ: 2 байта сохранены благодаря совету vihan1086.

Приведенный ниже фрагмент стека может быть использован для тестирования, поскольку он немного раскручен и использует лучше поддерживаемый синтаксис ES5. Вторая функция - это polyfill, потому 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>

NinjaBearMonkey
источник
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.

faubi
источник
0

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

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

Ввод от стандартного ввода. Попробуйте онлайн!

объяснение

                             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)
DLosc
источник