Алфавит пушка

34

Пушечное ядро ​​запускается таким образом, что в первом звене его полета он поднимается по Nверхушкам деревьев, во время второго звена в виде N-1верхушек деревьев и т. Д., Пока не достигнет самой высокой точки своей траектории. Затем он начинает падать на 1, 2 и т.д. на верхушку глаза, пока не упадет на землю. В то же время пушечное ядро ​​движется в горизонтальном направлении с постоянной скоростью 1 верхушка дерева / глазная связь.

Ваша задача - нарисовать траекторию последовательными буквами из английского алфавита. Если у вас закончились буквы, начните снова с 'A'. Написать функцию или программу. Входные данные являются целыми числами N( 1≤N≤15). Выходными данными может быть символьная матрица в любой разумной форме, например строка, разделенная новой строкой, или список строк. Буквы могут быть как строчными, так и прописными. Допускаются дополнительные начальные и конечные пробелы. Стандартные лазейки запрещены. Чем короче код, тем лучше.

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
СПП
источник
7
Тесно связана .
Дом Гастингс
2
Почему O и P на одном уровне в примере? Если я правильно прочитал спецификацию, кажется, что она должна подняться на одну верхушку дерева для P и спуститься на одну для Q.
Skyler
2
@Skyler На каждом тике алфавит идет 1 вправо и N вертикально. N также уменьшает каждый тик. Между Oи P, галочка идет 1 вправо, но 0 вверх или вниз.
Оливье Грегуар
4
Похоже, алфавитные пушки теперь каноны.
Карл Виттофт,
2
@ngn Ха, я возился с Perl-решением @ TonHospel и придумал на 1 байт меньше, но он поддерживает только до 14 !
Дом Гастингс

Ответы:

8

05AB1E , 33 32 29 28 байт

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

Попробуйте онлайн!

объяснение

>*                             # 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
источник
Я чувствую, что Nú»или что-то подобное можно использовать для печати по ходу дела, а не])~.c
Волшебный осьминог Урн
Все, что я мог придумать, - это реализация здесь, но она хуже на 2 байта.
Волшебная Урна Осьминога
8

Stax , 29 24 байта

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

Запустите и отладьте его онлайн

Соответствующее представление ascii той же программы таково.

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
рекурсивный
источник
7

R 169 163 161 153 150 110 109 байт

Этот подход заполняет матрицу и затем печатает матрицу.

Golfed

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,,"")

Спасибо @Giuseppe за 153.

Спасибо @JDL за 150.

См. Комментарий @ Giuseppe для 112, и некоторые правки для 110 теперь 109. Rip оригинальный код.

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="")}

Если выводится правильный вывод, то 73 байта

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

введите описание изображения здесь

