Dessiner mes slash


60

En tant que programmeur, vous avez probablement entendu parler de barres obliques et de barres obliques inversées. Mais avez-vous entendu parler de slashs? C'est à ce moment-là que vous prenez une série de barres obliques, connectez leurs extrémités et dessinez-les en descendant.

Pour le défi d'aujourd'hui, vous devez écrire un programme ou une fonction qui prend une chaîne composée uniquement de barres obliques et qui les affiche toutes en une ligne. Ce sera beaucoup plus clair si vous voyez un exemple. Étant donné la chaîne \\\//\/\\, vous devriez générer:

\
 \
  \
  /
 /
 \
 /
 \
  \

Voici quelques clarifications:

  • Il doit y avoir une barre oblique par ligne.

  • La première ligne aura 0 espaces de début.

  • Pour chaque paire de barres obliques:

    • S'ils sont différents les uns des autres, ils seront dessinés dans la même colonne. Par exemple, \/donnera:

      \
      /
      
    • S'ils sont identiques, le caractère inférieur est orienté dans la direction indiquée , c'est-à-dire qu'il se déplace vers la droite pour une barre oblique inverse et vers la gauche pour une barre oblique. Donc \\//va donner

      \
       \
       /
      /
      
  • Chaque ligne peut avoir des espaces de fin supplémentaires, à condition que cela ne modifie pas l'apparence visuelle de la sortie. Il est également possible d’acquérir jusqu’à une nouvelle ligne précédente et suivante. Les espaces supplémentaires ne sont pas autorisés !

Afin de garder cela plus simple, vous pouvez supposer que la chaîne ne contiendra jamais trop de barres obliques. En d'autres termes, aucun préfixe de l'entrée ne contiendra plus de barres obliques que de barres obliques inverses. Une entrée telle que \\////ou //ne sera jamais donnée. Cela signifie également que chaque entrée commencera par une barre oblique inverse.

Si votre entrée est considérée comme un littéral de chaîne, vous pouvez échapper les barres obliques inverses si cela est nécessaire. En outre, vous ne devrez jamais gérer une entrée vide ou contenant des caractères autres qu'une barre oblique.

Vous pouvez sortir par n'importe quel format raisonnable .

Comme d’habitude, il s’agit d’un défi de . Essayez donc de trouver la solution la plus courte possible, même si vous choisissez une langue qui est assez difficile. Des points bonus pour expliquer toutes les techniques intéressantes que vous utilisiez pour enlever des octets!

Exemples

#Input
\\\\\\\\\\\

#Output
\
 \
  \
   \
    \
     \
      \
       \
        \
         \
          \

#Input
\\\//\\/\//\\///

#Output
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/


#Input
\/\/\/

#Output
\
/
\
/
\
/

9
Les barres obliques inverses donnent lieu à une quantité dérangeante de
fu

Réponses:


20

GNU Sed, 20

s|\\|&^L|g
s|/|^H/^L^H|g

Notez que ^Let ^Hsont des caractères littéraux d’alimentation et de retour arrière (0x12 et 0x8).

Cette réponse fonctionne en déplaçant le curseur en utilisant des caractères de retour arrière et de saut de page. Les barres obliques / barres obliques inverses ne sont pas complétées par des espaces - Une incertitude à ce sujet disqualifie cette réponse. Cela ne fonctionne pas dans TIO, mais cela a l'air bien sous les terminaux courants tels que xtermet gnome-terminal.

Recréez ce script sed comme suit:

base64 -d <<< c3xcXHwmDHxnCnN8L3wILwwIfGc= > downslash.sed

Exécutez-le comme suit:

$ echo '\\\//\/\\' | sed -f downslash.sed
\ 
 \ 
  \ 
  /
 /
 \ 
 /
 \ 
  \ 

$ 

Explication:

s|\\|&^L|g     # move cursor down after every "\"
s|/|^H/^L^H|g  # move cursor left before every "/", then after, down and left again

14

Charbon de bois , 13 12 11 octets

FS¿⁼ι/↓¶/↘ι

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Soutient extra //s. Explication:

 S              Input string
F               Loop over each character
  ¿             If
    ι           Current character
   ⁼            Equals
     /          Literal /
      ↓¶        Move left
      ↓ /       Print a / downwards
         ↘ι     Else it's a \ so print that down and right

Je pense que ↓¶= "Déplacer à gauche" dans la description n'est pas correct.
Jonathan Allan

@JonathanAllan C'est vrai (nouvelle ligne imprimée vers le bas = déplacer vers la gauche), bien qu'il serait probablement plus clair de dire "imprimer \n/vers le bas"
ASCII uniquement

