Convertir les accolades en accolade droite (accolade triste)

26

L'accolade à droite est un style de bracketing de code dans lequel les accolades et les points-virgules sont tous alignés sur un seul point sur le côté droit d'un fichier.

Exemple d'image allez ici

En règle générale, cela est considéré comme une mauvaise pratique, pour plusieurs raisons.

Le défi

Prenez une chaîne multiligne par n'importe quelle méthode et convertissez son style d'accolade en accolade à droite.

Pour ce défi, vous n'en avez besoin que pour travailler sur du code Java, cependant, il devrait théoriquement fonctionner sur n'importe quel code qui utilise des accolades et des points-virgules.

Vous devez saisir tous les {};caractères dans une rangée, avec n'importe quelle quantité d'espace entre eux. PAR EXEMPLE. }},, ; } }\n\t\t}et alignez-les sur le côté droit du fichier en utilisant des espaces.

par exemple:

a {
b;
{c

devrait devenir

a {
b ;{
c

Ou, plus abstraitement, poussez tous les espaces blancs de la gauche de tous les {};caractères vers la droite.

L'indentation des lignes doit être conservée autrement. Les lignes contenant uniquement des espaces après le mouvement des {};personnages peuvent éventuellement être supprimées.

Par exemple:

a{
    b{
        c;
    }
}
d;

Peut devenir soit

a        {
    b    {
        c;}}
d        ;

ou

a        {
    b    {
        c;}}


d        ;

Poussé vers la droite fait référence à tous les {};caractères alignés sur un point pas plus court que la ligne la plus longue. Toute quantité d'espace après cela est acceptable.

Donc, tout ce qui suit est acceptable:

a {
bc;

a  {
bc ;

a   {
bc  ;

etc...

Les lignes de n'importe quel code peuvent contenir des {};caractères entre d'autres caractères non blancs, la gestion de ce cas n'est pas nécessaire, bien que si vous êtes incliné, vous devez les laisser en place. Les lignes peuvent également ne contenir aucun {};caractère, et cela doit être géré correctement. Comme indiqué ci-dessous.

a {
b ;
c
d }

Parce que nous ne voulons pas que la révision de code voit les choses horribles que nous faisons, vous devez rendre votre code aussi petit que possible.

Exemples / cas de test

Java générique

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

devient...

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

L'image elle-même

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

devient...

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

Pas si parfaitement générique Python

Pour le contraste

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

Main();

devient...

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

Remarques

  • Les échappatoires standard s'appliquent
  • IO standard s'applique
  • C'est le , donc le programme le plus court en octets gagne!
  • Je ne suis pas responsable des dommages liés à la programmation dans le style de l'accolade à droite
  • S'amuser!

Modifier les notes

J'ai reformulé les détails du défi, j'espère que je n'ai brisé la vision de personne sur les règles, je vous assure que ce n'était pas intentionnel. Cela devrait être une spécification beaucoup plus claire et moins conflictuelle.

ATaco
la source
Quel est le verdict sur les lignes avec plusieurs points-virgules? Quelque chose commeint a=0;System.out.println(a);
Value Ink
2
Ce n'est peut-être pas la meilleure image pour le défi si nous n'avons pas besoin de gérer les boucles comme dans l'exemple d'image?
Dennis
1
On dirait que l'image dans la question provient de cet exemple , qui a été suivi par ce suivi , qui a des exemples plus complexes
Ray Toal
2
Il pourrait être plus clair que vous souhaitiez que les ;{}caractères soient rassemblés s'ils sont sur des lignes distinctes (cela ne ressort que de l'exemple, pas des règles, et en fait, si une ligne consiste à \t}conserver l'indentation, cela signifierait de ne pas remonter }jusqu'à la fin de la ligne précédente)
Chris H
2
Bon dieu, dites-moi que personne ne le fait en pratique pour un langage verbeux comme Java ._.
Urne de poulpe magique du

Réponses:

5

Utilitaires V + Bash, 64 62 61 60 62 octets

1 octet enregistré grâce à @DJMcMayhem pour avoir assemblé les commandes ex

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

^Rest le caractère littéral de <C-r>( 0x12) et <84>est 0x84et <94>est 0x94.

wc -Lfonctionne sur la plupart des systèmes basés sur * nix, mais pas sur macOS. Pour macOS, vous devez le faire gwc -L après avoir obtenu des coreutils en utilisant brew, si vous ne l'avez pas déjà fait.

Essayez-le en ligne! (Java)

Essayez-le en ligne! (Python)

Essayez-le en ligne! (Java à nouveau)

Cela préserve toutes les lignes vides et ne gère pas les tabulations, seulement les espaces.

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

Explication

Nous devons d'abord pouvoir déplacer le curseur n'importe où dans le tampon, nous utilisons donc

:se ve=all|...

et nous enchaînons cela avec une autre commande ex en utilisant |

Nous devons obtenir la longueur de la plus longue ligne en entrée. Cela peut être fait avec la commande shell wc -L.

       ...|%!wc -L

Cela écrase le tampon actuel (contenant l'entrée) avec le résultat de wc -L. Il donne une sortie de quelque chose comme:

            42

et le curseur atterrit sur l' 4entrée 42. Ensuite, nous copions ce nombre en utilisant y$: le texte de la position du curseur jusqu'à la fin de la ligne. Cela stocke commodément ce numéro dans le registre 0. Mais plus là-dessus plus tard. L'entrée est remplacée par ce numéro, donc pour revenir en arrière, nous undo.

Supposons maintenant que l'entrée ressemble un peu à ceci:

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

nous devons déplacer les accolades }de la fin du tampon juste après l' printlninstruction.

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

Si l'expression régulière ne peut pas être trouvée, une erreur de rupture se produit et éclate de la récursivité causée par ò.

Vient maintenant la partie principale de ce programme, déplacez tous les accolades et les points-virgules et alignez-les comme indiqué dans la question.

ò                  " 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 `ò`

Encore une fois, cette récursivité sera arrêtée par une erreur de rupture provoquée lorsque l'expression régulière n'a pas pu être trouvée dans le tampon.

Modifications

  • Utilisé Dau lieu de d$(je ne sais même pas pourquoi j'ai raté ça en premier lieu)
  • Compressé [^(dans l'expression régulière)<84>
  • Correction du défaut à l'aide de \zs(compression dans <93>) et en retirant le $en$xk$pò
  • Suppression de la nouvelle ligne inutile
  • Regex modifié pour rendre la soumission conforme aux nouvelles règles et gain de 2 octets
Kritixi Lithos
la source
Vous pouvez enregistrer un octet si vous joignez vos commandes ex ensemble:se ve=all|%!wc -L
DJMcMayhem
@DJMcMayhem Thanks, TIL
Kritixi Lithos
4

Ruby, 100 114 108 octets

Lit le nom du fichier comme argument de ligne de commande. Si aucun nom de fichier n'est fourni, il lira à partir de STDIN. Ne gère pas les onglets.

Essayez-le en ligne!

f=$<.read.gsub(/[\s;{}]*$/){$&.tr"
 ",''}
$><<f.gsub(/(.*?)([;{}]+)$/){$1.ljust(f.lines.map(&:size).max)+$2}
Encre de valeur
la source
Ne fonctionne pas avec cela
Pavel
@ Pavel merci de m'avoir prévenu. Les deux problèmes que j'ai vus après avoir inséré le fichier dans le fichier étaient A. une catchinstruction en retrait et B. un point-virgule trop en retrait, sur la plus longue ligne du code. Je pense que je sais juste la chose dont j'ai besoin pour le réparer, donnez-moi une seconde. (De plus, j'ai mis à jour les spécifications pour mentionner qu'il ne peut pas gérer les onglets et que votre fichier a des onglets.)
Value Ink
At-il des onglets? Je viens de faire une recherche et un remplacement dessus, et il a fait 0 changement.
Pavel
3

Perl , 90 octets

88 octets de code + -p0drapeaux.

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

Essayez-le en ligne!

Explications courtes:
\@a[y///c]for/.*/g; compte la longueur de la ligne la plus longue: pour chaque ligne, il définit l'élément à index y///c(ie la taille de la ligne) du tableau @a. À la fin, l'indice maximum de @a(c'est-à-dire la taille de @a) est la taille de la ligne la plus longue.
s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gmeplace les {};caractères à la fin des lignes.
1while s/ *\n *([{};]+)$/$1/mfait met les accolades sur les lignes vides sur la ligne ci-dessus.

Merci à @primo à qui j'ai "volé" partiellement le début de mon code d' ici pour compter la longueur de la plus longue ligne.

Dada
la source
Les accolades doivent remonter à la ligne ci-dessus s'il n'y a que des espaces devant eux, cette réponse ne fait pas cela
Kritixi Lithos
@KritixiLithos en effet, cela semblait bien avant que le défi ne soit reformulé (d'après ce que j'ai compris à la fois des défis et des commentaires). Quoi qu'il en soit, c'est corrigé maintenant (j'avais déjà le code écrit dans ma réponse au cas où vous ne l'auriez pas remarqué).
Dada
1

Python 2: 228 octets

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
Chris H
la source
Horriblement long. J'aurais probablement dû ;{}repartir de zéro lorsque je me suis rendu compte que seul devait continuer à la fin des lignes précédentes.
Chris H
1

empilé , 133 octets

'\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

Essayez-le en ligne! Je pourrais être en train de trop réfléchir à cela ... mais quoi. Je le reverrai demain. Quelques bons conseils:

  1. "!peut souvent être utilisé à la place de map, en enregistrant un octet ou deux, selon que le prochain jeton commence par un mot. Cependant, il ne peut être utilisé que lorsque chaque atome du tableau souhaite être mappé. C'est semblable à une carte profonde.
  2. Un espace n'est pas nécessaire après une fonction entre guillemets, $MAXmapest donc équivalent à $MAX map, qui à son tour est équivalent à [MAX] map. (Mappe chaque tableau à son élément maximal.)
Conor O'Brien
la source
1

JavaScript (proposition ES), 139 121 octets

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>

Nécessite Firefox 48 / Chrome 57 / Opera 44 / Safari 10 / Edge 15 pour padEnd. Edit: 18 octets enregistrés grâce à @ValueInk.

Neil
la source
Avez-vous vraiment besoin de courir s.replace(r,`$1`)lors du calcul de la longueur de ligne? N'importe quelle quantité de remplissage droit devrait être suffisante, donc compter la longueur de la ligne avec les points-virgules et les crochets devrait être bien.
Value Ink
0

PHP, 201 194 185 172 172 167 octets

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

prend l'entrée du fichier f; suppose des sauts de ligne à un octet et aucun onglet; conserve les lignes vides.

  • +2 octets pour délimiter les espaces: ajouter +1au deuxième str_padparamètre.
  • -6 octets s'il était garanti qu'aucune ligne de code ne se compose d'un seul 0:
    supprimez ""<et remplacez ""==par !.

panne

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
;
Titus
la source
Êtes-vous sûr de devoir échapper aux {}accolades dans l'expression régulière?
Kritixi Lithos
@KritixiLithos Probablement pas; mais j'ai quand même trouvé une approche plus courte.
Titus
0

Java 8, 312 305 octets

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

Explication:

Essayez-le ici.

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
Kevin Cruijssen
la source
Hé, je commente cette réponse, mais elle s'applique à beaucoup d'autres. Nous avons actuellement besoin de paramètres lambda pour avoir des types en Java .
Nathan Merrill
1
@NathanMerrill avait peur que le jour du jugement vienne. Jk, je vais l'ajouter à partir de maintenant et j'ai édité ma réponse, merci. ;)
Kevin Cruijssen