Canhão de alfabeto

34

Uma bala de canhão é disparada, de modo que, no primeiro olho do seu vôo, ele sobe pelas Ncopas das árvores, durante o segundo olho pelas N-1copas das árvores, etc. até atingir o ponto mais alto de sua trajetória. Então começa a cair 1, 2, etc. copas das árvores por olho, até atingir o chão. Ao mesmo tempo, a bala de canhão está se movendo horizontalmente com uma velocidade constante de 1 copa das árvores / eyeblink.

Sua tarefa é desenhar a trajetória com letras consecutivas do alfabeto inglês. Se você ficar sem cartas, comece novamente a partir de 'A'. Escreva uma função ou um programa. A entrada é um número inteiro N( 1≤N≤15). A saída pode ser uma matriz de caracteres de qualquer forma razoável, por exemplo, uma cadeia separada por nova linha ou uma lista de cadeias. As letras podem ser todas minúsculas ou todas maiúsculas. Espaços extras à esquerda e à direita são permitidos. As brechas padrão são proibidas. Código mais curto é melhor.

in:
5
out:
    OP
   N  Q
   M  R
  L    S
  K    T
  J    U
 I      V
 H      W
 G      X
 F      Y
E        Z
D        A
C        B
B        C
A        D

in:
1
out:
AB
ngn
fonte
7
Intimamente relacionado .
Dom Hastings
2
Por que O e P estão no mesmo nível no exemplo? Se eu ler a especificação corretamente, parece que deve subir um copa de árvore para P e descer por uma para Q.
Skyler
2
@ Skyler A cada marca, o alfabeto passa 1 para a direita e N na vertical. N também diminui cada tick. Entre Oe P, o tique vai 1 para a direita, mas 0 para cima ou para baixo.
Olivier Grégoire
4
Parece que os canhões do alfabeto agora são canônicos.
Carl Witthoft 28/02
2
@ngn Hah, eu estava mexendo na solução Perl do @ TonHospel e consegui 1 byte a menos, mas ele suporta apenas 14 !
Dom Hastings

Respostas:

8

05AB1E , 33 32 29 28 bytes

>*As∍2ä`R)ζRIL£vyε`N·úJ])˜.c

Experimente online!

Explicação

>*                             # push input*(input+1)
  As∍                          # take that many characters from the alphabet (with wrap)
     2ä                        # split in 2 parts
       `R)                     # reverse the second part
          ζ                    # zip (gives a list of pairs)
           R                   # reverse
            IL£                # split into parts of sizes equal to [1,2...]
               vy              # for each (part y, index N)
                 ε             # for each pair in that part
                  `N·úJ        # insert N*2 spaces between the characters
                       ]       # end loops
                        )˜     # wrap in a flattened list
                          .c   # format as lines padded to equal length
Emigna
fonte
Eu sinto que Nú»ou algo assim poderia ser usado para imprimir à medida que você vai em vez de])~.c
Magic Octopus Urn
Tudo o que pude apresentar é essa implementação aqui, mas isso é pior em 2 bytes.
Magic Octopus Urn
8

Stax , 29 24 bytes

╦'♫ΓqπL⌂δ@╚n>DI∙Q┴òkεwö╔

Execute e depure on-line

A representação ascii correspondente do mesmo programa é essa.