Je n'ai pas dit print \n/ downparce que j'estimais qu'il était plus utile de décrire l'effet du code plutôt que sa traduction littérale.
Neil

1
(Langue dans la joue: Décrire l'effet = MyCode - Do the spec). Je comprends maintenant si l’effet est de bouger à gauche; Cela peut valoir la peine de dire "Déplacer à gauche (en imprimant une nouvelle ligne avec une direction d’impression vers le bas)".
Jonathan Allan

Le plus concis et explicite de tous!
J4hangir


10

/// , 119 octets

/// n'a pas de commande d'entrée, l'entrée doit donc être intégrée au programme. Pour celui-ci, la chaîne d'entrée est simplement ajoutée, sans échappement nécessaire.

/=/\/\///M/
|%%=N/%|||=C/BA=\/\\/\/C\\=C\\/CbC=B\A\=CfC=AB=/A/%Mxy=B/|z%N|x|y% %N%x|y%%% |fzN%M%b|zN|M|%
=|/AB\\=%/|=AC

Comment ça fonctionne

  • Dans ce qui suit, une entrée de \\/\//sera ajoutée au programme pour démonstration.
  • est utilisé pour représenter les nouvelles lignes dans le code en ligne.

Les abréviations

Le début /=/\/\///M/␤|%%=N/%|||=C/BA=du programme contient des substitutions aux abréviations de golf.

  • =se développe vers //, Mvers ␤|%%, Nvers %|||et Cvers BA.
  • Après cela, le programme actuel devient

    /\/\\/\/BA\\//BA\\/BAbBA//B\A\//BAfBA//AB///A/%
    |%%xy//B/|z%%||||x|y% %%|||%x|y%%% |fz%|||%
    |%%%b|z%||||
    |%%|%
    //|/AB\\//%/|//ABA\\/\//
    

Recodage des entrées

L'étape suivante transforme la chaîne d'entrée ajoutée en une forme plus utilisable. Comme il est entièrement composé de deux caractères de commande ///, cela évite de modifier le programme de base.

  • La première substitution substantielle /\/\\/\/BA\\/, remplace la chaîne /\par /BA\.
    • Le programme de base ne contient pas /\à ce moment, donc cette substitution ne l'affecte pas.
    • Cependant, cela divise la chaîne d’entrée ajoutée en séquences de \s suivies de séquences de /s, qui, combinées ABAau bout du programme de base, permettent de le parcourir avec les substitutions suivantes.
    • En incluant le ABApréfixe avant, l'exemple de chaîne d'entrée devient ABA\\/BA\//.
  • La substitution suivante /BA\\/BAbBA/, remplace BA\par BAbBA.
    • Etant donné que les substitutions /// sont répétées jusqu'à ce qu'elles ne correspondent plus, cela effectue une itération sur tous les \s de la chaîne d'entrée, qui devient désormais préfixe.ABAbBAbBA/BAbBA//
  • De même, les /B\A\//BAfBA/modifications apportées BA/à BAfBA, itérant à travers le par /.
    • La fuite \dans cette substitution est nécessaire car sinon elle serait mutilée par la précédente.
    • L'entrée est maintenant devenue ABAbBAbBAfBABAbBAfBAfBA.
  • Next /AB//supprime certaines parties superflues de l'encodage, le transformant en AbBAbBAfBAbBAfBAfBA.
    • Cela supprime également ABde la /|/AB\\/substitution plus tard dans le programme, ce qui était nécessaire pour la protéger de ce qui précède la /\manipulation.
    • À ce stade, chaque \chaîne d'entrée d'origine est devenue AbBet chaque chose /est devenue AfB. ( bet fse tenir pour aller et retour.) Il y a un vagabond Aà la fin.
  • Les deux substitutions suivantes remplacent tous les As et Bs par des fragments de programme à exécuter dans la dernière étape. Dans les chaînes de remplacement, %s et |s codent ce qui deviendra respectivement /s et \s. Cela a deux avantages:
    • Contrairement à /et \, les %s et |s n'ont pas besoin de s'échapper pour être copiés.
    • Les chaînes de remplacement évitent de contenir la sous-chaîne /\, qui aurait autrement été endommagée par les manipulations précédentes.
  • Après cela, la substitution /|/\\/(anciennement /|/AB\\/) décode maintenant le |s, après quoi le suivant /%/|//est devenu /%/\//et décode le %s.

Structure du programme au stade final

À ce stade, le programme de base a exécuté toutes ses substitutions et il ne reste que l'encodage par programme de la chaîne d'entrée.

  • Chaque caractère saisi est devenu un sous-programme

    /
    \//xy*\z//\\\\x\y/ //\\\/x\y/// \fz/\\\/
    \///b\z/\\\\
    \//\/
    

    (nouvelle ligne), où *représente soit fun original /, soit bun original \.

  • Il existe également une commande de substitution incomplète /␤\//xyà la fin du programme, qui n'aura d'effet que sur la nécessité de fournir une /substitution nécessaire au sous-programme précédent.

Sous-chaîne partagée

Avant le début de l'itération finale à travers les sous-programmes, une sous-chaîne traverse la limite après le sous-programme de chaque caractère du formulaire \/␤/.

  • Ces sous-chaînes sont utilisées en tant qu'état global partagé. Toutes les substitutions restantes du programme les manipuleront de manière identique et en parallèle, de telle sorte qu'à la fin du sous-programme de chaque caractère saisi, sa copie de cette sous-chaîne partagée (à l'exception de la finale /, qui ancre les substitutions) sera exécutée pour imprimer la ligne correspondante. personnage.
  • La version initiale de la sous-chaîne représente l’impression d’une ligne contenant juste /, qui est la "ligne précédente" imaginaire appropriée pour imprimer le premier caractère saisi au début de sa ligne.
  • En général, pendant les étapes d'impression, la sous-chaîne partagée est composée d'un nombre d'espaces, \\ou d' \/une nouvelle ligne et d'un texte suivant /.

Exécuter un sous-programme de personnage

Plusieurs des substitutions suivantes contiennent des éléments supplémentaires à l' \intérieur pour les empêcher d'être appariés et mutilés (y compris d'autres copies dans d'autres sous-programmes). La réalisation de c'est aussi la raison pour laquelle les deux xet ysont nécessaires.

  • La première substitution dans un sous-programme de caractères, /␤\//xyf\z/ou /␤\//xyb\z/, entraîne la ␤/fin de la sous-chaîne partagée xyfzou xybz, immédiatement après le \/ou \\.
  • La substitution /\\\\x\y/ /remplace \\xypar un espace, et la substitution /\\\/x\y//remplace \/xypar rien.
    • Ils s'appliquent lorsque le caractère saisi précédemment imprimé était respectivement un \ou /.
    • La sous-chaîne partagée contient maintenant le nombre approprié d'espaces pour imprimer un \suivant, suivi de fzou bz.
  • La substitution / \fz/\\\/␤\//remplace ​ fzpar \/␤/et /b\z/\\\\␤\//remplace bzpar \\␤/.
    • Ils s'appliquent lorsque le caractère d'entrée actuel est /ou \, respectivement.
    • Le premier mange un espace supplémentaire pour placer /correctement.
      • Si cet espace est manquant (c’est-à-dire que l’entrée enfreint la condition de préfixe), les substitutions suivantes sont mal interprétées, générant beaucoup de courrier indésirable et touchant généralement ///une boucle qui est une boucle infinie.
    • Chacun ajoute la commande correcte pour imprimer son propre caractère et rétablit l'original ␤/à la fin de la sous-chaîne partagée.
  • Le sous-programme de caractères a maintenant atteint sa copie de la sous-chaîne partagée, qui est prête à imprimer sa ligne.

Une fois que le dernier sous-programme a été exécuté, il ne reste que le programme /␤\//xy. Comme il s’agit d’une substitution incomplète avec une finale manquante /, le programme la saute et s’arrête normalement.


1
Le bon langage pour le travail! Lol
DJMcMayhem

6

Gelée , 14 octets

=”\ðḤ’+\_⁸⁶ẋżY

Un programme complet imprimant le résultat.

Essayez-le en ligne!

Comment?

=”\ðḤ’+\_⁸⁶ẋżY - Link: list of characters, s    e.g. "\\\//\\/"
 ”\            - literal '\'                         '\'
=              - equal? (call this e)                [1, 1, 1, 0, 0, 1, 1, 0]
   ð           - new dyadic chain f(e, s)
    Ḥ          - double                              [2, 2, 2, 0, 0, 2, 2, 0]
     ’         - decrement                           [1, 1, 1,-1,-1, 1, 1,-1]
      +\       - cumulative reduce with addition     [1, 2, 3, 2, 1, 2, 3, 2]
         ⁸     - chain's left argument, e            [1, 1, 1, 0, 0, 1, 1, 0]
        _      - subtract (# of leading spaces)      [0, 1, 2, 2, 1, 1, 2, 2]
          ⁶    - literal ' '                         ''
           ẋ   - repeat                              [""," ","  "," "," "," ","  ","  "]
            ż  - zip with s                          [["",'\'],[" ",'\'],["  ",'\'],["  ",'/'],[" ",'/'],[" ",'\'],["  ",'\'],["  ",'/']]
             Y - join with newlines                  ["",'\','\n'," ",'\','\n',"  ",'\','\n',"  ",'/','\n'," ",'/','\n'," ",'\','\n',"  ",'\','\n',"  ",'/']
               - implicit print - this smashes the lists (shown as "..." above) and the characters (shown as '...' above) together.



5

JavaScript (ES8), 66 59 63 octets

7 octets enregistrés grâce à Justin Mariner
+4 octets à corriger /\\/\\/(remarqué par Neil )

f=([a,...z],b=a<'0')=>a?a.padStart(b+=k=a>'/')+`
`+f(z,b-!k):''

Essayez-le en ligne!


5

MATL , 23 19 18 octets

1 octet sur grâce à @Sanchises

fGqoEq1yd~h*YsGZ?c

L'entrée est une chaîne entre guillemets simples.

Essayez-le en ligne! Ou vérifiez les cas de test: 1 , 2 , 3 .

Explication

Considérez l'entrée '\\\//\/\\'comme un exemple.

f      % Implicit input. Array of indices of nonzeros. Since all chars in the input
       % have nonzero code point, this gives [1 2 ... n] where n is input length
       % STACK: [1 2 3 4 5 6 7 8 9]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], '\\\//\/\\'
qo     % Subtract 1 from (the code-point) of each char and then compute modulo 2.
       % This transforms '\' into 1 and '/' into 0
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 0 1 0 1 1]
Eq     % Double, subtract 1. This transforms 0 into -1
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1]
1y     % Push 1 and duplicate from below
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 1 -1 -1 1 -1 1 1]
d~     % Consecutive differences, logical negation: gives 1 if consecutive entries
       % are equal, 0 otherwise
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], 1, [1 1 0 1 0 0 0 1]
h      % Horizontally concatenate
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 -1 -1 1 -1 1 1], [1 1 1 0 1 0 0 0 1]
*      % Element-wise multiplication
       % STACK: [1 2 3 4 5 6 7 8 9], [1 1 1 0 -1 0 0 0 1]
