Зворотний відступ


63

Я чув, що ваш код може працювати швидше, якщо відкласти його в зворотному порядку, щоб компілятор міг обробляти його як шаблон дизайну дерева з самої вершини "гілок" вниз. Це допомагає, оскільки гравітація пришвидшить час, необхідний для складання вашого коду, а ефективність структури даних покращиться. Ось приклад сценаріїв Java:

            function fib(n) {
        var a = 1, b = 1;
        while (--n > 0) {
    var tmp = a;
    a = b;
    b += tmp;
    if (a === Infinity) {
return "Error!";
    }
        }
        return a;
            }

Але чомусь у Блокноті немає налаштування робити це автоматично, тому мені потрібна програма, щоб це зробити для мене.

Опис

Подані матеріали повинні брати фрагмент коду як вхідний, відміняти відступ та виводити отриманий код.

Це робиться за наступною процедурою:

  • Розбийте код на рядки. Кожен рядок починатиметься з нуля або більше пробілів (вкладок не буде).

  • Знайдіть усі унікальні рівні відступи в коді. Наприклад, для наведеного вище прикладу це було б

    0
    4
    8
    12
    
  • Зворотний порядок цього списку рівнів відступів і зіставте перевернутий список у вихідний список. Це важко пояснити словами, але, наприклад, це виглядало б так

    0  — 12
    4  — 8
    8  — 4
    12 — 0
    
  • Застосуйте це зіставлення до вихідного коду. У прикладі, рядок з відступом 0-простору стане відступів на 12 пробілів, 4 пробіли стануть 8 пробілами тощо.

Введення-виведення

Вхід і вихід можуть бути надані, як би ви хотіли (STDIN / STDOUT, параметр функції / значення повернення тощо); якщо ваша мова не підтримує багаторядковий вхід (або ви просто не хочете), ви можете використовувати |символ для розділення рядків.

Вхід буде складатися лише з друкованих ASCII + нових рядків, і він не буде містити порожніх рядків.

Тестові справи

Вхід:

function fib(n) {
    var a = 1, b = 1;
        while (--n > 0) {
            var tmp = a;
            a = b;
            b += tmp;
            if (a === Infinity) {
                return "Error!";
            }
        }
    return a;
}

Вихід: наведений вище приклад коду.

Вхід:

a
  b
  c
d
   e
        f
  g
   h

Вихід:

        a
   b
   c
        d
  e
f
   g
  h

Вхід:

1
 2
  3
 2
1

Вихід:

  1
 2
3
 2
  1

Вхід:

  foo

Вихід:

  foo

21
Її "JavaScript", а не "Сценарій на Java": /
Optimizer

75
@Optimizer Я бачу, що моя мета - розлютити якомога більше людей першими двома абзацами була досягнута. ;)
Дверна ручка

7
1! = Якомога більше людей.
Оптимізатор

23
@JanDvorak Ті ж хлопці, які винайшли цитати стилю MLA, вважають, що це гарна ідея.
Rainbolt

6
Нібито, це швидше. Давайте призначимо йому комітет і почекаємо кілька років, поки ми забудемо мету цього.
Conor O'Brien

Відповіді:


10

CJam, 43 39 36 35 байт

qN/_{_Sm0=#}%___&$_W%er]z{~S*@+>N}%

Це виглядає занадто довго. Я впевнений, що я недостатньо оптимізую !

Як це працює:

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

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

Розширення коду:

qN/_                                      "Split the string on newline and take copy";
    {_Sm0=#}%                             "Map this code block on the copy";
     _Sm                                  "Copy the string and remove spaces from the copy";
        0=                                "Get first non space character";
          #                               "Gets its index in original string";
             ___                          "Get 3 copies of the above array";
                &$_W%                     "Get unique elements, sort, copy and reverse";
                     er                   "Transliterate unique sorted elements with";
                                          "the unique reverse sorted in the copy";
                       ]z                 "Get array of [row,
                                          " original number of leading spaces,
                                          " required number of leading spaces]";
                         {~S*@+>N}%       "For each above combination";
                          ~S*             " unwrap and get leading space string";
                             @+           " prepend to the row";
                               >          " remove original spaces";
                                N         " put newline";

І в дусі питання. Справжнє розширення коду:

                                          qN/_                                      "Split the string on newline and take copy";
                                {_Sm0=#}%                             "Map this code block on the copy";
                               _Sm                                  "Copy the string and remove spaces from the copy";
                             0=                                "Get first non space character";
                          #                               "Gets its index in original string";
                         ___                          "Get 3 copies of the above array";
                       &$_W%                     "Get unique elements, sort, copy and reverse";
                     er                   "Transliterate unique sorted elements with";
"the unique reverse sorted in the copy";
                ]z                 "Get array of [row,
" original number of leading spaces,
" required number of leading spaces]";
             {~S*@+>N}%       "For each above combination";
          ~S*             " unwrap and get leading space string";
        @+           " prepend to the row";
     >          " remove original spaces";
    N         " put newline";

7 байт збережено завдяки Мартіну та 1 байт завдяки Деннісу

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


1. {}#має помилку: він повертає цілий ряд, але він повинен повернути Long. За іронією долі, i(прикинути до цілого числа) це виправляє. 2. Оскільки ""#помилка не має однакового значення, _Sm0=#на один байт коротше.
Денніс

@Dennis Так, помилка дивна. Дякую за вирішення!
Оптимізатор

2
цей відступ у розширенні так легко читати! Ви повинні змінити це!
DLeh

13

Python 2 - 137 131 байт

i=raw_input().split('|')
f=lambda s:len(s)-len(s.lstrip())
d=sorted(set(map(f,i)))
for l in i:print' '*d[~d.index(f(l))]+l.lstrip()

Приймає введення з, |а не \n.

Пояснення

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

Останній рядок - набагато веселіше.

                                 l               # string with the line
                               f(l)              # amount of leading whitespace
                       d.index(f(l))             # where it is in list of whitespace amounts
                      ~d.index(f(l))             # bitwise NOT (~n == -(n+1))
                    d[~d.index(f(l))]            # index into the list (negative = from end)
           print' '*d[~d.index(f(l))]            # print that many spaces...
           print' '*d[~d.index(f(l))]+l.lstrip() # plus everything after leading whitespace
for l in i:print' '*d[~d.index(f(l))]+l.lstrip() # do the above for every line


@frya дякую :)
undergroundmonorail