VA*xRr:m|/xH({rix/|1*_%:T)mMm

VA*                             repeat alphabet input times
   xRr:m                        [x ... 1, 1 ... x] where x=input
        |/xH(                   get consecutive substrings of specified sizes
             {           m      map substrings using block
              ix<|1*            reverse string if index<x
                    _%:T)       left-pad to appropriate triangular number
                          Mm    transpose and output
recursivo
fonte
7

R, 169 163 161 153 150 110 109 bytes

Essa abordagem preenche uma matriz e depois imprime a matriz.

Golfe

function(n)write(`[<-`(matrix(" ",M<-2*n,k<-sum(1:n)),cbind(rep(1:M,c(n:1,1:n)),c(k:1,1:k)),LETTERS),1,M,,"")

Obrigado @ Giuseppe por 153.

Obrigado @JDL por 150.

Veja o comentário de @ Giuseppe para 112 e algumas edições para 110 agora 109. Rasgue o código original.

function(n){a=matrix(" ",M<-2*n,k<-sum(1:n))
Map(function(x,y,z)a[x,y]<<-z,rep(1:M,c(n:1,1:n)),c(k:1,1:k),head(LETTERS,2*k))
cat(rbind(a,"
"),sep="")}

Se estiver plotando uma saída válida, 73 bytes

function(n,k=sum(1:n))plot(rep(1:(2*n),c(n:1,1:n)),c(1:k,k:1),pc=LETTERS)

insira a descrição da imagem aqui

Vlo
fonte
153 bytes - sua solução imprimiu um espaço extra no ápice que eu consertei e depois também joguei algumas coisas. Boa resposta!
Giuseppe
você pode usar em Mapvez de mapply?
JDL
@JDL Você está certo. Eu sempre acho que o Map é um invólucro, em lapplyvez de mapply. Obrigado por 150
Vlo 01/01
Isso continuou me incomodando, porque pensei que deveria haver uma maneira de indexar a matriz por row,columnpares diretamente, em [vez de ter que passar por mapply(ou Map), então encontrei uma maneira de fazer isso. Lembrei-me também de que writeexiste e pode substituir catpor 112 bytes !
Giuseppe
@ Giuseppe Meu comentário sobre "" não funcionou, mas com [<-, conseguimos espremer tudo em uma linha, eliminando a necessidade de algumas definições de variáveis. 110 bytes: tio.run/##K/qfpmCj@z@tNC@5JDM/...
Vlo
6

Python 2 , 140 135 133 bytes

lambda n:[' '*(n-j)+chr(~-i%26+65)+'  '*j+chr((n*-~n-i)%26+65)for i,j in zip(range(n*-~n/2,0,-1),sum([-~i*[i]for i in range(n)],[]))]

Experimente online!

TFeld
fonte
5

MATL , 29 bytes

,G:tPY"tf1Y2y@?tn+P])Z?]Pv1X!

Experimente online!

Como funciona

,        % Do twice
  G:     %   Push [1 2 ... n], where n is the input
  tP     %   Duplicate, flip: pushes [n n-1 ... 1]
  Y"     %   Run-length decoding: gives vector with n ones, n-1 twos ... (*)
  tf     %   Duplicate, find: gives [1 2 3 ... n*(n-1)/2] (**)
  1Y2    %   Push string 'ABC...Z'
  y      %   Duplicate from below: pushes [1 2 3 ... n*(n-1)/2]  again
  @?     %   If we are in the second iteration
    tn   %     Duplicate, length: pushes n*(n-1)/2
    +    %     Add: gives [n*(n-1)/2+1 n*(n-1)/2+2 ... n*(n-1)*2] 
    P    %     Flip: gives [n*(n-1)/2 n*(n-1)/2-1 ... n*(n-1)/2+1]
  ]      %   End if
  )      %   Index (1-based, modular) into the string. Gives a substring
         %   with the letters of one half of the parabola (***)
  Z?     %   Sparse: creates a char matrix with the substring (***) written
         %   at specified row (*) and column (**) positions. The remaining
         %   positions contain char(0), which will be displayed as space
]        % End do twice. We now have the two halves of the parabola, but
         % oriented horizontally instead of vertically
P        % Flip the second half of the parabola vertically, so that the
         % vertex matches in the two halves
v        % Concatenate the two halves vertically
1X!      % Rotate 90 degrees, so that the parabola is oriented vertically.
         % Implicitly display
Luis Mendo
fonte
4

Java (OpenJDK 8) , 121 bytes

n->{for(int l=n*++n/2,r=l,i=1,j=0;l>0;j=j-->0?j:i++)System.out.printf("%"+(n-i)+"c%"+(2*i-1)+"c%n",--l%26+65,r++%26+65);}

Experimente online!

Explicação

n->{                             // int-accepting consumer
 for(                            //  loop
   int l=n*++n/2,                //    declare l (left) is the first character to print.
                                 //              Oh, and n is increased to reduce byte count later.
       r=l,                      //            r (right) is the second character to print.
       i=1,                      //            i is the "outer-loop" index
       j=0;                      //            j is the "inner-loop" index
   l>0;                          //    while there are characters to print        
   j=j-->0?j:i++)                //    simulate two loops in one,
                                 //      where j starts from 0 and always decreases until it reaches 0
                                 //      at which point j is reset to i and i is increased
  System.out.printf(             //   Print...
   "%"+(n-i)+"c%"+(2*i-1)+"c%n", //    2 characters
                                 //    - the first with n-i-1 whitespaces (remember, n was increased)
                                 //    - the second characters with 2*i-2 whitespaces
   --l%26+65,                    //    the first character to print is the left one, we decrease it.
   r++%26+65                     //    the second character to print is the right one, we increase it.
  );                             //   
                                 //  end loop
}                                // end consumer
Olivier Grégoire
fonte
3

C, 184 bytes

i,j,k,l,m,h,o;f(n){char L[o=n*n][n*3];for(i=o;i--;)for(L[i][j=n*2]=h=k=0;j--;)L[i][j]=32;for(m=n;!h|~i;m-=1-h*2)for(h+(l=m)?++j:++h;l--;)L[h?i--:++i][j]=65+k++%26;for(;o--;)puts(L+o);}

Experimente online!

Desenrolado:

i, j, k, l, m, h, o;
f(n)
{
    char L[o=n*n][n*3];

    for (i=o; i--;)
        for (L[i][j=n*2]=h=k=0; j--;)
            L[i][j] = 32;

    for (m=n; !h|~i; m-=1-h*2)
        for (h+(l=m)?++j:++h; l--;)
            L[h?i--:++i][j] = 65 + k++%26;

    for (; o--;)
        puts(L+o);
}
Steadybox
fonte
interessante, eu não consigo compilar este (não há nenhuma principal) mas TIO pode
NGN
1
@ngn É apenas uma função , você precisa adicionar o mainpara compilá-lo. No TIO, mainestá na seção rodapé.
Steadybox
3

Clojure, 417 319 bytes

(defn cannon[n](let[a(map #(char(+ 65 %))(iterate #(if(> % 24)0(inc %))0))m1(reverse(reduce #(concat %(repeat %2(- n %2)))[](range 0(inc n))))p1(map-indexed #(str(apply str(repeat %2 " "))(nth a %))m1)m2(reverse(reduce #(concat %(repeat %2(-(* 2 %2)2)))[](reverse(range 0(inc n)))))p2(reverse(map-indexed #(str(apply str (repeat %2 " "))(nth a(+(count p1)%)))m2))](doseq[x(reverse(map #(str % %2)p1 p2))](println x))))

Em algum momento, me envolvi em reverseligações e desisti da ideia de torná-la a mais curta possível. Eu só queria ter uma solução funcional. Aqui está...

Mais ou menos

(defn cannon [n]
  (let [a (map #(char (+ 65 %)) (iterate #(if (> % 24) 0 (inc %)) 0))
        m1 (reverse (reduce #(concat % (repeat %2 (- n %2))) [] (range 0 (inc n))))
        p1 (map-indexed #(str (apply str (repeat %2 " ")) (nth a %)) m1)
        m2 (reverse (reduce #(concat % (repeat %2 (- (* 2 %2) 2))) [] (reverse (range 0 (inc n)))))
        p2 (reverse (map-indexed #(str (apply str (repeat %2 " ")) (nth a (+ (count p1) %))) m2))]
    (doseq [x (reverse (map #(str % %2) p1 p2))] (println x))))

Atualizar

Motivado pelo comentário de Olivier, consegui cortar várias reversechamadas e aplicar alguns truques gerais de golfe para cortar caracteres. Também criei aliases para reverse, map-indexed, concat, repeate strporque eu usei-los várias vezes cada.

(defn c[n](let[a(map #(char(+ 65 %))(iterate #(if(> % 24)0(inc %))0))k #(reduce %[](range 0(inc n)))r #(apply str(repeat % " "))rv reverse m map-indexed c concat t repeat s str p(m #(s(r %2)(nth a %))(rv(k #(c %(t %2(- n %2))))))](rv(map #(s % %2)p(rv(m #(s(r %2)(nth a(+(count p)%)))(k #(c %(t %2(-(* 2 %2)2))))))))))

Ungolfed

(defn c [n]
  (let [a (map
           #(char (+ 65 %))
           (iterate
            #(if (> % 24) 0 (inc %))
            0))
        k #(reduce
            %
            []
            (range 0 (inc n)))
        r #(apply str (repeat % " "))
        rv reverse
        m map-indexed
        c concat
        t repeat
        s str
        p (m
           #(s
             (r %2)
             (nth a %))
           (rv (k #(c % (t %2 (- n %2))))))]
    (rv
     (map
      #(s % %2)
      p
      (rv
       (m
        #(s
          (r %2)
          (nth a (+ (count p) %)))
        (k #(c % (t %2 (- (* 2 %2) 2))))))))))

Cria a função cque aceita o valor n e retorna uma lista de linhas.

Joshua
fonte
Esta não é uma resposta, pois aparentemente não há nenhuma tentativa de jogar golfe (você mesmo diz).
Olivier Grégoire
Ok, isso é muito melhor! ;-)
Olivier Grégoire
3

Carvão , 33 31 bytes

≔⁰ηF…±N⊕θ«¿ι→↓F↔ι«P§αη≦⊕η¿›ι⁰↓↑

Experimente online! Link é a versão detalhada do código. Editar: salvou 2 bytes graças a @ ASCII-only. Explicação:

≔⁰η

Inicialize a letra atual como um índice no alfabeto maiúsculo para 0.

F…±N⊕θ«

Faça um loop da negação da entrada para a entrada inclusive.

¿ι→↓

Normalmente, cada coluna está à direita da anterior. No entanto, não há coluna para zero. Em vez disso, é necessária uma correção para garantir que os lados esquerdo e direito estejam alinhados.

F↔ι«

Loop para cada letra na coluna.

P§αη

Imprima a letra atual.

≦⊕η

Incremente o índice de letras.

¿›ι⁰↓↑

Mover para cima ou para baixo, dependendo do lado da trajetória em que estamos.

Neil
fonte
Parece que poderia haver uma maneira mais curta de fazer isso, mas não sei como: /
ASCII-only
4
31 bytes
somente ASCII
3

Perl 5 , -n 112 92 90 88 bytes

Pela primeira vez o terrivelmente longo printfparece ganhar.

#!/usr/bin/perl -n
$p=$q=$_*($%=$_+1)/2;map{printf"%$%c%$.c
",--$p%26+65,$q++%26+65for--$%..$';$.+=2}//..$_

Experimente online!

Ton Hospel
fonte
Boa melhoria! Eu estava tentando (A..Z)x9trabalhar, mas estava muito abaixo do limite! Teve isso por apenas 91. :)
Dom Hastings
1
@DomHastings Foi uma boa tentativa de sinergia entre os dois cálculos de letras quase repetidos. Aquele também me irrita.
Ton Hospel
2

Python3 + numpy, 124 115

from pylab import*
def i(N):
 x=zeros((N,2*N),'U');x[r_[N-1:-1:-1,0:N],r_[:2*N]]=map(chr,r_[0:2*N]%26+65)
 return x

Isso cria uma matriz de tamanho apropriado, localiza os índices da trajetória e atribui o caractere apropriado a eles. A parte mais complexa é gerar os caracteres AZ, que dependem de um elenco muito hackish de números para um tipo de string. O objeto retornado é uma matriz unicode.

Editar : salvou 9 bytes substituindo o código numpy que gerou os caracteres AZ ( (r_[0:2*N]%26+65).view('U1')[::2]) com map, conforme sugerido aqui .

user2699
fonte
2

Python 3 , 139 136 bytes

f=lambda n,o=0:n and'\n'.join([f(n-1,o+n).replace('\n','\n ')]+[chr(65+(n+o+~i)%26)+'  '*~-n+chr(65+(n*n+o+i)%26)for i in range(n)])or''

Experimente online!

Gera cada camada recursivamente, considerando o tamanho e o deslocamento.

-3 bytes graças a Jo King

Matthew Jensen
fonte
@JoKing Obrigado, eu sempre esqueço o ~operador!
Matthew Jensen
Você também pode alterar n and ... or''a n*' 'and ...para outro byte
Jo rei
2

J , 78 75 bytes

(26{.65|.a.)($~#)`(;/@])`(' '$~1+{:@])}i.@+:(,.~(|.,])@i.@-:@#)@#~1+i.@-,i.

Experimente online!

-3 graças a ngn

Jonah
fonte
1
(,|.)@i.@-->i.@-,i.
ngn
Obrigado @ngn. Este é um daqueles onde parecia que deveria haver uma solução em 40-50 bytes, mas se houver, não consegui vê-lo ....
Jonah
1

Python 2 , 182 bytes

I=input()
S=list('ZYXWVUTSRQPONMLKJIHGFEDCBA'*I)
R=range
print zip(*[(' '*(sum(R(abs(i))))+eval('S.pop()+'*abs(i)+"''")[::[-1,1][i>0]]).ljust(sum(range(I+1)))for i in R(-I,I+1)if i])

Experimente online!

Retorna a lista de listas de caracteres. Verificação primitiva aqui

Gambá morto
fonte
1

Yabasic , 125 bytes

Uma solução que usa o modo gráfico para imprimir os caracteres na coluna e linha corretas da tela.

Input""n
Clear Screen
For i=-n To n
For j=1To Abs(i)
k=i>0
?@(i+n-k,(i^2-i)/2+j-2*j^(!k)+k)Chr$(c+65)
c=Mod(c+1,26)
Next
Next

Como esta solução usa o modo gráfico, não pode ser executada no TIO.

Saída

Abaixo está a saída para entrada 7

Program Output (n=7)

Taylor Scott
fonte
1

Ruby , 106 103 bytes

->n,f=2*s=-~n*n/2-1{l=*?A..?Z;(1..n).map{|i|i.times{puts' '*(n-i)+l[(f-s)%26]+' '*~-i*2+l[(s+=1)%26]}}}

Experimente online!

Asone Tuhid
fonte
1

QBasic 1.1 , 124 bytes

Toma entrada e dispara um canhão. Devido a limitações de tamanho da tela,n devemos ser 6.

INPUT n
CLS
FOR i=-n TO n
FOR j=1TO ABS(i)
k=i>0
LOCATE(i^2-i)/2+j-2*j^-(k=0)-k+1,i+n+k+1
?CHR$(c+65)
c=(c+1)MOD 26
NEXT j,i
Taylor Scott
fonte
1

Python 3 , 190 bytes

j,r,c,s=int(input()),range,[],[];a=(j+1)*j;b=a//2
for i in r(j):k=i+1;c.extend([j-k]*k)
for i in r(a):s+=chr(ord('A')+(i%26))
for i in r(b):print(' '*c[i]+s[b-i-1]+' '*(2*(j-c[i]-1))+s[b+i])

Experimente online!

Eu tentei o meu melhor. Deixe-me saber se são possíveis otimizações.

Koishore Roy
fonte
1

k4, 76 71 bytes

{+|:'p$(-k,|k:+\l)$(x#b),|:'x_b:(i:-1_0,+\l,|l)_a:(2*p:+/l:|1+!x)#.Q.a}

algumas reorganizações + atribuições para economizar 5 bytes


{+|:'(+/l)$(-k,|k:+\l)$(x#i_a),|:'((-x)#i:-1_0,+\l,|l)_a:(2*+/l:|1+!x)#.Q.a}

esforço de meia hora com algum esforço para eliminar alguns bytes, mas provavelmente há muito mais que pode ser feito aqui. voltará a ele. desafio divertido!

rabisco
fonte