Ys     % Cumulative sum
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3]
G      % Push input again
       % STACK: [1 2 3 4 5 6 7 8 9], [1 2 3 3 2 2 2 2 3], '\\\//\/\\'
Z?     % Build sparse matrix with those row indices, column indices, and values
       % STACK: [92  0  0;
                  0 92  0;
                  0  0 92;
                  0  0 47;
                  0 47  0;
                  0 92  0;
                  0 47  0;
                  0 92  0;
                  0  0 92]
c      % Convert to char. Char 0 is shown as space. Implicitly display
       % STACK: ['\  ';
                 ' \ ';
                 '  \';
                 '  /';
                 ' / ';
                 ' \ ';
                 ' / ';
                 ' \ ';
                 '  \']

Un octet par un algorithme légèrement différent pour obtenir vos index: Essayez-le en ligne!
Sanchises

@Sanchises Merci pour vos modifications très appropriées!
Luis Mendo

5

C # (.NET Core) , 74 88 82 78 77 76 + 18 octets

-1 octet grâce à Kevin Cruijssen

s=>s.Select((x,i)=>$"{x}".PadLeft((x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)))

Sort une collection de chaînes, une pour chaque ligne. Le nombre d'octets comprend également:

using System.Linq;

Essayez-le en ligne!

Explication de la réponse sur 77 octets:

s =>                              // Take input, a string
    s.Select((x, i) =>            // Replace every character with:
        $"{x}"                    //     The character as string
        .PadLeft(                 //     Pad with this many spaces:
            s.Take(i)             //         Take characters, in the input string, preceding current one
            .Sum(y =>             //         Sum them by:
                y < 92 ? -1 : 1   //             If it's a \ add 1, if / subtract 1
            )
            + (x - s[0]) / 45 + 1 //         If first slash is a / add one more space, if current slash is a \ add one more space (I got this through power of MATHS!)
                                  //         How I arrived at this function:
                                  //         + x / 48        If current slash is a \ add one more space
                                  //         - s[0] / 48 + 1 If the first slash is a / add one more space
        )
    )

3
Ça ne marche pas pour /\\/\\/.
Neil

@Neil merci de l'avoir signalé! Fixé.
Grzegorz Puławski

1
Je sais que ça fait un moment, mais vous pouvez économiser un octet en changeant s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1pour(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
Kevin Cruijssen

Un gentil @KevinCruijssen!
Grzegorz Puławski

4

05AB1E , 14 octets

ÇÈx<ηOs-W-ISú»

Essayez-le en ligne!

Explication

Ç                # convert input string to a list of ascii codes
 È               # check each for evenness
  x              # push a doubled copy
   <             # decrement
    η            # compute prefixes
     O           # sum each prefix
      s          # swap the unaltered copy of evenness to the top
       -         # subtract from the prefix-sum list
        W-       # subtract the minimum value
          IS     # push input split to a list of chars
            ú    # pad each with the number of spaces computed
             »   # join on newline

1
Ça ne marche pas pour /\\/\\/.
Neil

Ç¥.¥0<.SηOv¹Nèy<ú, sanglotant en binaire
Magic Octopus Urn

3

R , 122 121 octets

-1 octet grâce à Giuseppe

x=el(strsplit(scan(,""),""));n=seq(x);y=x>"/";for(i in n)cat(rep(" ",diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]),x[i],"\n",sep="")

Essayez-le en ligne!

Avec des espaces supplémentaires:

x = el(strsplit(scan(,""),""))
n = seq(x)
y = x>"/"
for(i in n) {
  cat(rep(" ", diffinv(y[n[-1]-1]+y[n[-1]]-1)[i]), x[i], "\n", sep="")
}

Explication: Cette réponse est basée sur l'observation que le nombre d'espaces en tête change de chaque ligne de -1, plus le nombre d'espaces /des lignes précédentes et actuelles.

Si nous avons N barres, la variable yest un vecteur de longueur N, avec 1 pour chaque position avec \, sinon 0. Par conséquent, nous calculons pour obtenir le changement du nombre d'espaces en tête par ligne y[1:(N-1)] + y[2:N] - 1. La fonction diffinvconvertit ces différences en une séquence commençant par 0. Le reste consiste simplement à assembler chaque ligne en tant que nombre requis d'espaces de fin, suivie de la barre oblique appropriée et d'un retour à la ligne.


1
hein J'ai adopté une approche assez différente pour 119 octets, ce qui me fait me demander si nous pourrions combiner nos approches. (bonne utilisation de diffinv;) Vous pouvez également définir y=x>")"pour -1 octet
Giuseppe

@ Giuseppe Vous devriez poster cela comme réponse séparée, c'est une approche assez différente. Le vôtre est un bon moyen d’éviter de faire strsplitce qui est toujours un tueur. Vous pouvez également utiliser le célèbre diffinv!
user2390246

1
Aussi, je pense que si vous mettez library(methods)dans l'en-tête (ce qui devrait être OK sans pénalité puisque ce paquetage fait partie de la base R), vous pouvez l'utiliser el. En outre, diffinvs'est avéré être aussi long que cumsum! :)
Giuseppe

Oui, je venais juste de réaliser que ça aussi, ça ne marche pas tout à fait dans ce contexte
user2390246

Eh bien, je suis venu avec une solution de contournement , mais oui, ça *Sfout les choses.
Giuseppe

3

Brain-Flak , 175 octets (174 caractères + 1 drapeau)

Courir avec un -cdrapeau.

{(({})<(())>){({}[()]<([{}])>)}{}(({}<>{}<><({}<>)((()()()()()){})>)<{({}[()]<((((()()()()){}){}){})>)}>{})<>}<>{}{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Essayez-le en ligne!

Explication

{ for each char in the input...
  (({})<(())>){({}[()]<([{}])>)}{} push 1/-1 for backslash/slash
  ((
   {}<>{}<> add the 1/-1 to a running total
   <
    ({}<>) move slash/backslash to other stack
    ((()()()()()){}) newline
   >
  )<{({}[()]<((((()()()()){}){}){})>)}>{}) spaces
  <>
}<>{} end for
reverse data order, removing one space before backslash
{({}<>)(({})(())){({}[()]<([{}]())>)}{}{<>{}<>(<{}>)}{}<>}<>

Je vote toujours au cerveau-flak. : D
DJMcMayhem

3

Ruby , 80 76 octets

-4 octets grâce à manatwork

puts"\\";$*[i=0].chars.each_cons 2{|b,c|puts" "*(b==c ?b==?/?i-=1:i+=1:i)+c}

Essayez-le en ligne!

Explication:

puts "\\"           # Output the first backslash
$*[i=0].            # Get the first argument and set i to 0
chars.              # Go through every individual character,
each_cons 2 { |b,c| # In pairs to compare easily
                    #
    puts " " *      # Decide how many padding spaces to use based on the value
                    # of i. The expression inside the parenthesis will return
                    # i but before that, it will increment/decrement i based
                    # on what the previous character was.
                        #
    ( b==c ?            # if b == c
        b==?/ ?         #   if b == "/" (Going to the left)
            i-=1        #       return decremented i
            :           #   else        (Going to the right)
            i+=1        #       return incremented i
        :               # else
        i) +            #   return i
                    #
                c   # Finally, write the second of the characters that we're
}                   # iterating through.

1
Quelle version de Ruby? 2.3.3 J'ai le paramètre autour de la demande lorsque le bloc de code suivant: .each_cons(2){…}. Dans le changement, vous pouvez enregistrer en remplaçant .each_char.chars.
manatwork

@ manatwork Ma version ruby ​​est la 2.4.1. Merci pour la suggestion sur les personnages, je ne savais pas à ce sujet.
Pazzaz

Vous pouvez enregistrer deux autres octets en vous déplaçant i+=au début de l'expression ternaire imbriquée et en la terminant par -1:1:0.
benj2240

3

Java 8, 121 118 110 109 102 octets

a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}

-7 octets grâce à la magie au niveau des bits de @ Nevay . :)

