Membalikkan indentasi

63

Saya pernah mendengar bahwa kode Anda dapat berjalan lebih cepat jika Anda memasukkannya secara terbalik, sehingga kompiler dapat memprosesnya seperti pola desain pohon dari bagian atas "cabang" ke bawah. Ini membantu karena gravitasi akan mempercepat waktu yang dibutuhkan untuk mengkompilasi kode Anda, dan efisiensi struktur data ditingkatkan. Berikut ini contohnya, dalam skrip 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;
            }

Tetapi untuk beberapa alasan Notepad tidak memiliki pengaturan untuk melakukan ini secara otomatis, jadi saya perlu program untuk melakukannya untuk saya.

Deskripsi

Pengajuan harus mengambil cuplikan kode sebagai input, membalikkan lekukan, dan mengeluarkan kode yang dihasilkan.

Ini dilakukan dengan prosedur berikut:

  • Bagi kode menjadi beberapa baris. Setiap baris akan mulai dengan nol atau lebih banyak spasi (tidak akan ada tab).

  • Temukan semua level lekukan unik dalam kode. Misalnya, untuk contoh di atas, ini akan menjadi

    0
    4
    8
    12
    
  • Membalik urutan daftar tingkat indentasi ini, dan memetakan daftar terbalik ke daftar asli. Ini sulit dijelaskan dengan kata-kata, tetapi sebagai contoh, akan terlihat seperti

    0  — 12
    4  — 8
    8  — 4
    12 — 0
    
  • Terapkan pemetaan ini ke kode asli. Dalam contoh ini, baris dengan indentasi 0-spasi akan menjadi indentasi oleh 12 spasi, 4 spasi akan menjadi 8 spasi, dll.

Input output

Input dan output dapat disediakan namun Anda ingin (STDIN / STDOUT, parameter fungsi / nilai pengembalian, dll.); jika bahasa Anda tidak mendukung input multiline (atau Anda tidak mau), Anda dapat menggunakan |karakter untuk memisahkan baris.

Input akan terdiri dari hanya baris ASCII + yang dapat dicetak, dan tidak akan berisi baris kosong.

Uji kasus

Memasukkan:

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

Output: contoh kode di atas.

Memasukkan:

a
  b
  c
d
   e
        f
  g
   h

Keluaran:

        a
   b
   c
        d
  e
f
   g
  h

Memasukkan:

1
 2
  3
 2
1

Keluaran:

  1
 2
3
 2
  1

Memasukkan:

  foo

Keluaran:

  foo
Gagang pintu
sumber
21
Ini "JavaScript" bukan "Java scripting": /
Optimizer
75
@ Pengoptimal Saya melihat bahwa tujuan saya untuk membuat marah sebanyak mungkin orang dengan dua paragraf pertama telah tercapai. ;)
Gagang Pintu
7
1! = Orang sebanyak mungkin.
Pengoptimal
23
@JanDvorak Orang-orang yang sama yang menemukan kutipan gaya MLA berpikir ini adalah ide yang bagus.
Rainbolt
6
Seharusnya, lebih cepat. Mari kita menugaskan sebuah komite untuk itu dan menunggu beberapa tahun sementara kita lupa tujuannya.
Conor O'Brien

Jawaban:

10

CJam, 43 39 36 35 byte

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

Ini terlihat terlalu panjang. Saya yakin saya tidak cukup Mengoptimalkan !

Bagaimana itu bekerja:

Ide dasarnya adalah untuk membagi input pada baris baru, menghitung jumlah spasi terdepan di setiap baris, mengurutkan dan mendapatkan nomor unik, menyalin array itu dan membalikkan salinan, mentransliterasikan nomor urutan asli dengan dua array ini dan akhirnya membentuk string terakhir menggunakan informasi ini.

Bagian terlama adalah untuk mencari tahu berapa banyak ruang utama yang ada di setiap baris karena CJam tidak memiliki cara mudah untuk melakukannya.

Perluasan kode:

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

Dan dalam semangat pertanyaan. Perluasan nyata dari kode:

                                          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 byte disimpan berkat Martin dan 1 byte berkat Dennis

Cobalah online di sini

Pengoptimal
sumber
1. {}#memiliki bug: mengembalikan Integer, tetapi harus mengembalikan Long. Ironisnya, i(cast to integer) memperbaiki ini. 2. Karena ""#tidak memiliki bug yang sama, _Sm0=#lebih pendek satu byte.
Dennis
@ Dennis Ya, bug itu aneh. Terima kasih atas solusinya!
Pengoptimal
2
lekukan dalam ekspansi ini sangat mudah dibaca! Anda harus membalikkannya!
DLeh
13

