"Escadaria"

12

Você deve escrever um programa ou função que crie uma seqüência de caracteres "if-escada". Aqui está como você "escava" uma string:

Para cada caractere na sequência:

  • Se o caractere for uma vogal maiúscula ou minúscula, sem incluir 'y', faça a saída e mova o restante da string para cima de uma coluna.

  • Se o caractere for um espaço ou uma tabulação, faça a saída e mova o restante da string para baixo de uma coluna.

  • Se o caractere não for nenhum, produza-o normalmente.

O IO pode estar em qualquer formato razoável. A entrada não conterá nenhuma nova linha. Se desejar, você pode remover qualquer espaço em branco à direita.

Se você optar por retornar a sequência, em vez de imprimi-la, inclua também um programa curto que imprimirá sua sequência para que possa ser visualizada. Isso não é obrigatório, nem irá para a sua contagem de bytes. Essa é apenas uma conveniência para os usuários que não entendem golfe ou esolangs (como eu) poder verificar a saída ou mexer no código.

IO de amostra:

Saída para "bcdef ghijkl":

    f    jkl
bcde  ghi

Saída para "Programação de quebra-cabeças e código de golfe":

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

Saída para "Abcdefghijklmnopqrstuvwxyz":

                     vwxyz
               pqrstu
         jklmno
     fghi          
 bcde             
A        

Como de costume, isso é código-golfe, e a resposta mais curta em bytes vence.

James
fonte
Podemos remover qualquer espaço em branco à esquerda / à direita?
orlp
@orlp Como não muda a representação visual, não vejo por que não.
James
Se optarmos por retornar a sequência, o programa para imprimi-la está incluído na contagem de bytes?
@PeterPeter Veja minha última edição.
James

Respostas:

2

MATL , 38 37 bytes

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

Experimente online!

Explicação

Para cada caractere, o código calcula sua posição vertical, medida a partir de cima (0 é o mais alto). Em seguida, cria a cadeia de saída transposta: cada caractere está em uma linha com tantos espaços à esquerda quanto sua posição vertical indica. Todas as linhas são contatenadas em uma matriz de caracteres 2D, que é finalmente transposta e exibida.

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
fonte
7

Pitão, 63 bytes

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

Os espaços no meio são, na verdade, um único caractere de tabulação, mas o StackExchange o processa como quatro espaços.

Experimente online!

Freira Furada
fonte
Eu conto 64 bytes.
Conor O'Brien
Por causa da guia sendo mostrada como quatro espaços aqui.
Leak Nun #
Definitivamente 64 bytes. mothereff.in/...
Não, @KennyLau significava que o caractere de tabulação deveria ser colocado em vez dos quatro espaços. Veja o link Experimente online.
Mama Fun rolo
@MamaFunRoll StackExchange substitui automaticamente as guias por 4 espaços.
orlp
4

Python 2, 141 137 bytes

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
fonte
Parece que este não desce sobre os espaços
# #
@Score_Under Funciona bem na minha máquina. Você está testando no Python 2?
Orlp
Está funcionando. Não sei exatamente como, mas devo ter cometido um erro ao colar pela primeira vez.
Score_Under
3

JavaScript (Firefox 30-57), 151 bytes

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`

Onde \nrepresenta o caractere literal de nova linha.

Neil
fonte
2
Com as seqüências de caracteres do modelo, você pode colocar uma nova linha em uma sequência, para poder substituí-la /npor ``
Usuário genérico
1
@GenericUser A contagem de bytes é ajustada assumindo que você já fez isso; Eu só não queria usar uma nova linha literal no meu post.
Neil
1

C, 180 bytes

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

Ungolfed:

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
fonte
1

Perl, 110 bytes (script de 108 bytes + sinalizadores de 2 bytes)

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

Executar com perl -nl script.pl, a entrada está em stdin, a saída está em stdout.

Desofuscada

Eu renomeado as variáveis mais sensata, fez o código use stricte use warningscomplacente, e fez um monte explícita do perl magia faz automaticamente.

Isso é apenas executado como perl script.pl, porque replica os efeitos dos -nlsinalizadores dentro do 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
fonte
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`
`

Menos golfe

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

Teste

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
fonte
0

Haskell (dentro do terminal ANSI), 75 bytes

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

Exemplo de uso: putStr $ ("\27[2J"++).(h=<<) $ "bcdef ghijkl"

Isso usa códigos de escape ANSI para mover o cursor para cima e para baixo.

nimi
fonte
0

C, 173 160 156 155 bytes

Edit: idéia emprestada de usar strchr de @mIllIbyte para cortar 13 bytes

Edit2: simplificou as comparações mínimas / máximas, -4 bytes

Edit3: c pode ter qualquer valor para começar -> para main (c), -1 byte

Edit4: Adicionado ungolf / explicação

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

Ungolfed e explicou:

/* 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
fonte