Explication:

Essayez ici.

a->{                    // Method with char-array parameter and String return-type
  String r="";          //  Return-String
  int s=0,              //  Amount of spaces
      p=0,              //  Previous characters (starting at 0)
      i;                //  Index-integer
  for(char c:a){        //  Loop over the input
    for(i=s+=p+(p=c-63)>>5;
                        //   If the current does not equals the previous character
                        //    Leave `s` the same
                        //   Else-if it's a '\':
                        //    Increase `s` by 1
                        //   Else (it's a '/'):
                        //    Decrease `s` by 1
                        //   And set the previous character to the current in the process
        i-->0;r+=" ");  //   Append `r` with `s` amount of spaces               
    r+=c+"\n";          //   Append the character + a new-line to the result
  }                     //  End of loop
  return r;             //  Return result-String
}                       // End of method

1
102 octets:a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
Nevay

@ Merci Merci. Je savais que cela pourrait être raccourci avec quelques opérations sur les bits, mais je ne pouvais pas le comprendre. Principalement parce que j'avais oublié d'essayer les effets de >>/ >>>/ <<... Je n'avais vérifié que certaines choses avec &/ |/ ~/ ^..>.
Kevin Cruijssen le

3

C (GCC), 137 134 97 octets

Essayez-le en ligne!