Python 2 - 137 131 byte

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()

Mengambil input dengan |alih - alih \n.

Penjelasan

Tiga baris pertama cukup mudah. Buat daftar semua garis dalam input, tentukan fungsi yang memberi tahu Anda seberapa besar spasi yang dimiliki oleh string, dan buat daftar nilai yang diurutkan yang fungsi tersebut keluarkan untuk setiap baris input.

Baris terakhir jauh lebih menyenangkan.

                                 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
monmon bawah tanah
sumber
Dikonfirmasi 137 :)
FryAmTheEggman
@ frya terima kasih :)
undergroundmonorail
1
Ini semua tampak baik dalam python 3 yang seharusnya menghemat 2 byte (bayar 2 untuk ()hemat 4 raw_)
FryAmTheEggman
1
f(s)for s in iseharusnya map(f,i).
feersum
1
Sepotong sihir: d=[];d+=set(L)adalah versi lebih pendek dari d=sorted(set(L)).
xnor
7

JavaScript, ES6, 113 103 101 byte

Saya cukup yakin ini bisa bermain golf setidaknya sedikit lebih jauh, tapi begini saja.

Tidak akan pernah berpikir bahwa akan ada solusi JS byte 101, mengalahkan 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]))

Ini menciptakan metode bernama fyang dapat dipanggil dengan string input. Jika Anda menggunakan Firefox terbaru, Anda memiliki string templat dan Anda dapat memanggil metode seperti

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

Kalau tidak, Anda juga bisa menyebutnya seperti

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

atau, coba cuplikan di bawah ini:

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>

Pengoptimal
sumber
Anda dapat menyimpan byte coupe dengan menyimpan regex sebagai variabel, karena digunakan dua kali (Anda harus dapat mengganti \sdengan karakter spasi), dan menghapus tanda kurung di xdalam fungsi ganti.
NinjaBearMonkey
Ya ampun, terima kasih! Saya bahkan tidak tahu mengapa saya menulis (x): /
Pengoptimal
Anda tidak membutuhkan keduanya bdan capakah Anda? Mereka hanya merujuk pada array yang sama.
Neil
5

Ruby, 63 byte

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

Ini mendefinisikan fungsi tanpa nama yang mengambil dan mengembalikan string. Anda bisa memanggilnya dengan menambahkan ["string here"]atau dengan menugaskannya ke variabel, dan kemudian memanggil variabel itu.

Cara kerjanya: s.scan(r=/^ */)memberikan daftar semua ruang terkemuka dan toko yang masuk kembali runtuk digunakan nanti. uniqmenghilangkan duplikat. sort... macam.

Sekarang lompat ke akhir, l.zip(l.reverse)berikan array pasangan yang ingin kita gantikan. to_hmengubahnya menjadi hash, menafsirkan pasangan sebagai pasangan kunci-nilai.

Sekarang s.gsubdiganti semua kecocokan regex (semua ruang utama) dengan menggunakan hash itu sebagai tabel pencarian untuk menemukan penggantinya.

Martin Ender
sumber
2

Japt -R , 27 byte

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

Cobalah online!

Dibongkar & Cara kerjanya

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

Cara benar-benar bekerja

                 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
Bubbler
sumber
1

Scala, 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'}}

Ini akan menambahkan baris baru ekstra di akhir. Jika saya tidak harus menyimpan ruang di akhir baris, saya bisa mendapatkannya ke 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'}}

Tidak Disatukan:

      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'
    }
      }
Chad Retz
sumber
1

PowerShell , 112 byte

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

Cobalah online!

Kurang bermain golf:

$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
mazzy
sumber
0

Haskell, 116

import Data.List
f s|l<-map(span(==' '))$lines s=unlines[k++b|(a,b)<-l,(k,r)<-reverse>>=zip$sort$nub$map fst l,r==a]
haskeller bangga
sumber
0

PHP - 173 byte

Kode yang tidak dioptimalkan harus disimpan dalam $vvariabel:

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

Ini adalah versi yang tidak diklik dan dikomentari:

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

Saya mungkin tidak pernah menulis sesuatu yang begitu kotor. Aku malu.

Lubang hitam
sumber
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);

Versi tidak disatukan:

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

Pengujian

The Guy with The Hat
sumber
0

Perl 5, 112

111 +1 untuk -n( -Egratis)

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

Saya yakin itu bisa dilakukan dengan pukulan lebih sedikit, tetapi saya tidak melihat bagaimana saat ini.

msh210
sumber