Detonar uma string

34

Dada qualquer sequência, imprima-a na forma de um triângulo, onde o texto corre para cima e para baixo ao longo de cada diagonal. Por exemplo, uma entrada de "Hello World"deve produzir:

                    d
                  l  
                r   d
              o   l  
            W   r   d
              o   l  
        o   W   r   d
      l       o   l  
    l   o   W   r   d
  e   l       o   l  
H   l   o   W   r   d
  e   l       o   l  
    l   o   W   r   d
      l       o   l  
        o   W   r   d
              o   l  
            W   r   d
              o   l  
                r   d
                  l  
                    d

O espaço entre cada caractere em uma linha deve ser pelo menos 1, para manter o formato adequado.

maquiavel
fonte
1
Podemos assumir que a string não está vazia?
Mr. Xcoder
@ Mr.Xcoder Sim, você pode
maquiavel
1
O espaço entre cada caractere em uma linha deve ser pelo menos 1 : isso significa que H l o W r dé uma linha central válida? Perguntando, porque no seu exemplo, cada linha tem 3 espaços entre cada caractere.
Emigna
1
@ Emigna Eu entendi mal a sua pergunta, minhas desculpas. Sim, seu exemplo seria válido.
Maquiavel
1
São permitidos espaços à esquerda ou à direita?
Luis Mendo

Respostas:

19

Carvão , 10 7 bytes

↗ELθ✂θιUE¹

Experimente online! Experimente online! Os links são para a versão detalhada do código. Explicação:

    ↗       Print up and to the right
     ELθ✂θι All suffixes of the input, as a list down and to the right
    UE¹     Insert blank columns

Primeira vez que pude usar o UEcomando.

Neil
fonte
Eu sabia que o carvão seria uma das primeiras respostas aqui. Era quase tentador me iniciar, mas sou muito inexperiente para terminar uma solução a tempo e, de qualquer maneira, acabaria jogando golfe ..;)
Kevin Cruijssen
6
@Emigna ... mas esta foi a minha grande chance de uso UE...
Neil
6
@EriktheOutgolfer ... mas esta foi a minha grande chance de uso UE..
Neil
1
@ Neil É -3 bytes! -3 por um bom sacrifício! Quem não quer um bom -3?
Erik the Outgolfer
4
@EriktheOutgolfer O que você deveria dizer é: "Você não pode deixar 05AB1E bater em você, pode?"
Neil
12

05AB1E , 10 8 7 bytes

Obrigado a Emigna por economizar 2 bytes!

ðâƶ.cðζ

Usa a codificação 05AB1E . Experimente online!

Adnan
fonte
De acordo com esta linha O espaço entre cada caractere em uma linha deve ser pelo menos 1 que você pode remover ¶«. (também verificou a validade com OP)
Emigna
@Emigna Thanks! :)
Adnan
Pode querer atualizar o link Tio :)
Mr. Xcoder
@ Mr.Xcoder ninja'd
Adnan
1
Uso inteligente de âem ðâvez de Sð«!
Erik the Outgolfer
9

Python 2 , 75 bytes

s=input()
k=l=len(s)
while k>1-l:k-=1;m=abs(k);print' '*m+' '.join(s[m::2])

Experimente online!

Ruud salvou 3 bytes.

Lynn
fonte
3
Isso foi permitido pelo OP: 78 bytes . O espaço em cada linha deve ser pelo menos 1 .
Mr. Xcoder
1
75 bytes
Arfie
8

C, 86 78 73 70 caracteres

for(int i=1,j=1-n;i=putchar(j*j<i*i&i-j?s[i-1]?:13:32)^13?i+1:++j<n;);

Experimente online!

Explicação

Implementação ingênua: dois ciclos, preenchidos de cima para baixo, da esquerda para a direita (99 bytes):

for(int j=1;j<n*2;j++){for(int i=0;i<n;i++)printf("%c ",(i+j)%2&&i+1>=abs(j-n)?s[i]:' ');puts("");}

