Parantezleri Sağ El Brace (Sad Brace) birimine dönüştür


26

Sağ küme ayracı, küme ayraçlarının ve noktalı virgüllerin aa dosyasının sağ tarafındaki tek bir noktaya hizalandığı, kod tutturma stilidir.

Örnek Resim buraya gidin

Genel olarak, bu, birkaç nedenden dolayı, kötü bir uygulama olarak kabul edilir.

Meydan okuma

Herhangi bir yöntemde çok satırlı bir dize alın ve bu küme ayracı stilini Sağ Ayraca'ya dönüştürün.

Bu zorluk için, yalnızca Java kodu üzerinde çalışması gerekir, ancak teorik olarak Parantez ve Noktalı virgül kullanan herhangi bir kod üzerinde çalışması gerekir.

Tüm {};karakterleri arka arkaya, aralarında herhangi bir miktarda boşluk olacak şekilde almalısınız . ÖRNEĞİN. }},, ; } }\n\t\t}ve onları beyaz boşluk kullanarak dosyanın sağ tarafına hizalayın.

Örneğin:

a {
b;
{c

olmalı

a {
b ;{
c

Veya, daha soyut olarak, tüm boşlukları tüm {};karakterlerin solundan sağa doğru itin .

Satırların girintisi aksi takdirde korunmalıdır {};Karakterlerin hareketinden sonra sadece boşluk içeren çizgiler isteğe bağlı olarak kaldırılabilir.

Örneğin:

a{
    b{
        c;
    }
}
d;

Ya olabilir

a        {
    b    {
        c;}}
d        ;

veya

a        {
    b    {
        c;}}


d        ;

Sağa itti, tüm {};karakterlerin en uzun çizgiden kısa olmayan bir noktaya hizalanması anlamına gelir . Bundan sonra herhangi bir boşluk miktarı kabul edilebilir.

Yani aşağıdakilerin tümü kabul edilebilir:

a {
bc;

a  {
bc ;

a   {
bc  ;

vb...

Herhangi bir koddaki satırlar, {};diğer boşluk olmayan karakterler arasındaki karakterleri içerebilir , bu durumun ele alınması gerekli değildir, ancak eğer eğilirseniz onları yerinde bırakmanız gerekir. Satırlar ayrıca hiçbir {};karakter içermeyebilir ve bu doğru kullanılmalıdır. Aşağıda gösterildiği gibi.

a {
b ;
c
d }

Kod İncelemenin yaptığımız korkunç şeyleri görmesini istemediğimizden , kodunuzu olabildiğince küçük hale getirmeniz gerekir.

Örnekler / Testcases

Genel Java

public class HelloWorld{
       public static void main(String[] args){
           System.out.println("Hello, World!");
       }
}

olur ...

public class HelloWorld                        {
    public static void main(String[] args)     {
        System.out.println("Hello, World!")    ;}}

Resmin kendisi

public class Permuter{
    private static void permute(int n, char[] a){
        if (n == 0){
            System.out.println(String.valueOf(a));
        }else{
            for (int i=0; i<= n; i++){
                permute(n-1, a);
                swap(a, n % 2 == 0 ? i : 0, n);
            }
        }
    }
    private static void swap(char[] a, int i, int j){
        char saved = a[i];
        a[i] = a[j];
        a[j] = saved;
    }
}

olur ...

public class Permuter                                {
    private static void permute(int n, char[] a)     {
        if (n == 0)                                  {
            System.out.println(String.valueOf(a))    ;}
        else                                         {
            for (int i=0; i<= n; i++)                {
                permute(n-1, a)                      ;
                swap(a, n % 2 == 0 ? i : 0, n)       ;}}}
    private static void swap(char[] a, int i, int j) {
        char saved = a[i]                            ;
        a[i] = a[j]                                  ;
        a[j] = saved                                 ;}}

Çok Mükemmel Değil Genel Python

Kontrast için

def Main():
    print("Hello, World!");

Main();

olur ...

def Main():
    print("Hello, World!")    ;
Main()                        ;

notlar

  • Standart Loopholes uygulanır
  • Standart GÇ geçerlidir
  • Bu , bayt cinsinden en kısa program kazanıyor!
  • Sağ Brace tarzında programlama ile ilgili zararlardan sorumlu değilim
  • İyi eğlenceler!

Notları Düzenle

Mücadelenin ayrıntılarını yeniden değerlendirdim, Umarım kimsenin kurallara bakışını ihlal etmedim, sizi temin ederim ki istenmeyen. Bu çok daha net ve daha az kendi kendine çelişen bir özellik olmalıdır.


Birden fazla noktalı virgül içeren satırlardaki karar nedir? Gibi bir şeyint a=0;System.out.println(a);
Value Ink

2
Örnek resimdeki gibi döngüler için işlem yapmamız gerekmiyorsa, bu sorun için en iyi görüntü olmayabilir mi?
Dennis,

1
Söz konusu görüntü , daha karmaşık örneklere sahip olan bu izlemenin izlediği bu örnekten geldi gibi görünüyor
Ray Toal,

2
İstediğin net yapılmış olabilir ;{}onlar ayrı satırlarda iseniz topladı karakterler (örneğin sadece açık değil, kurallar ve bir çizgi oluşuyorsa aslında \t}anlamına geleceğini girinti koruyarak değil hareketli }sonuna kadar önceki hattın)
Chris H,

2
Tanrım, lütfen bana kimsenin pratikte Java ._ gibi ayrıntılı bir dil için pratik yapmadığını söyle.
Magic Octopus Urn,

Yanıtlar:


5

V + Bash yardımcı programları, 64 62 61 60 62 bayt

Eski komutları bir araya getirmek için @DJMcMayhem sayesinde 1 bayt kurtarıldı

:se ve=all|%!wc -L
y$uò/^ *<93>[{};]
xk$pòò/<84> {};][{};]«$
lDî^R0|p

^Riçin karakterin yazı <C-r>( 0x12) ve <84>bir 0x84ve <94>bir 0x94.

wc -L* nix tabanlı sistemlerin çoğunda çalışır, ancak macOS'ta çalışmaz. MacOS için, gwc -L henüz yapmadıysanız, marangoz kullanarak coreutils aldıktan sonra yapmanız gerekir.

Çevrimiçi deneyin! (Java)

Çevrimiçi deneyin! (Python)

Çevrimiçi deneyin! (Tekrar Java)

Bu, tüm boş satırları korur ve sekmeleri tutmaz, yalnızca boşlukları tutar.

HexDump:

00000000: 3a73 6520 7665 3d61 6c6c 7c25 2177 6320  :se ve=all|%!wc 
00000010: 2d4c 0a79 2475 f22f 5e20 2a93 5b7b 7d3b  -L.y$u./^ *.[{};
00000020: 5d0a 786b 2470 f2f2 2f84 207b 7d3b 5d5b  ].xk$p../. {};][
00000030: 7b7d 3b5d ab24 0a6c 44ee 1230 7c70       {};].$.lD..0|p

açıklama

Öncelikle imleci arabellekte herhangi bir yere taşıyabilmemiz gerekir, bu yüzden

:se ve=all|...

ve biz bunu kullanarak başka bir ex komutu ile zincir |

Girişteki en uzun satırın uzunluğunu almamız gerekiyor. Bu, kabuk komutuyla yapılabilir wc -L.

       ...|%!wc -L

Bu, sonucun bulunduğu geçerli tamponun (girişi içeren) üzerine yazar wc -L. Gibi bir şey çıktısını verir:

            42

ve imleç indirsinler 4in 42. Daha sonra bu numarayı kopyalayarak y$: yank metni imlecin konumundan satırın sonuna kadar kopyalarız . Bu, bu numarayı kayıt defterinde uygun bir şekilde saklar 0. Fakat daha sonraları. Girdi bu sayı ile değiştirildi, böylece geri dönmek için geri udöndük.

Şimdi, girişin bu şekilde göründüğünü söyleyin:

public class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello, World!");
    }
}

kaşlı ayraçları }arabellek sonundan printlnifadenin hemen arkasına taşımamız gerekir.

