"Stair-ify" une chaîne

12

Vous devez écrire un programme ou une fonction qui crée une chaîne "en escalier". Voici comment vous "escaladez" une chaîne:

Pour chaque caractère de la chaîne:

  • Si le caractère est une voyelle en majuscule ou en minuscule, n'incluant pas «y», sortez-la puis déplacez le reste de la chaîne vers le haut d' une colonne.

  • Si le caractère est un espace ou une tabulation, sortez-le puis déplacez le reste de la chaîne dans une colonne.

  • Si le caractère n'est ni l'un ni l'autre, sortez-le normalement.

IO peut être dans n'importe quel format raisonnable. L'entrée ne contiendra aucune nouvelle ligne. Si vous le souhaitez, vous pouvez supprimer tout espace de fin.

Si vous choisissez de renvoyer la chaîne, plutôt que de l'imprimer, veuillez également inclure un programme court qui imprimera votre chaîne afin qu'elle puisse être visualisée. Ce n'est pas obligatoire, et cela n'ira pas vers votre nombre d'octets. C'est juste une commodité pour les utilisateurs qui ne comprennent pas le golf ou les esolangs (comme moi) pour pouvoir vérifier la sortie ou bricoler avec le code.

Exemple d'E / S:

Sortie pour "bcdef ghijkl":

    f    jkl
bcde  ghi

Sortie pour "Programmation de puzzles et de code-golf":

                               lf
                            -Go
                  s  nd   de   
         ng   zzle  A   Co       
      mmi   Pu                 
   gra        
Pro

Sortie pour "Abcdefghijklmnopqrstuvwxyz":

                     vwxyz
               pqrstu
         jklmno
     fghi          
 bcde             
A        

Comme d'habitude, c'est le code-golf, donc la réponse la plus courte en octets l'emporte.

James
la source
Pouvons-nous supprimer tout espace blanc de début / fin?
orlp
@orlp Comme cela ne changera pas du tout la représentation visuelle, je ne vois pas pourquoi.
James
Si nous choisissons de renvoyer la chaîne, le programme pour l'imprimer est-il inclus dans le nombre d'octets?
@PeterPeter Voir ma dernière modification.
James

Réponses:

2

MATL , 38 37 octets

Oj33<G13Y2m-IL)hYstX<-"@Z"GX@)h]Xh!c!

Essayez-le en ligne!

Explication

Pour chaque caractère, le code calcule sa position verticale, mesurée par le haut (0 est le plus élevé). Il construit ensuite la chaîne de sortie transposée: chaque caractère est sur une ligne avec autant d'espaces de tête que sa position verticale l'indique. Ensuite, toutes les lignes sont contaténées dans un tableau de caractères 2D, qui est finalement transposé et affiché.

O       % push a 0
j       % input a string
33<     % array of the same length as the input that contains true for spaces or tabs
G       % push input again
11Y2    % string 'aeiouAEIOU'
m       % array of the same length as the input that contains true for vowels
-       % subtract
IL)     % remove last element
h       % prepend the 0 that is at the bottom of the stack
Ys      % cumulative sum. This gives the vertical position of each char
tX<     % duplicate. Compute minimum
-       % subtract. This sets minimum vertical position to 0
"       % for each vertical position
  @     %   push vertical position of current character
  Z"    %   string with that many spaces
  G     %   push input again
  X@)   %   get the character corresponding to the current iteration index
  h     %   concatenate horizontally
]       % end for each
Xh      % concatenate all lines into a row cell array
!       % transpose into a column cell array
c       % convert into 2D array, padding with spaces if needed
!       % transpose. Implicitly display
Luis Mendo
la source
7

Pyth, 63 octets

V_Q aY?}rN0"aeiou"=hZ?}N"     "=tZZ;Jh.mbYKh.MZYjC.b++*d+JNY*dK_YQ
                         ^^^^^
                         |||||
                         |tabs
                        space

Les espaces au milieu sont en fait un caractère de tabulation unique, mais StackExchange le rend comme quatre espaces.

Essayez-le en ligne!

Leaky Nun
la source
Je compte 64 octets.
Conor O'Brien
En raison de la tabulation affichée en quatre espaces ici.
Leaky Nun
Certainement 64 octets. mothereff.in/…
Non, @KennyLau signifiait que le caractère de tabulation devait être placé à la place des quatre espaces. Regardez le lien essayer en ligne.
Mama Fun Roll
@MamaFunRoll StackExchange remplace automatiquement les tabulations par 4 espaces.
orlp
4

Python 2, 141 137 octets

def S(s,l=[0]):
 for c in s:l+=[l[-1]-(c in"aeiouAEIOU")+(c<"!")]
 for h in sorted(set(l)):print"".join([" ",c][i==h]for i,c in zip(l,s))