1
У Python 3 все це чудово, що має заощадити 2 байти (заплатити 2 за ()заощадження 4 за raw_)
FryAmTheEggman

1
f(s)for s in iповинно бути map(f,i).
feersum

1
Чарівник: d=[];d+=set(L)це скорочена версія d=sorted(set(L)).
xnor

7

JavaScript, ES6, 113 103 101 байт

Я впевнений, що це можна пограти в гольф хоча б трохи далі, але ось що.

Ніколи б не подумав, що буде JS-рішення на 101 байт, побивши Python!

f=a=>(b=c=[...Set(a.match(r=/^ */gm).sort())],c.map((x,i)=>b[x]=c.slice(~i)[0]),a.replace(r,x=>b[x]))

Це створює метод, названий fяким можна викликати рядок введення. Якщо ви перебуваєте в останньому Firefox, у вас є рядки шаблонів, і ви можете викликати такий метод

f(`a
  b
  c
d
   e
        f
  g
   h`)

В іншому випадку ви також можете назвати це так

f("a\n\
  b\n\
  c\n\
d\n\
   e\n\
        f\n\
  g\n\
   h")

або спробуйте фрагмент нижче:

g=_=>O.textContent=f(D.value)

f=a=>(b=c=[...Set(a.match(r=/^ */gm).sort())],c.map((x,i)=>b[x]=c.slice(~i)[0]),a.replace(r,x=>b[x]))
<textarea id=D></textarea><button id=B onclick=g()>Inverse!</button>
<pre id=O></pre>


Ви можете зберегти байти купе, зберігаючи регулярний вираз як змінну, оскільки він використовується двічі (ви повинні мати можливість замінити \sсимволом пробілу) та видалити круглі дужки навколо xу функції заміни.
NinjaBearMonkey

@hsl да, дякую! Навіть не знаю, чому я написав (x): /
Оптимізатор

Вам не потрібно і те, bі cчи не так? Вони все одно посилаються на той самий масив.
Ніл

5

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

->s{l=s.scan(r=/^ */).uniq.sort;s.gsub r,l.zip(l.reverse).to_h}

Це визначає неназвану функцію, яка бере і повертає рядок. Ви можете зателефонувати йому, додавши ["string here"]або додавши до змінної, а потім викликавши цю змінну.

Як це працює: s.scan(r=/^ */)подає список усіх провідних просторів і магазинів, які повторно rвикористовуються для подальшого використання. uniqвиключає дублікати. sort... сортування.

Тепер пропустимо до кінця, l.zip(l.reverse)дає масив пар, які ми хочемо замінити. to_hперетворює це в хеш, інтерпретуючи пари як пари ключових значень.

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



2

Japt -R , 27 байт

·
mâ\S
Vâ n
Ëx2 iSpWg~WbVgE

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

Розпаковано та як це працює

Input: U = multiline string

qR    Split by newline and implicit assign to U

mâ\S
m     Map over U...
 â\S    .search(/\S/); first index of non-whitespace char
      Implicit assign to V (V = array of indentations)

Vâ n  Take unique elements of V, sort, and implicit assign to W