ò                  " recursively do this until a breaking error:
 /^ *<93>[{};]     "   this compressed regex becomes /^ *\zs[{};]
                   "   this finds any character from `{};` after leading spaces
                   "   the cursor then goes to the `{};`

x                  "   delete character
 k$                "   go to the end of the line above
   p               "   and paste
    ò

Eğer regex bulunamazsa, bir kırılma hatası meydana gelir ve neden olduğu özyinelemeden çıkar ò.

Şimdi bu programın ana kısmı geliyor, tüm parantezleri ve noktalı virgülleri hareket ettirin ve soruda belirtildiği gibi hizalayın.

ò                  " starts recursion
 /<84> {};][{};]«$ "   compressed form of [^ {};][{};]\+$
                   "   finds a sequence of `{};`s at the end of the line with a non-`{};` char to preceding it
 l                 "   move the cursor 1 to the right (since we were on the non-`{};` char now)
  D                "   delete everything from this position to the end of line
                   "   the deleted text contains `{};`
   î               "   execute as normal commands:
    ^R0            "   contains what's in register `0`, ie the length of the longest line
       |           "   now go to the column specified by that number
        p          "   and paste the contents 
                   " implicit ending `ò`

Yine, bu özyineleme, regex'in arabellekte bulunamamasına neden olan bir kırılma hatası ile durdurulacaktır.