orlp
la source
Celui-ci ne semble pas descendre sur les espaces
Score_Under
@Score_Under Cela fonctionne très bien sur ma machine. Testez-vous sur Python 2?
orlp
Ça marche. Je ne sais pas trop comment mais j'ai dû faire une erreur en le collant la première fois.
Score_Under
3

JavaScript (Firefox 30-57), 151 octets

s=>[...s].map((c,i)=>r[c<'!'?n++:/[AEIOU]/i.test(c)?n--:n][i]=c,n=s.length,r=[for(_ of s+s)[]])&&[for(a of r)if(s=[for(c of a)c||' '].join``)s].join`\n`

\nreprésente le caractère de nouvelle ligne littéral.

Neil
la source
2
Avec les chaînes de modèle, vous pouvez mettre une nouvelle ligne dans une chaîne, vous pouvez donc la remplacer /npar ``
Utilisateur générique
1
@GenericUser Le nombre d'octets est ajusté en supposant que vous l'avez déjà fait; Je ne voulais tout simplement pas utiliser une nouvelle ligne littérale dans mon message.
Neil
1

C, 180 octets

char s[99];i,j,p[99],m,M;main(c){for(gets(s);c=s[i];j+=strchr("aeiou",c|32)!=0,j-=c<33,m>j?m=j:M<j?M=j:0)p[i++]=j;for(;m<=M;putchar(10),M--)for(i=0;c=s[i];)putchar(M^p[i++]?32:c);}

Non golfé:

char s[99];i,j,p[99],m,M;
main(c){for(gets(s);c=s[i];
j+=strchr("aeiou",c|32)!=0,j-=c<33,m>j?m=j:M<j?M=j:0)
  //move current height up or down, adjust minimum and maximum height
p[i++]=j;  //record height of character
for(;m<=M;putchar(10),M--)  //from maximum to minimum height
for(i=0;c=s[i];)putchar(M^p[i++]?32:c);}  //print only characters on this height
mIllIbyte
la source
1

Perl, 110 octets (script de 108 octets + drapeaux de 2 octets)

$h=0;map{$h{$h}.=' 'x($p-$p{$h}).$_;$p{$h}=++$p;$h+=/[aeiou]/i-/\s/}split//;print for@h{sort{$b<=>$a}keys%h}

Exécutez avec perl -nl script.pl, l'entrée est sur stdin, la sortie est sur stdout.

Désobfusqué

J'ai renommé les variables de manière plus sensible, rendu le code use strictet use warningsconforme, et rendu explicite une grande partie de la magie de Perl automatiquement.

Ceci est simplement exécuté comme perl script.pl, car il reproduit les effets des -nlindicateurs à l'intérieur du script.

use strict;
use warnings;
use English;

# The effect of -l in perl's flags
$INPUT_RECORD_SEPARATOR = "\n";
$OUTPUT_RECORD_SEPARATOR = "\n";

# These variables are magicked into existence
our $column = 0;
our %line_col = ();
our %lines = ();

# The implicit while-loop is the effect of -n in perl's flags
while (defined(my $line = <>)) {
    # The "chomp" is part of perl's -l flag too
    chomp $line;

    # Here starts the actual script. "$h=0" turns into...
    our $height = 0;
    for my $char (split '', $line) {
        if (!exists $line_col{$height}) {
            # Setting it to 0 is a bit of a white lie, but it might as well be 0.
            # Perl would otherwise have called the value "undef", which is
            # similar to 0 in numeric contexts.
            $line_col{$height} = 0;
        }

        $lines{$height} .= ' ' x ($column - $line_col{$height});
        $lines{$height} .= $char;

        $column++;
        $line_col{$height} = $column;

        $height++ if $char =~ /[aeiou]/i;
        $height-- if $char =~ /\s/;
    }

    # Sort line heights numerically descending (so the greatest is printed first)
    my @heights = sort { $b<=>$a } keys %lines;

    for my $line (@lines{ @heights }) {
        print $line;
    }
}
Score_Under
la source
1

JavaScript (ES6), 133

s=>s.replace(/[^aeiou ]*(.?)/gi,(z,x,c)=>(q=o[r]||'',o[r]=q+=' '.repeat(c-q.length)+z,x<'!'?++r:r?--r:o=[,...o]),o=[],r=0)&&o.join`
`

Moins golfé

s=>(
  s.replace(/[^aeiou ]*(.?)/gi,(z,x,c)=>(
    q = o[r] || '',
    o[r] = q += ' '.repeat(c - q.length) + z,
    x == ' ' ? ++r : r ? --r : o = [,...o]
  ), o = [], r = 0),
  o.join`\n`
)

Tester

f=s=>s.replace(/[^aeiou ]*(.?)/gi,(z,x,c)=>(q=o[r]||'',o[r]=q+=' '.repeat(c-q.length)+z,x<'!'?++r:r?--r:o=[,...o]),o=[],r=0)&&o.join`
`

function test() {
  i=I.value
  O.textContent=f(i)
}

test()
#I { width:90%}
<input id=I oninput='test()' value='Programming Puzzles And Code-Golf'>
<pre id=O>

