创建一个二进制标尺


22

给定数字n,生成此模式的前n列:

                               #
               #               #
       #       #       #       #
   #   #   #   #   #   #   #   #
 # # # # # # # # # # # # # # # #
################################ ...

在(1索引)n处的列的高度是n的二进制表示形式中的尾随0位数,再加上1。结果,底层填充了每一列,第二层填充了第二列,第三层填充了第四列,依此类推。

规则

  • 您可以通过任何标准方法输入和输出。
  • 您可以假定输入是1到999之间的一个整数(含)。
  • 只要模式是完整的,输出就可以包含任意数量的空格。
  • 该模式必须为1索引,并且格式必须与此处所示相同。
  • 您可以使用任何单个非空白字符代替#,但不能更改空格字符。

测试用例

1
#

2
 #
##

3
 # 
###

4
   #
 # #
####

5
   # 
 # # 
#####

7
   #   
 # # # 
#######

32
                               #
               #               #
       #       #       #       #
   #   #   #   #   #   #   #   #
 # # # # # # # # # # # # # # # #
################################

这里可以找到一些较大的测试用例。

计分

这是,因此每种语言中以字节为单位的最短代码获胜。



现在我可以用二进制来测量距离了!等等...
Okx

2
1.标尺必须水平吗?2.标记必须是#吗?
乔纳森·艾伦

1
@JonathanAllan 1.是,并且2.否,它们可以是任何单个非空格字符。我已将此添加到规则中。
ETHproductions

OEIS上的顺序:A001511
不是一棵树,

Answers:


11

Python 2,54个字节

i=n=input()
while i:i-=1;print((' '*~-2**i+'#')*n)[:n]

在线尝试!

打印带有大量前导空白。i从开始倒数的每一行n重复一个2**i-1空格模式,后跟一个#。重复此图案直到输入的标尺宽度n。这是通过将模式字符串乘以n并将第一个n字符乘以来完成的[:n]

可以通过将字符串格式化为等长替代格式来制作图案。

i=n=input()
while i:i-=1;print('%%%ds'%2**i%'#'*n)[:n]

可爱的切片方法更长。

n=input();s=~-2**n*' '+'#'
exec"s=s[1::2]*2;print s[:n];"*n

〜是-1还是+1?
斯坦·史特鲁姆

没关系,它是(-x)-1
Stan Strum


9

V17,16字节

é#Àñä}Är {ñÎÀlD

在线尝试!

十六进制转储:

00000000: e923 c0f1 e416 7dc4 7220 7bf1 cec0 6c44  .#....}.r {...lD

感谢@KritixiLithos节省了一个字节!

这种算法是可怕的效率不高,但它应该在理论上适用于任何大小的输入。

它通过生成以下模式的前n个迭代来工作:

#

 #
##

   #
 # #
####

       #
   #   #
 # # # #
########

               #
       #       #
   #   #   #   #
 # # # # # # # #
################

                               #
               #               #
       #       #       #       #
   #   #   #   #   #   #   #   #
 # # # # # # # # # # # # # # # #
################################

然后切掉除前n列以外的所有列。因此,这将产生大量的领先空白,但OP表示:

只要模式完好,输出中可以包含任意数量的空格

说明:

é#                      " Insert an '#'
  Àñ           ñ        " 'N' times:
    ä<C-v>}             "   Duplicate every line blockwise (duplicating horizontally instead of vertically)
           Ä            "   Duplicate the top line. This conveniently puts us on the first non-whitespace character (that is, '#')
            r           "   Replace this character with a space
              {         "   Move to the beginning of the buffer
                Î       " On every line:
                 Àl     "   Move 'N' characters to the right ('l' for right, makes sense, right?)
                   D    "   And delete everything after the cursor

我不确定,但是我认为您可以删除|
Kritixi Lithos

@KritixiLithos阿哈!事后看来,这是如此明显!谢谢你的提示。:)
DJMcMayhem

5

JavaScript(ES6),61 58字节

f=(n,c=n,s='')=>c?f(n,c>>1,s+s+' ')+`
`+(s+1).repeat(c):''

@ETHProductions节省了1个字节,然后当我看到可以使用任何字符时又节省了2个字节。

递归解决方案。

测试用例:

动画:


1
做得好。您可以更改c/2|0c>>1保存一个字节。
ETHproductions

很好,我需要重新了解按位运算符。
里克·希区柯克

4

APL(Dyalog),21字节

'# '[1+⊖0⍪∨⍀⊖2⊥⍣¯1⍳⎕]

在线尝试!