Vlo
источник
153 байта - ваше решение напечатало дополнительное пространство на вершине, которую я исправил, а затем я также добавил несколько вещей. Хороший ответ!
Джузеппе
ты можешь использовать Mapвместо mapply?
JDL
@JDL Вы правы. Я всегда думаю, что Map является оберткой lapplyвместо mapply. Спасибо за 150
Vlo
Это продолжало беспокоить меня, потому что я думал, что должен быть способ индексировать матрицу row,columnпарами напрямую, [а не проходить через mapply(или Map), поэтому я нашел способ сделать это. Я также вспомнил , что writeсуществует и может заменить catна 112 байт !
Джузеппе
@Giuseppe Мой комментарий о "" не сработал, но с помощью [<- мы можем сжать все в пределах одной строки, устраняя необходимость в некоторых определениях переменных. 110 байт: tio.run/##K/qfpmCj@z@tNC@5JDM/…
августа,
5

MATL , 29 байт

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

Попробуйте онлайн!

Как это работает

,        % 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
Луис Мендо
источник
4

Java (OpenJDK 8) , 121 байт

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

Попробуйте онлайн!

объяснение

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
Оливье Грегуар
источник
3

C 184 байта

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

Попробуйте онлайн!

раскатали:

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
источник
интересно, я не могу скомпилировать это (нет главного), но
TIO
1
@ngn Это просто функция , вам нужно добавить ее mainдля компиляции. На TIO это mainнаходится в разделе нижнего колонтитула.
Steadybox
3

Clojure, 417 319 байт

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

В какой-то момент я запутался в reverseзвонках и разочаровался в идее сделать это как можно короче. Я просто хотел иметь рабочее решение. Ну вот...

Вроде негольфя

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

Обновить

По мотивам комментария Оливье мне удалось сократить количество reverseзвонков и применить некоторые общие трюки в игре в гольф, чтобы вырезать персонажей. Также я создал псевдонимы reverse, map-indexed, concat, repeatи strпотому что я использовал их несколько раз каждый.

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

Создает функцию, cкоторая принимает значение n и возвращает список строк.

Джошуа
источник
Это не ответ, так как, по-видимому, вообще нет попыток играть в гольф (вы даже говорите так).
Оливье Грегуар
Хорошо, это намного лучше! ;-)
Оливье Грегуар
3

Древесный уголь , 33 31 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Редактировать: Сохранено 2 байта благодаря @ ASCII-only. Объяснение:

≔⁰η

Инициализируйте текущую букву как индекс в верхнем регистре алфавита к 0.

F…±N⊕θ«

Сделайте цикл от отрицания входа до входа включительно.

¿ι→↓

Обычно каждый столбец находится справа от предыдущего. Тем не менее, нет столбца для нуля. Вместо этого требуется коррекция, чтобы обеспечить выравнивание левой и правой сторон.

F↔ι«

Цикл для каждой буквы в столбце.

P§αη

Распечатать текущее письмо.

≦⊕η

Увеличить буквенный индекс.

¿›ι⁰↓↑

Двигайтесь вверх или вниз в зависимости от того, на какой стороне траектории мы находимся.

Нил
источник
Похоже, что может быть более короткий способ сделать это, но не уверен, как: /
Только для ASCII
4
31 байт
только для ASCII
3

Perl 5 , -n 112 92 90 88 байт

На этот раз ужасно долго, printfкажется, победит.

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

Попробуйте онлайн!

Тон Хоспел
источник
Хорошее улучшение! Я пытался добраться (A..Z)x9до работы, но это было слишком мало! Было это только для 91. :)
Дом Гастингс
1
@DomHastings Yours был хорошей попыткой объединить два почти повторяющихся вычисления букв. Это меня тоже раздражает.
Тон Хоспел
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

Это создает массив соответствующего размера, находит индексы для траектории и назначает им соответствующий символ. Самая сложная часть - это генерирование символов AZ, которое основано на очень хакерском приведении чисел к строковому типу. Возвращаемый объект является массивом Unicode.

Редактировать : Сохранено 9 байтов, заменяя код, который генерировал символы AZ ( (r_[0:2*N]%26+65).view('U1')[::2]) map, как предложено здесь .

user2699
источник
2

Python 3 , 139 136 байт

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

Попробуйте онлайн!

Создает каждый слой рекурсивно, учитывая размер и смещение.

-3 байта благодаря Джо Кингу

Мэтью Дженсен
источник
@ JoKing Спасибо, я всегда забываю об ~операторе!
Мэтью Дженсен
Кроме того, можно изменить , n and ... or''чтобы n*' 'and ...для следующего байта
Джо Кинг
2

J , 78 75 байт

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

Попробуйте онлайн!

-3 благодаря ngn

Ион
источник
1
(,|.)@i.@-->i.@-,i.
нгн
Спасибо @ngn. Это один из тех случаев, когда казалось, что должно быть решение в 40-50 байтов, но если оно есть, я не смог его увидеть ....
Иона
1

Ябасич , 125 байт

решение , которое использует графический режим для печати символов в правильном столбце и строке экрана.

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

Поскольку это решение использует графический режим, его нельзя выполнить на TIO.

Выход

Ниже вывод для ввода 7

Выход программы (n = 7)

Тейлор Скотт
источник
1

QBasic 1.1 , 124 байта

Берет вход и стреляет из пушки. Из-за ограничений по размеру экрана,N должно быть 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
Тейлор Скотт
источник
1

Python 3 , 190 байт

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

Попробуйте онлайн!

Я старался как мог. Дайте мне знать, если возможны какие-либо оптимизации.

Койшор Рой
источник
1

k4, 76 71 байт

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

некоторые перестановки + назначения для сохранения 5 байтов


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

получасовые усилия с некоторыми усилиями, чтобы сбрить несколько байтов, но, вероятно, здесь можно сделать гораздо больше. вернусь к этому. веселый вызов!

каракули
источник