mDEF{Dx2 iSpWg~WbVgE
mDEF{                 Map over U...
     Dx2                Trim left
         iSp            Indent by this many spaces...
                 VgE      Find the current indentation stored in V
               Wb         Find its index on W
            Wg~           Take the opposite element on W

-R    Join with newline

Як це насправді працює

                 Input: U = multiline string

                 qR    Split by newline and implicit assign to U

                 mâ\S
                 m     Map over U...
               â\S    .search(/\S/); first index of non-whitespace char
         Implicit assign to V (V = array of indentations)

                 Vâ n  Take unique elements of V, sort, and implicit assign to W

                 mDEF{Dx2 iSpWg~WbVgE
                 mDEF{                 Map over U...
            Dx2                Trim left
      iSp            Indent by this many spaces...
VgE      Find the current indentation stored in V
 Wb         Find its index on W
     Wg~           Take the opposite element on W

                 -R    Join with newline

1

Скала, 176 171

def g(n:String)={val a=n.split('|').map(a=>a.prefixLength(' '==)->a)
(""/:a){case(s,(l,p))=>val b=a.unzip._1.distinct.sorted
s+" "*b.reverse(b.indexOf(l))+p.drop(l)+'\n'}}

Це додасть додатковий новий рядок наприкінці. Якщо мені не довелося зберігати пробіли в кінці рядка, я можу отримати його до 167:

def t(n:String)={val a=n.split('|').map(a=>a.prefixLength(' '==)->a.trim)
(""/:a){(s,l)=>val b=a.unzip._1.distinct.sorted
s+" "*b.reverse(b.indexOf(l._1))+l._2+'\n'}}

Безголівки:

      def reverseIndent(inString: String): String = {
    val lines = inString.split('\n')
    val linesByPrefixLength = lines.map { line =>
  line.prefixLength(char => char == ' ') -> line
    }
    val distinctSortedPrefixLengths = linesByPrefixLength.map(_._1).distinct.sorted
    val reversedPrefixes = distinctSortedPrefixLengths.reverse
    linesByPrefixLength.foldLeft("") { case (string, (prefixLength, line)) =>
  val newPrefixLength = reversedPrefixes(distinctSortedPrefixLengths.indexOf(prefixLength))
  val nextLinePrefix = " " * newPrefixLength
  string + nextLinePrefix + line.substring(prefixLength) + '\n'
    }
      }

1

PowerShell , 112 байт

$x=@($args|sls '(?m)^ *'-a|% m*|% v*|sort -u)
[regex]::Replace($args,'(?m)^ *',{$x[-1-$x.IndexOf($args.Value)]})

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

Менше гольфу:

$xIdents=@($args|select-string '(?m)^ *'-AllMatches|% matches|% value|sort -unique) # get a sorted set of indentations
[regex]::Replace($args,'(?m)^ *',{$xIdents[-1-$xIdents.IndexOf($args.Value)]})    # replace each indentation with opposite one


0

PHP - 173 байти

Неоптимізований код повинен зберігатися у $vзмінній:

<?php $f='preg_replace';$f($p='#^ *#me','$i[]='.$s='strlen("$0")',$v);$a=$b=array_unique($i);sort($a);rsort($b);echo$f($p,'str_repeat(" ",array_combine($a,$b)['.$s.'])',$v);

Ось невольф і коментований варіант:

<?php
// Get the level of indentation for each line
$preg_replace = 'preg_replace';
$pattern = '#^ *#me';
$strlen = 'strlen("$0")';
$preg_replace($pattern, '$indentationLevelsOldList[] = '. $strlen, $value);

// Create an array associating the old level of indentation with the new expected one
$sortedArray = array_unique($indentationLevelsOldList);
$reverseSortedArray = $sortedArray;

sort($sortedArray);
rsort($reverseSortedArray);

$indentationLevelsNewList = array_combine($sortedArray, $reverseSortedArray);

// Print the correctly indented code
echo $preg_replace($pattern, 'str_repeat(" ", $indentationLevelsNewList['. $strlen .'])', $value);

Я, певно, ніколи не писав чогось такого брудного. Мені соромно.


0

JavaScript, 351

var i=0;var a=$("#i").html().split("\n");var b=[];for(;i<a.length;i++){j=a[i].match(/\s*/)[0];if(b.indexOf(j)<0){b.push(j);}}b.sort(function(a,b){return a - b;});var c=b.slice().reverse();var d="";for(i=0;i<a.length;i++){d+=a[i].replace(/\s*/,c[b.indexOf(a[i].match(/\s*/)[0])])+"\n";j=a[i].search(/\S/);if(b.indexOf(j)<0){b.push(j);}}$("#i").html(d);

Негольована версія:

var i = 0;
var a = $("#i").html().split("\n");
var b = [];
for (; i < a.length; i++) {
  j = a[i].match(/\s*/)[0];
  if (b.indexOf(j) < 0) {
    b.push(j);
  }
}
b.sort(function(a, b) {
  return a - b;
});
var c = b.slice().reverse();
var d = "";
for (i = 0; i < a.length; i++) {
  d += a[i].replace(/\s*/, c[b.indexOf(a[i].match(/\s*/)[0])]) + "\n";
  j = a[i].search(/\S/);
  if (b.indexOf(j) < 0) {
    b.push(j);
  }
}
$("#i").html(d);

Тестування


0

Перл 5, 112

111 + 1 для -n( -Eбезкоштовно)

@{$.[$.]}=/( *)(.*)/;++$_{$1}}{map$_{$_[$#_-$_]}=$_[$_],0..(@_=sort keys%_);say$_{$.[$_][0]}.$.[$_][1]for 0..$.

Я впевнений, що це можна зробити меншими ударами, але наразі не бачу, як це зробити.

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