• 3 octets merci ATaco

• 37 octets grâce à Digital Trauma & ThePirateBay

i,d;f(char*s){char c=s[i],n=s[++i];if(c){printf("%*c%c\n",d+1,c);(c-n)?d:(c==47)?--d:++d;f(s);}}

Rien de bien plus qu'une simple fonction récursive qui prend une chaîne et affiche les barres obliques; notez que l'entrée doit d'abord échapper aux barres obliques inverses.

Usage

f("\\\\\\//\\/\\\\",0,0);

Ungolfed

Ceci est pour l’ancienne réponse, consultez le lien d’essai en ligne pour la mise à jour!

f(char *s, i, d) {
    char c=s[i], n=s[++i];
    if(!c) return;
    for(int j=0; j<d; j++) printf(" ");
    printf("%c\n",c);
    f(s, i, (c!=n)?d:(c=='/')?d-1:d+1);
}

Sortie

entrez la description de l'image ici


Vous pouvez remplacer c=='\0'par !cpour le même effet.
ATaco

Awesome merci vient de mettre à jour la solution!
Asleepace

Pouvez-vous utiliser printf("%*s%c", n, "", c)pour imprimer le caractère c avec n espaces de début?
Digital Trauma

Je suis sûr que vous pouvez économiser quelques octets en remplaçant (c!=n)avec c-net en réarrangeant les expressions ternaires. Même avec (c=='/'). En outre, vous pouvez remplacer '/'par un nombre littéral 47. Je pense que c'est 7 octets au total.