Aqui, o puts () apenas imprime \ n na saída. Vamos combinar declarações de variáveis ​​e combinar j ++ com algo (94 bytes):

for(int i,j=0;++j<n*2;){for(i=0;i<n;i++)printf("%c ",(i+j)%2&&i>=abs(j-n)?s[i]:' ');puts("");}

Boa. A variável j tem um intervalo de 0 a 2n; seja em -n ... n, isso simplifica a matemática. Observe que a expressão booleana à direita de && sempre tem o valor 0 ou 1. Isso significa que podemos substituir && por &. 91 bytes:

for(int i,j=-n;++j<n;){for(i=0;i<n;i++)printf("%c ",~(i+j)%2&i>=abs(j)?s[i]:' ');puts("");}

E agora percebemos que estávamos imprimindo um espaço extra. E sim, não precisamos de printf () para imprimir apenas um único símbolo. 86 bytes:

for(int i,j=-n;++j<n;){for(i=0;i<n;i++)putchar(~(i+j)%2&i>=abs(j)?s[i]:' ');puts("");}

Melhor ainda. Observe que a condição i * i> = j * j é a mesma que i> = abs (j), mas menor. Vamos mover puts () para a expressão de incremento do loop. E adivinha? Na verdade, não precisamos do aparelho em torno de i + j. 78 bytes:

for(int i,j=-n;++j<n;puts(""))for(i=0;i<n;i++)putchar(i*i>=j*j&~i+j?s[i]:' '); 

Você sabia que putchar () retorna o caractere impresso? Vamos usar o XOR para testar os números de equivalência. Vamos substituir o espaço pelo código ASCII, 32. Lembre-se que o código de final de linha é 13. E finalmente: você sabia que o GCC / Clang suporta https://en.wikipedia.org/wiki/Elvis_operator ? 73 bytes:

for(int i,j=-n;++j<n;)for(i=0;putchar(i*i>=j*j&~i+j?s[i]?:13:32)^13;i++);

Finalmente, adivinhe? Não precisamos de dois para loops. Podemos substituir feio ~ i + j por apenas ij. 70 bytes:

for(int i=1,j=1-n;i=putchar(j*j<i*i&i-j?s[i-1]?:13:32)^13?i+1:++j<n;);

Trabalho futuro: mudar a direção do loop? Isso pode economizar alguns bytes, se feito corretamente.

MrShoor
fonte
5

SOGL V0.12 , 13 10 9 bytes

ēI*@∑}¹╚H

Isso usa um recurso que acabei de adicionar , mas foi documentado há um tempo atrás.

Experimente aqui!
Nesse link ,é adicionado porque isso espera a entrada na pilha e {adicionado porque, caso contrário, ,seria executado toda vez que o loop

implicitly start loop over POP
ē            increase the variable E, on first push which will be 0
 I           increase by 1
  *          multiply the current character that many times
   @∑        join with spaces
     }     end loop
      ¹    wrap everything on stack in an array
       ╚   center vertically
        H  rotate counter-clockwise
dzaima
fonte
4

Haskell , 73 bytes

f s|l<-length s-1=[zipWith min s$(' '<$[1..abs x])++cycle"~ "|x<-[-l..l]]

Experimente online!

Lynn
fonte
3

Gaia , 16 bytes

$:ċ⟪×$§×⟫†€|$¦tụ

Experimente online!

Explicação

$                 Split into list of chars
 :ċ               Push [1 .. len(input)]
   ⟪×$§×⟫†        Apply this block to corresponding elements of the two lists:
    ×              Repetition
     $             Split into chars
      §×           Join with spaces
          €|      Centre align the rows
            $¦    Split each line into chars
              t   Transpose
               ụ  Join each row with spaces, then join the rows together with newlines
Gato de negócios
fonte
3

Python 2 , 86 83 bytes

-3 graças a officialaimm

lambda s,j=' '.join:map(j,zip(*(j(c*-~i).center(len(s)*2)for i,c in enumerate(s))))