edc65
la source
0

Haskell (dans le terminal ANSI), 75 octets

("\27[2J"++).(h=<<)
h ' '="\27[B "
h c|elem c"aeiouAEIOU"=c:"\27[A"
h c=[c]

Exemple d'utilisation: putStr $ ("\27[2J"++).(h=<<) $ "bcdef ghijkl"

Cela utilise des codes d'échappement ANSI pour déplacer le curseur de haut en bas.

nimi
la source
0

C, 173 160 156 155 155 octets

Edit: idée empruntée d'utiliser strchr de @mIllIbyte pour raser 13 octets

Edit2: rationalisé les comparaisons min / max, -4 octets

Edit3: c peut avoir n'importe quelle valeur pour commencer -> dans main (c) à la place, -1 octet

Edit4: Ajout d'ungolf / explication

p,l,j,m;main(c){char b[99],*s=gets(b);for(;j<m+2;p?putchar(c?l?32:c:10):l<j?j=l:l>m?m=l:0,l-=c?(c&=223)&&c-9?!!strchr("AEIOU",c):-1:(p=s=b,l+j++))c=*s++;}

Non golfé et expliqué:

/* declare and initialize these variables to int and 0 */
p,l,j,m;

/* declares main, but also int c */
main(c)
{

  /* we can handle strings of length 98 (+1 for string-terminating 0) */
  /* we declare and initialize s to point to the beginning of the input
     string for the first pass through the for loop */
  char b[99],*s=gets(b);

  /* the for-loop actually contains nested loops, where the inner loops
     behave differently depending on the outer loop parameter p as follows:
     p attains the values false (0) and true (non-null pointer), in this order.

     p == false:
      the inner loop has the parameter s and passes through all the characters
      in the string until the string is exhausted (*s == 0). l is the vertical
      position of the current character relative to the first character
      (l = 0), smaller number = higher up. The purpose here is simply to find
      the range of vertical positions [j, m] present in the string. The
      commands in execution order are:

      -- loop over s --

      // test does not do anything since j <= m by design
      1. j < m+2

      // puts current char in c and increments string counter
      2. c = *s++          

      // ensures that j (m) equals the min (max) of the vertical positions (l)
         encountered so far. At first step j = l = m = 0.
      3. l<j?j=l:l>m?m=l:0 

      // c != 0, this updates the vertical position for the next character
      // c = SPC or C = TAB -> lower (l increases by 1)
      // c = "aeiouAEIOU" -> higher (l decreases by 1)
      4a. l-=(c&=223)&&c-9?!!strchr("AEIOU",c):-1

      -- loop over s ends --

      // c == 0, this resets the string pointer s and puts p = true, and 
      //         thereby initiates the next phase of the algorithm
      //         see rest of the explanation at p == true)
      4b. p=s=b

    p == true:
     now there are two inner loops. The outer of these has the parameter j,
     which ranges from the smallest vertical position+1 (the value of j after
     the p == false pass) to the largest vertical position+1 (m+2 after the
     p == true pass). The innermost loop has the parameter s and passes through
     all characters in the string until the string is exhausted (*s == 0) just
     as in the p == false inner loop. Here l is now the vertical position
     relative to the current position j-1, so that l == 0 when a character is
     at the current level. Such characters are printed as is, whereas
     characters at other levels are replaced by space. The end-of-string
     marker 0 outputs a newline. The commands in execution order are:

      -- loop over j --

      // at first step increments j to point to be one more than the
      // current vertical position. At other steps moves the current position
      // (j-1) one vertical position downwards. Also, at all steps, this
      // biases the vertical position counter l to be zero at the current
      // vertical position (j-1)
      1. l=-j++

      // compare j to stopping criteria, exit if j > m+1
      2. j < m+2

       -- loop over s --

       // puts current char in c and increments string counter
       3. c = *s++          

       // outputs character as follows:
       // c == 0 (end of string), output newline
       // c != 0 (middle of string)
       //  l == 0 (character at current vertcial position), output c
       //  l != 0 (character not at current vertical position), output space
       4. putchar(c?l?32:c:10)

       // c != 0, this updates the vertical position for the next character
       // c = SPC or C = TAB -> lower (l increases by 1)
       // c = "aeiouAEIOU" -> higher (l decreases by 1)
       5a. l-=(c&=223)&&c-9?!!strchr("AEIOU",c):-1

       -- loop over s ends --

      // c == 0, this resets the string pointer s for next loop over s
      //         algorithm (see rest of the explanation at p == true)
      5b. p=s=b

     -- loop over j ends --
  */

  for(;
      j<m+2;
      p?putchar(c?l?32:c:10):
    l<j?j=l:l>m?m=l:0,
      l-=c?(c&=223)&&c-9?!!strchr("AEIOU",c):-1:
       (p=s=b,l+j++))
    c=*s++;
}
Zunga
la source