3

Retina , 47 octets

^|\\
 $&
+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3
m`^ 

Essayez-le en ligne! Le lien inclut des cas de test. Explication:

^|\\
 $&

Ajoutez un espace au début et à la fin de chaque ligne \.

+m`^( *)( /|\\)(/| \\)
$1$2¶$1$3

Considérons les deux premiers caractères de la chaîne. Si le premier est un, /le retrait doit être décrémenté; ceci est réalisé en incluant l'espace précédent dans la capture (qui existe toujours car le premier étage l'a ajouté); si le second est un, \\il doit être incrémenté; ceci est réalisé en incluant l'espace que la première étape a ajouté dans la capture. Après avoir donné le deuxième tiret correct, la scène est répétée pour les deuxième et troisième caractères, etc.

m`^ 

Supprimer le retrait supplémentaire.

J'ai écrit une version de 94 octets qui (comme ma réponse Charcoal) autorise toute combinaison de barres obliques: essayez-le en ligne! Explication:

.$
¶$.`$* $&

Faites rouler la balle en prenant la dernière barre oblique et indentez-la à la même position sur sa propre ligne.

/
 /

Préfixez les espaces à toutes les barres obliques afin qu'elles puissent être capturées.

+`^(.*)( /|\\)¶( *)( \\|/)
$1¶$3$2¶$3$4

Prenez à plusieurs reprises la dernière barre oblique de l'entrée et alignez-la sur sa propre ligne avec la barre oblique de la ligne ci-dessous.

+ms`^(?<!^[\\/].*) (?!.*^[\\/])