Düzenlemeler

  • DBunun yerine kullanılır d$(İlk başta neden kaçırdığımı bile bilmiyorum)
  • Sıkıştırılmış [^(regex) için<84>
  • Kullanılarak Sabit hata \zs(sıkıştırılması <93>) çıkararak, $in$xk$pò
  • Faydasız newline kaldırıldı
  • Gönderimi yeni kurallara uygun hale getirmek için değiştirilmiş regex ve 2 bayt kazandı

Eski komutlarınıza birlikte katılırsanız bir bayttan tasarruf edebilirsiniz:se ve=all|%!wc -L
DJMcMayhem

@DJMcMayhem Teşekkürler, TIL
Kritixi Lithos 14:17

4

Ruby, 100 114 108 bayt

Dosya adını komut satırı argümanı olarak okur. Eğer bir dosya adı verilmezse, STDIN'den okuyacaktır. Sekmeleri işlemez.

Çevrimiçi deneyin!

f=$<.read.gsub(/[\s;{}]*$/){$&.tr"
 ",''}
$><<f.gsub(/(.*?)([;{}]+)$/){$1.ljust(f.lines.map(&:size).max)+$2}




@Pelel bana bildirdiğiniz için teşekkür ederiz. Dosyaya geçtikten sonra gördüğüm iki konu A. girintili bir catchifade ve B. kodun en uzun satırında çok fazla girintili olan bir noktalı virgül idi. Sanırım düzeltmem gereken şeyi biliyorum, bir saniye ver. (Ayrıca, sekmeleri kaldıramayacağını belirtmek için belirtimi güncelledim ve dosyanızda sekmeler var.)
Value Ink

Sekmeleri var mı? Sadece bulup değiştirdim ve 0 değişiklik yaptım.
Pavel

3

Perl , 90 bayt

88 bayt kodu + -p0bayrakları.

\@a[y///c]for/.*/g;s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gme;1while s/ *
 *([{};]+)$/$1/m

Çevrimiçi deneyin!

Kısa açıklamalar:
\@a[y///c]for/.*/g; en uzun satırın uzunluğunu sayar: her satır için dizinin indeksindeki öğeyi y///c(yani satırın boyutunu) tanımlar @a. Sonunda, @a(örneğin büyüklüğü @a) maksimum dizini en uzun satırın boyutudur.
s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gmeyerleştirir {};satırlarının sonunda karakterleri.
1while s/ *\n *([{};]+)$/$1/mboş çizgilerdeki diş tellerinin yukarıdaki çizgiye gitmesini sağlar.

Teşekkür etmek @primo ben kısmen benim kod başlangıcı "çaldı" kimden burada en uzun hat uzunluğunu saymak.


Onlardan önce sadece boşluk varsa, parantezler yukarıdaki satıra geri
dönmelidir

@KritixiLithos gerçekten, meydan okuma yeniden ele alınmadan önce iyi görünüyordu (hem zorluklardan hem de yorumlardan anladığım kadarıyla). Her neyse, şimdi düzeltildi (farketmemeniz durumunda cevabımda yazılı kod zaten vardı).
Dada

1

Python 2: 228 Bayt

import re
g=re.search
def b(a):
    s,l="",a.split('\n')
    r=max([len(k)for k in l]) 
    for k in l:
        n,m=g('[;}{]',k),g('[\w]',k)
        if n:n=n.start()
        if m:m=m.start()
        if n>m and m!=None:s+="\n"+k[:n]+" "*(r-n)
        s+=k[n:]
    print s

Korkunç derecede uzun. Muhtemelen ;{}önceki satırların sonuna gitmek için yalnız başına ihtiyacım olduğunu anladığımda sıfırdan başlamalıydım .
Chris H,

1

yığılmış , 133 bayt

'\s+([;{}])' '$1'repl lines{!n'[\s;{}]+$'match''join:n\'$'+del\,}"!tr:$size"!$MAXmap@k{e i:e[' 'k i#rpad]"!}map tr[' 'join]map'
'join

Çevrimiçi deneyin! Bu konuyu çok fazla düşünebilirdim ... ama neyse. Yarın tekrar bakacağım. Bazı güzel ipuçları:

  1. "!mapBir sonraki belirtecin bir kelime ile başlayıp başlamamasına bağlı olarak, bir veya iki bayt kaydederek yerine kullanılabilir . Ancak, yalnızca dizinin her atomunun eşlenmesini istediğinde kullanılabilir. Derin bir haritaya benzer.
  2. Bir uzay bir alıntı işlevi sonrasında gerekli değildir, bu nedenle $MAXmapeşdeğerdir $MAX mapsırayla eşdeğer olan [MAX] map. (Her diziyi maksimum öğesine eşler.)

1

JavaScript (ES Önerisi), 139 121 bayt

f=
s=>s.replace(/^(.*?)\s*(([;{}]\s*)+)$/gm,(_,t,u)=>t.padEnd(Math.max(...s.split`
`.map(s=>s.length)))+u.replace(/\s/g,``))
<textarea rows=10 cols=40 oninput=o.textContent=f(this.value)></textarea><pre id=o>

Firefox 48 / Chrome 57 / Opera 44 / Safari 10 / Kenar 15 gerektirir padEnd. Düzenleme: @ValueInk sayesinde 18 bayt kaydedildi.


s.replace(r,`$1`)Satır uzunluğunu hesaplarken gerçekten kaçmanız gerekiyor mu? Herhangi bir miktarda makul sağ dolgu yeterli olmalıdır, bu nedenle noktalı virgül ve parantez ile çizgi uzunluğu sayımı iyi olmalıdır.
Value Ink,

0

PHP, 201 194 185 172 167 bayt

foreach($f=file(f)as$s)$x=max($x,strlen($a[]=rtrim($s,"{} ;
")));foreach($a as$i=>$c)echo str_pad($c,""<$c|!$i?$x:0),trim(substr($f[$i],strlen($c))),"
"[""==$a[$i+1]];

f dosyasından girdi alır; tek baytlı satır başlıkları varsayar; boş satırları korur.

  • Beyaz alanı sınırlamak için +2 bayt: +1ikinci str_padparametreye ekleyin .
  • Hiçbir kod satırı tek ibaret olduğunu garanti olsaydı -6 bayt 0:
    Kaldır ""<ve değiştirme ""==ile !.

Yıkmak

foreach($f=file(f)as$s)             // loop through file
    $x=max($x,strlen(                   // 3. set $x to maximum code length
        $a[]=                           // 2. append to array $a
            rtrim($s,"{} ;\n")          // 1. strip trailing whitespace and braces
    ));
foreach($a as$i=>$c)echo            // loop through $a
    str_pad($c,                         // 1. print code:
        !$i|""<$c                       // if first line or not empty
        ?$x                             // then padded to length $x
        :0                              // else unpadded (= print nothing)
    ),
    trim(substr($f[$i],strlen($c))),    // 2. print braces
    "\n"[""==$a[$i+1]]                  // 3. if next line has code, print newline
;

{}Regex'teki diş tellerinden kaçmanız gerektiğine emin misiniz ?
Kritixi Lithos,

@KritixiLithos Muhtemelen hayır; ama yine de daha kısa bir yaklaşım buldum.
Titus,

0

Java 8, 312 305 bayt

s->{String t="([;{}]+)",z[],r="",a;s=s.replaceAll(t+"[\\s\\n]*","$1").replaceAll(t,"$1\n");int m=0,l;for(String q:s.split("\n"))m=m>(l=q.length())?m:l;for(String q:s.split("\n")){z=q.split("((?<="+t+")|(?="+t+"))",2);for(a="",l=0;l++<m-z[0].length();a+=" ");r+=z[0]+a+(z.length>1?z[1]:"")+"\n";}return r;}

Açıklama:

Burada dene.

s->{                                  // Method with String parameter and String return-type
  String t="([;{}]+)",                //  Temp regex-String we use multiple times
    z[],a,                            //  Temp String-array and temp String
    r="";                             //  Result-String
  s=s.replaceAll(t+"[\\s\\n]*","$1")  //  We replace all ;{} in the input with zero or more whitespaces/newlines to just ;{}
     .replaceAll(t,"$1\n");           //  and then add a single newline after each group of ;{}
  int m=0,l;                          //  Two temp integers
  for(String q:s.split("\n"))         //  Loop (1) over the lines
    m=m>(l=q.length())?m:l;           //   To determine the longest line
                                      //  End of loop (1)
  for(String q:s.split("\n")){        //  Loop (2) over the lines again
    z=q.split("((?<="+t+")|(?="+t+"))",2);
                                      //   Split on groups of ;{}, but keep them in the array
    for(a="",l=0;l++<m-z[0].length();a+=" "); 
                                      //   Amount of spaces we should add
    r+=z[0]+a+(z.length>1?z[1]:"")+"\n"; 
                                      //   Append this line to the result-String
  }                                   //  End of loop (2)
  return r;                           //  Return the result-String
}                                     // End of method

Hey, bu cevapla ilgili yorum yapıyorum, ancak sizin diğer birçoklarınız için de geçerli. Şu anda Java türlerinde lambda parametrelerine ihtiyacımız var .
Nathan Merrill

1
@NathanMerrill, kararın geleceği günden korkuyordu. Jk, bundan sonra ekleyeceğim ve cevabımı düzelttim, teşekkürler. ;)
Kevin Cruijssen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.