Experimente online!

Arfie
fonte
1
83 bytes
officialaimm
3

Oitava, 59 63 58 57 bytes

@(s,a=@strjust)a([kron(+a(hankel(s)),[1 0;0 0]) '']',99)'

Experimente online!

rahnema1
fonte
1
99: Boa idéia :-)
Luis Mendo
3

Java, 292 bytes (desculpe)

public class D{
public static void main(String[]r){
String s=r[0];int L=s.length(),n=L*2-1,x=L-1,d=-1,i,j;boolean a=false,o=L%2==1;
for(i=0;i<n;i++){
for(j=0;j<L;j++)System.out.print(j<x||a&&j%2==(o?0:1)||!a&&j%2==(o?1:0)?' ':s.charAt(j));
System.out.println();
x+=d;if(x<0){x=0;d=1;}a=!a;}}}
ubzack
fonte
1
Você pode remover as novas linhas, caso contrário, isso parecerá bastante divertido!
`` Zacharý
1
Você pode jogar mais: 1 boolean a=1<0,o=L%2>0;.. 2. Se você não precisa i, usar este loop: for(i=0;i++<n;). 3. Você pode se livrar de o: j%2<L%2then j%2>L%2. 4. Usar dcomo flip leva tantos caracteres: apenas faça j<(x<0?-x:x). 5. Você tem muito mais variáveis ​​do que o necessário. 6. Você não precisa de um programa completo: um lambda ou método é suficiente. - Se você quiser um exemplo de Java, verifique minha resposta .
Olivier Grégoire
3

Haskell , 81 bytes

f s|l<-length s=[[last$' ':[s!!i|i>=n,mod(n+i)2<1]|i<-[0..l-1]]|n<-abs<$>[-l..l]]

Experimente online!

Laikoni
fonte
3

Java (OpenJDK 8) , 116 bytes

s->{for(int l=s.length(),i=-l;++i<l;)System.out.printf("%"+l+"s%n",s.substring(i<0?-i:i).replaceAll("(.).","$1 "));}

Experimente online!

Explicação

s->{                                // Consumer<String> lambda
 for(int l=s.length(),i=-l;++i<l;)  // For each length between l and 1 and back to l, 
  System.out.printf("%"+l+"s%n",    // Print with align to right
    s.substring(i<0?-i:i)           // skip the first |i| characters
     .replaceAll("(.).","$1 ")      // replace every even-positioned character with a space.
   );
}
Olivier Grégoire
fonte
3

C ++, 135 bytes

Ok, aqui está minha chance com C ++:

auto f=[&](auto f,int y)->void{
  for(int i{};i<n;i++) putchar(y<0?f(f,y+1?i+1:n-1-i),'\n':i<y||i+y&1?' ':s[i]);
}; f(f,-1); f(f,-2);

Experimente Online (ideone)!

Alexandr Poltavsky
fonte
3

Haskell , 140 137 bytes