Supprimez tout retrait laissé.

G`.

Supprimez l'entrée maintenant vide.


2

Lua , 96 octets

c=0 for s in(...):gmatch(".")do c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end

Essayez-le en ligne!

Le plus court que j'ai pu trouver à Lua. La saisie est effectuée à partir de la ligne de commande.

Cela utilise quelques astuces:

  1. (...):gmatch(
    Cela devrait être la forme la plus courte pour obtenir une seule chaîne dans un programme Lua à partir de la ligne de commande. L' ...expression en Lua capture tout paramètre en excès dans une fonction non spécifiée dans la déclaration de fonction et est utilisé pour les variables. Puisque le corps principal d'un programme Lua est appelé comme une fonction avec les arguments de la ligne de commande comme paramètres, les arguments de la ligne de commande se retrouveront dans ....
    Les parenthèses qui l'entourent transforment l' ...expression potentiellement à valeurs multiples en une expression à valeur unique. Considérez cet exemple (quelque peu surprenant):
    function multipleReturnValues()
        return "abc", "def"
    end
    print(  multipleReturnValues()  ) --This prints: abc    def
    print( (multipleReturnValues()) ) --This prints: abc
  2. L'analyseur Lua n'a besoin d'aucun terminateur de ligne, ni même d'espacement entre les instructions, tant que les jetons des deux instructions peuvent être clairement séparés et qu'il n'existe qu'une seule interprétation du texte qui soit du code Lua valide.
  3. Abuser and/ orpour "si x alors valeur1 sinon valeur2" logique.
    L' andopérateur de Lua retourne son premier argument s'il s'agit de fausseté; sinon, il retourne son deuxième argument. L' oropérateur retourne son premier argument s'il s'agit de la vérité; sinon, le deuxième argument.
  4. pn'a pas besoin d'initialisation.
    p==sdoit toujours être faux lors de la première exécution de la boucle, quelle que soit l'entrée. Si vous ne définissez paucune valeur avant d'entrer dans la boucle (en la quittant nil), cela sera possible et vous économiserez des octets.

Quelqu'un peut-il jouer au golf (à Lua)?


J'ai pu économiser deux octets en utilisant gsub au lieu de gmatch. c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
QuertyKeyboard

Eh bien, pas que ça compte. Vous auriez pu facilement sauvé deux octets en changeant gmatch(".")de gmatch"."comme vous l'avez fait dans votre prochaine réponse.
QuertyKeyboard

@QuertyKeyboard C'est bizarre ... En fait, j'ai utilisé gsub exactement comme cela dans la première version de ce code, mais j'ai ensuite basculé sur gmatch car il s'est avéré plus court. Je ne sais pas ce que j'ai fait différemment, le fichier est malheureusement écrasé.
Jonathan S.


2

R , 119 octets

function(s)for(i in 1:nchar(s))cat(rep(" ",cumsum(c(0,!diff(S<-(utf8ToInt(s)>48)*2-1))*S)[i]),substr(s,i,i),"
",sep="")

Essayez-le en ligne!

Cela diffère quelque peu de la réponse de user2390246 . Ils parcourent chacun la chaîne en imprimant un certain nombre de caractères d'espace, puis le /\caractère approprié .

Cependant, j’évitais de scinder la chaîne, préférant remplacer les caractères par leur valeur de codage UTF-8, ce qui me permettait alors de calculer directement les nombres, ce qui ne me permettait d’économiser que quelques octets.


Je pense que votre algorithme a une erreur: TIO
user2390246

@ user2390246 Je l'ai corrigé! J'avais des parenthèses égarées, mais maintenant diffinvcela ne fonctionnera certainement pas ici.
Giuseppe


2

C # (.NET Core) , 60/65 octets

J'ai essayé la version C # plus courte

s=>{int i=0;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

comme il a été dit: "Cela signifie également que chaque entrée commencera par une barre oblique inverse." Ou un peu plus longtemps qui résolvent de commencer "/"

s=>{int i=s[0]&1;return s.Select(x=>"".PadLeft(x<92?--i:i++)+x);}

Essayez-le en ligne!


Bienvenue sur le site! :)
DJMcMayhem

2

Lua , 88 84 octets

Version améliorée (-4 octets grâce à QuertyKeyboard)

s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)

Essayez-le en ligne!

Version originale (88 octets)

Une autre tentative à Lua, cette fois avec une approche complètement différente en utilisant la manipulation de chaîne au lieu d'une variable de compteur.

s=""for c in(...):gmatch"."do s=s:gsub("\\"," "):gsub("/?$",c):gsub(" /","/")print(s)end

Ungolfed:

s = ""
for c in string.gmatch((...), ".") do --for each character in the input
  --s contains the output from the previous iteration
  s = s:gsub("\\", " ") --Replace backslash with space -> indent by 1
  s = s:gsub("/?$", c) --Remove any / at the end of the string and append c to the string
  s = s:gsub(" /", "/") --Remove a single space in front of any / -> un-indent by 1
  print(s)
end

Il y a une chose intéressante dans le code: (...):gmatch"."
cela utilise quelques bizarreries dans l'analyseur Lua. Lorsque Lua rencontre un morceau de code dans le formulaire func "string", il le convertit en func("string"). Cela permet d'écrire print "string"pour imprimer une chaîne constante et cela ne fonctionne qu'avec un seul littéral de chaîne après la fonction. Tout le reste donnera une erreur de syntaxe. Cependant, ce sucre syntaxique fonctionne également avec les appels de fonction au milieu d'une expression, et plus surprenant, il fonctionne parfaitement avec l' :appel de méthode sucre syntaxique. Donc à la fin, Lua interprétera le code comme suit:

(...):gmatch"."
-> (...):gmatch(".")
-> string.gmatch((...), ".")

Si quelqu'un peut trouver un moyen de supprimer l'un des trois appels gsub, dites-le-moi.


1
J'ai été déçu de constater que mon astuce de gsub que j'ai commentée dans votre autre réponse n'a pas très bien fonctionné pour celle-ci. En fait, il a fini par ajouter un octet. Cependant, je n'abandonnerais pas aussi facilement. D'abord, j'ai essayé de stocker gsub en tant que variable pour raccourcir le code. À ma grande surprise, mon code était exactement le même nombre d'octets - 88. Cependant, je me suis rendu compte qu'avec l'enregistrement de gsub, mon astuce gsub pouvait désormais fonctionner! Voici mon code qui a supprimé 4 octets:s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
QuertyKeyboard

@QuertyKeyboard Yup, j'ai aussi essayé de stocker gsub dans une variable avant la boucle et de l'utiliser ensuite au lieu d'écrire gsub trois fois, et j'étais tout aussi surpris de constater que cela ne faisait absolument aucune différence. Combiner les astuces "gsub au lieu de loop" et "store gsub" est vraiment génial, je n'ai pas pensé à celui-là! Merci! :)
Jonathan S.


1

Perl, 40 + 2 octets

/\//&&$.--,say($"x$.,$_),/\\/&&$.++for@F

Vous avez besoin du -Fdrapeau.


1

Perl, 34 38 + 1 octets

gérer les deux cas

s,(/)|.,$"x($1?$c&&--$c:$c++).$&.$/,ge

être couru avec -poption

s,(/)|.,$"x($1?--$c:$c++).$&.$/,ge

EDIT: le commentaire suivant ne fonctionne pas quand le premier caractère est /

s,(/)|.,$"x($1?$c--:++$c).$&.$/,ge

cependant, la sortie sera décalée d’un caractère à droite si le premier caractère est \


1
Ça ne marche pas pour /\\/\\/.
Neil

Avec la question mise à jour, votre 34solution d' origine est maintenant parfaitement valide
Ton Hospel le

1

VBA (Excel), 181 octets

Sub q()
a = Cells(1, 1)
For x = 1 To Len(a)
c = Mid(a, x, 1)
If c = "\" Then: Debug.Print b & c: b = b + " "
If c = "/" Then: b = Left(b, Len(b) - 1): Debug.Print b & c
Next
End Sub

1
Vous pouvez jouer au golf de manière significative sans changer votre algorithme en tirant parti de la nature du format automatique d'Excel VBA et de la [...]notation: je l'ai réduit à 128 octets Sub q For x=1To[Len(A1)] c=Mid([A1],x,1) If c="\"Then Debug.?b;c:b=b+" " If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c Next End Sub
Taylor Scott

Merci d'avoir joué mon scénario au golf. J'ai appris quelque chose de cela et je vais l'appliquer à l'avenir. :) Je ne savais pas que je pouvais l'utiliser pour récupérer des données directement dans les cellules. Merci encore :)
remoel



En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.