字母加农炮


34

发射炮弹,使其在飞行的第一个眨眼中由N树梢上升,在第二个眨眼中由N-1树梢等,直到到达其轨迹的最高点。然后,它每眨眼一次就掉下1、2等树梢,直到掉到地上。同时,炮弹以1个树梢/眨眼的恒定速度水平移动。

您的任务是使用来自英语字母表的连续字母绘制轨迹。如果字母用完了,请从重新开始'A'。编写函数或程序。输入是整数N1≤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


2
为什么在示例中O和P处于同一水平?如果我正确阅读了规范,似乎它应该在P的树梢上上升,在Q的树梢上下降
Skyler

2
@Skyler在每个刻度上,字母右移1,垂直向N。N也会每个滴答滴答地减少。在O和之间P,刻度线向右移1,但向上或向下为0。
奥利维尔·格雷戈尔

4
看起来像字母大炮现在正教规。
卡尔·威索夫特

2
@ngn Hah,我正在修改@TonHospel的Perl解决方案,并减少了1个字节,但它最多支持14个字节!
Dom Hastings

Answers:


8

05AB1E33 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

我觉得Nú»或随便可以用来打印的东西,而不是])~.c
魔术章鱼缸

我所能想到的就是这里的实现,但是差了2个字节。
魔术章鱼缸

8

Stax29个 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字节

此方法填充矩阵,然后打印矩阵。

打高尔夫球

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)。翻录原始代码。

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)

enter image description here


153个字节 -您的解决方案在我固定的顶点处打印了一个额外的空间,然后我还打了一些东西。好答案!
朱塞佩

可以Map代替使用mapply吗?
JDL

@JDL你是对的。我一直认为Map是lapply而不是的包装mapply。感谢150
Vlo

这一直困扰着我,因为我认为应该有一种row,column直接与成对索引的矩阵,[而不是必须经过mapply(或Map),因此我找到了一种方法。我还记得write存在并且可以替换cat112个字节
朱塞佩

@Giuseppe我对“”的评论不起作用,但是使用[<-,我们可以设法将所有内容压缩在一行中,而无需某些变量定义。110字节:tio.run
##

6

Python 2中140个 135 133字节的

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

在线尝试!


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

有趣的是,我无法编译(没有主程序),但TIO可以
ngn

1
@ngn 这只是一个函数,您需要添加对其main进行编译。在TIO上,main位于页脚部分。
Steadybox

3

Clojure,417319字节

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

更新资料

受奥利维耶(Olivier)评论的激励,我设法削减了多个reverse电话,并运用了一些一般的高尔夫技巧来削减角色。此外,我创建了别名reversemap-indexedconcatrepeatstr因为我用他们每个多次。

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

不打高尔夫球

(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并返回行列表的函数。


这不是答案,因为显然根本没有尝试打高尔夫球(您甚至可以这么说)。
奥利维尔·格雷戈尔

好吧,这好多了!;-)
OlivierGrégoire18年

3

木炭33 31字节

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

在线尝试!链接是详细版本的代码。编辑:由于仅@ASCII,节省了2个字节。说明:

≔⁰η

将当前字母初始化为大写字母0的索引。

F…±N⊕θ«

从输入的取反到包含的输入进行循环。

¿ι→↓

通常,每列都位于前一列的右侧。但是,没有零列。相反,需要进行校正以确保左侧和右侧对齐。

F↔ι«

循环搜索列中的每个字母。

P§αη

打印当前字母。

≦⊕η

增加字母索引。

¿›ι⁰↓↑

根据我们所处轨迹的哪一侧向上或向下移动。


似乎可以采用更短的方法来执行此操作,但不确定如何:/
仅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。:)
Dom Hastings

1
@DomHastings Yours很好地尝试了两个几乎重复的字母计算之间的协同作用。那也让我很生气。
Ton Hospel '18

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字节替换numpy的代码生成字符AZ((r_[0:2*N]%26+65).view('U1')[::2]含)map,所建议的在这里



2

J78 75字节

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

在线尝试!

-3感谢ngn


1
(,|.)@i.@-->i.@-,i.
ngn

谢谢@ngn。这是那些地方的一个感觉好像应该有40-50个字节的解决方案,但如果我没能看到它....
乔纳



1

Yabasic,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字节

接受输入并发射大炮。由于屏幕尺寸的限制,ñ 一定是 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}

半小时的工作量,并努力减少了一些字节,但是在这里可能还有很多事情可以做。会回到它。有趣的挑战!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.