(m#n)s=(\(i,x)->' ':(last$"  ":[x:" "|rem i 2==m&&i>n]))=<<zip[0..]s
g s=((++)=<<reverse.tail)$id=<<[[(0#n)s,(1#n)s]|n<-[-1,1..length s]]

Experimente online!

Salva 3 bytes thanls no Challenger5

Eu não acho que isso é ótimo ...

fproduz uma das linhas ( m= 0 ou 1 é o módulo do número da linha, né o número da linha)

g intercala linhas "ímpares" e "pares" e adiciona ao resultado um espelho de si mesmo.

jferard
fonte
Você pode salvar bytes definindo fcomo uma função de infixo (como em (m#n)s=...) em vez de uma função de prefixo.
Esolanging Fruit
2

Mathematica 105 Bytes

(c=Characters@#;l=Length@c;StringRiffle@Table[If[Abs[j-l]<i&&EvenQ[j+i],c[[i]]," "],{j,1,2l+1},{i,1,l}])&

Talvez eu possa cortar outro byte ou dois, mas a sobrecarga de caracteres no processamento de strings no Mathematica cria desafios simples como esse não competitivo.

Kelly Lowder
fonte
2

J, 54 bytes

[:|:|.@i.@#(>@],~' '#~[)"_1[:(,' '&,)/&.>>:@i.@#<@#"0]

Experimente online! (observe que a saída no TIO tem uma nova linha e três espaços, mas isso não é da chamada de função - provavelmente é exatamente o que o intérprete J faz automaticamente).

Acho que a idéia geral para resolver isso é correta, mas há pequenas coisas que provavelmente estou fazendo de maneira subótima que estão adicionando ao número de bytes.

Variantes anteriores

55 bytes

<:@+:@#{.[:|:|.@i.@#(],~' '#~[)"_1>:@i.@#(,' '&,)/@#"0]

56 bytes

<:@+:@#{.[:|:|.@i.@#(],~' '#~[)"_1#{.[:(,' '&,)//.[:]\.]

Explicação

Isso será dividido em algumas funções. Além disso, não fui tão meticuloso com as últimas partes da explicação, então deixe-me saber se você deseja uma explicação melhor para uma determinada parte e posso editá-la.

dup   =. >:@i.@# <@#"0 ]
space =. (,' '&,)/&.>
pad   =. |.@i.@# (>@],~' '#~[)"_1 ]
trans =. |:
  • dup duplica cada caractere tantas vezes quanto seu índice (mais um) na string
  • space insere espaços entre cada caractere
  • pad preenche os caracteres com a quantidade certa de espaços
  • trans transpõe a matriz resultante

Exemplo de chamada:

   trans pad space dup 'abc'
  c
 b 
a c
 b 
  c

Dup

>:@i.@# <@#"0 ]
>:@i.@#         Indices of each character plus one
      #          Length of the string
   i.            Range [0,length)
>:               Add one
        <@#"0 ] Duplicate each character as many times as it index (plus one)
           "0   For each
          #   ]  Copy the character
>:@i.@#           as many times as it index
        <        Box the result

Os resultados estão em caixas para impedir que J preencha as extremidades com espaços (já que são de comprimento desigual).

Exemplo de chamada:

   dup 'abc'
┌─┬──┬───┐
│a│bb│ccc│
└─┴──┴───┘

Espaço

(,' '&,)/&.>
         &.>  For each boxed element
(,' '&,)/      Insert spaces between each

Exemplo de chamada:

   space dup 'abc'
┌─┬───┬─────┐
│a│b b│c c c│
└─┴───┴─────┘

Almofada

|.@i.@# (>@],~' '#~[)"_1 ]
        (>@],~' '#~[)      Pad the right arg with spaces given by the left arg
|.@i.@#                    Indices in reverse order
   i. #                     Range [0,length)
|.                          Reverse

Basicamente, preencha o primeiro elemento com comprimento - 1 espaços, o segundo com comprimento - 2, etc. Ele também remove o boxe.

Exemplo de chamada:

   pad space dup 'abc'
  a  
 b b 
c c c

Transpor

Esta é apenas a função |:interna que aceita a transposição de uma matriz.

Cole
fonte
1
Eu usei uma abordagem semelhante, mas evitei o boxe. 45 bytes: |:@(-@i.@-@#|."0 1((,@,.~' '#~#)@$"0~1+i.@#)). certamente poderia ser jogado ainda mais. esta parte -@i.@-@#é um pouco de frutas penduradas, provavelmente
Jonah
@ Jonah Não consigo decifrar rapidamente como sua resposta funciona, então deixarei que você a publique, se quiser, pois eu gostaria de incluir uma explicação da minha resposta. Eu acho que J para mim agora é uma linguagem somente de gravação.
cole
útil para decifrar rapidamente: f=. <some tacit expression>, em seguida, 5!:2 <'f'dá uma visualização em caixa e 5!:4 <'f'dá uma visualização de árvore. no meu caso, tente executar $"0~1+i.@#com alguma corda primeiro, depois execute tudo à direita de |."0 1, entenda isso |."0 1e tudo à esquerda, salve a transposição final, está apenas fazendo as rotações necessárias.
Jonah
1
oh, eu não estava esperando que você atualizasse sua resposta. era mais um "ei, você pode achar isso interessante". Eu poderia ter postado, mas senti que as abordagens de alto nível eram semelhantes o suficiente, não valia a pena.
Jonah
2
Acabei de lembrar dos argumentos complexos de #help aqui, 26 bytes with|:@((-#)|."_1(1j1##)"0)~#\
miles
1

JavaScript (ECMAScript 6), 161 bytes

(s,n=console.log)=>s.split("").map((q,i,a,p)=>n(p=" ".repeat(q=a.length-++i)+a.map((v,j)=>j>=q&&j%2==q%2?a[j]+' ':'').join(''))||p).reverse().map((v,i)=>i&&n(v))

Experimente online!

sgtdck
fonte
1

Perl 5 , 86 + 2 (-F) = 88 bytes

Usei as sugestões do @ Dom e alguns dos meus próprios ajustes para diminuir a contagem de bytes.

for$k(0..$#F){$i=1;$a[$#F+$k]=$a[$#F-$k]=[map$i++<$k|($i+$k)%2?$":$_,@F]}say"@$_"for@a

Experimente online!

Xcali
fonte
Desculpe por isso, feliz que você tenha sua resposta lá fora! Teve um pouco de brincadeira quando eu estava tentando consertar o meu e não conseguir uma solução, a sua foi uma abordagem melhor! É possível soltar alguns bytes usando -aFpara inserir todas as letras @Fe alguns pequenos ajustes ( -Fconta como 3, pois precisa de um espaço depois): Experimente online!
Dom Hastings
1
Por que -F conta como 3? Não deveria ser 2 no máximo? Não é a diferença entre perl -e'code...'e perl -eF 'code...'. Também -aé desnecessário ao usar -F, para que o byte possa ser cortado.
Xcali 18/08/19
É exatamente isso. Então, -Faceita um argumento, mas não queremos passar um ( -Fnos permite controlar o que se -adivide, sem argumento, divide cada caractere sozinho), portanto é a diferença entre perl -ae '...'e perl -aF -e '...'. Por padrão, -adivide-se em /\s+/. Espero que ajude a esclarecer!
Dom Hastings
Além disso, bom uso de $#F! Sempre esqueça disso!
Dom Hastings
0

q / kdb +, 55 bytes

Solução:

-1(+){{1_a,((2*y)#" ",z),a:x#" "}'[(|)c;1+c:(!)(#)x]x};

Exemplo:

q)-1(+){{1_a,((2*y)#" ",z),a:x#" "}'[(|)c;1+c:(!)(#)x]x}"Hello World";
          d
         l
        r d
       o l
      W r d
       o l
    o W r d
   l   o l
  l o W r d
 e l   o l
H l o W r d
 e l   o l
  l o W r d
   l   o l
    o W r d
       o l
      W r d
       o l
        r d
         l
          d

Explicação:

FAÇAM. versão não-gasta é 66 bytes:

-1 flip{{1_a,((2*y)#" ",z),a:x#" "}'[reverse c;1+c:til count x]x};

Bônus:

Para obter a mesma saída que o exemplo (74 bytes):

q)-1(+){1_'raze{(a,((2*y)#" ",z),a:x#" ";(2*y+x)#" ")}'[(|)c;1+c:(!)(#)x]x}"Hello World";
                    d
                  l
                r   d
              o   l
            W   r   d
              o   l
        o   W   r   d
      l       o   l
    l   o   W   r   d
  e   l       o   l
H   l   o   W   r   d
  e   l       o   l
    l   o   W   r   d
      l       o   l
        o   W   r   d
              o   l
            W   r   d
              o   l
                r   d
                  l
                    d
rua
fonte