'# '[…`]索引字符串

 得到输入

 很多 ntegers

2⊥⍣¯1 转换为二进制,使用所需的位数(每一个数字)

 上下颠倒

∨⍀ 纵向累积或减少

0⍪ 在顶部连接零

 上下翻转(即再次向上翻转)

1+ 添加一个(用于基于1的索引)





2

Japt20 17字节

@Shaggy和@ETHproductions节省了3个字节

õ_¤q1 o Ä ço÷z w

在线尝试!

说明:

输入5

õ_¤q1 o Ä ço÷z w
õ           Ã       // Create a range [1...Input] [1,2,3,4,5]
 _                  // Map; At each item:
  ¤                 //   Convert to binary        ["1","10","11","100","101"]
   q1               //   Split on "1"             [["",""],["","0"],["","",""],["","00"],["","0",""]]
      o             //   Get the last item        ["","0","","00",""]
        Ä           //   Add 1                    [["1","01","1","001","1"]]
          ço        //   Fill with "o"            ["o","oo","o","ooo","o"]
             ·      // Join with new-lines        ["o\noo\no\nooo\no"]
              z     // Rotate 90 degrees          ["ooooo\n o o \n o   "]
                w   // Reverse                    ["   o \n o o \nooooo"]


@Shaggy实际上,您甚至不需要l
ETHproductions

@ETHproductions:是的,只是想通了。18字节
Shaggy


按位运算符的一个很酷的技巧是n&-n只捕获in中的最终1和所有尾随0s n。不确定这是否会有所帮助,但是值得一

2

C,84 74字节

f(i,l,m){putchar(32+3*!(i&m));i<l?f(i+1,l,m):m?putchar(10),f(1,l,m>>1):1;}

取消高尔夫:

void f(int counter, int length, int mask) {
    putchar((counter&mask) ? ' ' : '#');
    if(counter<length) {
        f(counter+1, length, mask);
    } else if(mask) {
        putchar('\n');
        f(1, length, mask>>1);
    }
}

测试:

int main() {
    f(1, 32, 1023);
    putchar('\n');
    f(1, 1, 1023);
    putchar('\n');
    f(1, 999, 1023);
    putchar('\n');
}

说明

再一次,递归在C语言中比迭代花费更少的字符,因此两个循环被表示为两个递归调用。

同样,C是使用布尔表达式玩技巧的一种出色语言,它允许决定#是通过表达式来表示空格还是将a 表示出来32+3*!(i&m)。空格的ASCII值为32,ASCII值为#35,因此如果在中设置了掩码中的任何位,我们将得到一个空白i


您甚至需要int i,l,m吗?
扎卡里

@ZacharyT不,原来我没有。感谢您保存这10个字节:-)
cmaster

2

Pyth,15字节

j_.tm*Nhx_.Bd1S

试试吧!

说明

j_.tm*Nhx_.Bd1S
    m         SQ   # map over the numbers from 0 to the implicit input (lambda variable: d)
          .Bd      # Convert d to a binary string: (12 -> 1100)
         _         # reverse: (1100 -> 0011)
        x    1     # get the location of the first 1 ( 2 )
     *Nh           # make one more than that " quotation marks (""")
 _.t               # transpose the list of quotation mark strings and reverse it
j                  # join on newline

@JasonS这是一种基于Python的高尔夫语言!我现在链接了pyth的github。我想试试看!链接到在线执行器就足够了。
KarlKastor


1

JavaScript(ES8),71个字节

padStart()函数在ECMAScript中介绍了2017年!

N=>eval(`for(s='',n=1;n<=N;n*=2)s='\\n'+'#'.padStart(n).repeat(N/n)+s`)


JavaScript(ES6),77个字节

N=>eval(`for(s='',n=1;n<=N;n*=2)s='\\n'+(' '.repeat(n-1)+'#').repeat(N/n)+s`)


1
@RickHitchcock已修复。
darrylyeo

1

Mathematica,69个字节

Rotate[Grid["#"~Table~#&/@(IntegerExponent[2*#,2]&/@Range[#])],Pi/2]&

1

WESRRMICGSE):237个字节

IF(ROW()<=FLOOR(LOG(COUNTA(R1C:R[-1]C,R[1]C:R[1024]C)+1,2),1)+2,LEFT(REPT(REPT(" ",FLOOR(POWER(2,LOG(COUNTA(R1C:R[-1]C,R[1]C:R[1024]C)+1,2)-ROW()+2),1)-1) &"#",COUNTA(R1C:R[-1]C,R[1]C:R[1024]C)+1),COUNTA(R1C:R[-1]C,R[1]C:R[1024]C)+1),"")

好的。的时间。

首先,COUNTA(R1C:R[-1]C,R[1]C:R[1024]C)+1简单地替换所有内容[i],以进行输入。令牌会计算包含公式的单元格(不包括自身)的数量,然后加一个以包含自身。由于WESRRMICGSE会根据您提供的输入拖动公式,因此该标记始终会产生输入。

我们有:

IF(ROW()<=FLOOR(LOG([i],2),1)+3,LEFT(REPT(REPT(" ",FLOOR(POWER(2,LOG([i],2)-ROW()+2),1)-1) &"#",[i]),[i]),"")

这更具可读性。您会经常看到FLOOR(LOG([i],2),1)令牌,这意味着采用最接近2的幂,该幂小于输入([i])的数字。例如:4->4, 5->4, 6->4, 7->4, 8->8 ...etc。我将替换为GS[[i]]

IF(ROW()<=GS[[i]]+3,LEFT(REPT(REPT(" ",,FLOOR(POWER(2,LOG([i],2)-ROW()+2),1),1)-1) &"#",[i]),[i]),"")

更好。分解if子句,我们正在测试行是否小于或等于GS[[i]]+3,因为所有标尺的高度都等于GS [[i]] + 1,这将选择与行的高度相等的行。统治者。+1对于1索引行,和+1再次用于WESRRMICGSE偏移量。

FALSE结果产生一个空的细胞(“”),和真正的结果收率LEFT(REPT(REPT(" ",,FLOOR(POWER(2,LOG([i],2)-ROW()+2),1),1)-1) &"#",[i]),[i])

目前仍在编辑中,敬请期待



1

k,33个字节

`0:|" #"{(1+!x){~y!x}/:(x>)(2*)\1}

这似乎仅在AW的解释器中有效

在AW的解释器中工作的示例。

oK版本(您可以在线尝试)似乎存在错误,需要稍作更改才能使其起作用:

`0:|" #"{(1+!x){~y!x}/:{x>y}[x](2*)\1}

1

C#,174个字节

此方法有两个参数,一个是标尺长度的输入,另一个是作为字符串的标尺的输出。

打高尔夫球:

void R(int n,out string s){var l=new int[++n];int i,x=n,y=0;for(s="";x-->1;)for(i=0;0==(l[x]=(x>>i++&1)*i);y=y<i?i:y);for(y++;y-->0;s+='\n')for(x=0;++x<n;s+=y<l[x]?'#':' ');}

缩进:

void R(int n,out string s){                       // Return the result in an out parameter.
    var l=new int[++n];                           // Use a 1-based array.
    int i,x=n,y=0;                                //
    for(s="";x-->1;)                              // For each number x on the ruler
        for(i=0;0==(l[x]=(x>>i++&1)*i);y=y<i?i:y) // ... find lowest set bit of x, counting the maximum value.
            ;                                     //
    for(y++;y-->0;s+='\n')                        // Count down each line.
        for(x=0;++x<n;s+=y<l[x]?'#':' ')          // Output # for numbers that are tall enough.
            ;                                     //
}

在线尝试!


将转换为Func<int, string>保存您一些字节吗?
TheLethalCoder

1

木炭27 23字节

↶F…·¹N«Jι⁰#W¬﹪鲫A÷ι²ι#

在线尝试!链接是详细版本的代码。编辑:通过切换到保存了4个字节JumpTo


它仍然是绝对的,只是现在它被称为JumpTo(对不起)
仅限ASCII

仅限@ASCII啊,Wiki可以进行更新。(或者我想如果您要授予我编辑权限,我可以做...)
尼尔(Neil


您有GitHub帐户吗?
仅ASCII码

@只有ASCII码,我有两个...我无法决定哪个更合适...
Neil

1

J,38个字节

3 :'|.|:''#''#~,.(1+|.i.1:)@#:"0>:i.y'

不是很好。如果字节计数关闭,则显示Lmk-我在手机上。


对我来说看起来像38,除非3输入了开头...
ETHproductions's

@ETHproductions谢谢,从默认定义的耻辱切换并没有保存任何字节...
科尔

1
28个字节,含0|.@|:'#'#"0~1#.2~:/\i.#:@,]
英里

0

Java(OpenJDK 8),91字节

n->{int i=10,j;String s="";for(;i-->0;s+="\n")for(j=0;j++<n;)s+=j>>i<<i<j?' ':35;return s;}

在线尝试!

取消高尔夫:

n->{
    int i=10,j; // Since we are allowed extra whitespace, set columns always to 10
    String s = "";
    for(;i-->0;s+="\n")      // Every iteration add a newline, i=9..0
        for(j=0;j++<n;)      // j=1..n+1
            s+= j>>i<<i<j    // if j has less than i trailing 0s in binary form
                ?' '         // add a space else
                :35          // # (java handles ternary return types weirdly)
}



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.