创建ABACABA城市


17

这是ABACABA的第三个城市:

  _
A|_|
B|__|
A|_|_
C|___|
A|_|
B|__|
A|_|

它是由ABACABA序列组成的,该序列基本上是:

  • A(第一次迭代)
  • 地方B-AB
  • 重复A-ABA(第二次迭代)
  • 地方C-ABAC
  • 重复ABA-ABACABA(第3次迭代)

这样你就知道了。

建筑物的高度(对应于下划线的数量)等于将字母转换为数字,例如A = 1,B = 2等

输入项

迭代次数1 <= n <= 26。

输出量

顺序n的ABACABA城市,包括行首的字母。


@DonMuesli哈哈是的。将有问题的超链接。

1
当数字大于26时,我们需要输出什么?
阿德南

是的,请:D (不是那么容易吗?)

1
那将不算作有效输入。

2
输入可以为零吗?如果是,则输出应为零?同样,列出第一个输入(例如4个输入)和预期输出也无妨。
Zgarb '16

Answers:


6

Python 2,82字节

f=lambda n,s=1:n*"'"and"  _"*s+f(n-1,0)+"_"*(n-2)+"\n%c|%s|"%(64+n,"_"*n)+f(n-1,0)

我注意到没有人发布过二进制递归方法,并决定尝试一下……现在从Sherlock9借用了一个技巧,这是最短的python答案!(另外,感谢xnor的进一步缩短。)(然后是Dennis,他又剃了一些……)

取消高尔夫:

def f(n,s=1):
    if n>0:
        strsofar = "  _" if s==1 else ""        #prepend overhang for top-level call
        strsofar += f(n-1,0)                    #build the city above the current line
        strsofar += "_"*(n-2)                   #add the overhang to reach the current tower
        strsofar += "\n%c|%s|" % (64+n, "_"*n)  #write the current (center) line
        strsofar += f(n-1,0)                    #build the city below the current line
        return strsofar
    else: 
        return ""                               #only this line will be executed when n==0 (base case)

print "  _"+f(input())

我想我明白这一点,而且非常聪明。我完全错过了这种不错的递归。您可以通过在两侧串联而不是存储来保存一些字符s,并通过将第二行作为anon函数来实现:f=lambda n:n*"?"and f(n-1)+"_"*(n-2)+"\n%c|%s|"%(64+n,"_"*n)+f(n-1);lambda n:" _"+f(n)
xnor

我当时正在考虑下一步…
quintopia '16

@quintopia f=lambda n,s=1:n*"_"and" _"*s+f(n-1,0)+"_"*(n-2)+"\n%c|%s|"%(64+n,"_"*n)+f(n-1,0)应该起作用。
丹尼斯

@丹尼斯,我建议在Pyth中实现上述解决方案。我怀疑它可能短于59个字节...我会做,但目前为止,这只是我的一半...
quintopia

1
程序为81字节,功能长度相同
xnor

3

Python 2,99个字节

b=1;i=2**input('  _\n')-1
while i:i-=1;a=len(bin(i&-i))-2;print'%c|%s|'%(64+b,'_'*b)+'_'*(a+~b);b=a

要找到iABACABA序列的第th个数字,请用i二进制写,计算尾随零的数目,然后加1。我们使用经典的位技巧i&-i来找到该除法的最大2功效i,然后计算位长。实际上,我们i从倒数2**n-10,这很好,因为ABACABA序列是对称的。

我们借助“上一个”变量来跟踪序列的当前和最后一个数字b。这告诉我们要打印多少个下划线作为“突出端”。最终建筑物正确绘制,没有悬垂,因为0被视为具有位长1

用于打印的字符串格式取自Sp3000,这是使用input打印第一行的技巧。


3

MATL,59字节

vi:"t@wv]!-1hPXJtPvX>"'|'@Z"63+h6MJ2+X@)(]XhcJ64+!wh!32H:(!   

这使用该语言的当前版本(15.0.0)

在线尝试!


(如果输出中不必包含字母,则可以使用以下内容,48个字节):

vi:"t@wv]!-1hPXJtPvX>"' |'X@1=o)@Z"63+h6MJ2+X@)(

说明

v        % vertically concatenate the stack contents: gives an empty array
i:       % input number n. Generate [1,2,...,n]
"        % for each k in [1,2,...n]
  t      %   duplicate
  @      %   push k
  wv     %   swap, vertically concatenate
]        % end. Poduces the numeric ABACABA: [1 2 1 3 1 2 1]: ceiling heights
!        % transpose into a row
-1h      % append -1
PXJ      % reverse array. Copy into clipboard J
tP       % duplicate. Reverse again, so undo the reversing
v        % vertically concatenate reversed and non-reversed row arrays
X>       % max of each column. Gives array of wall heights: [1 2 2 3 3 2 2 1]
"        % for each value in that array
  '|'    %   push "floor" char
  @      %   push height
  Z"     %   create string with that many spaces
  63+    %   transform spaces into "wall" chars, '_'
  h      %   concatenate horizontally
  6M     %   push "floor" char '|' again, to be used as ceiling
  J      %   push array of ceiling heights
  2+X@)  %   index into that to get height of current building
  (      %   at that position, overwrite the string with '|'
]        % end
Xhc      % concatenate all strings into a 2D char array, padding with spaces
J        % push array of ceiling heights (numeric ABACABA sequence)
64+      % add 64 to transform into letters
!        % transpose into column array
wh       % swap, concatenate horizontally. This appends letters below the floor
!        % transpose
32H:(    % overwrite first two positions (in linear order) with spaces
!        % transpose back. Implicitly display

很好的答案,但是您还需要在建筑物前面输出字母:p。
阿德南

解决了。等待OP澄清反正
路易斯Mendo

1
我实际上已经问过了,但是我删除了我的评论。虽然是响应:p。
阿德南

一个非常优雅的解决方案。

2

CJam,37 35字节

SS'_Lri{[H)'_*_2>N@H'A+'|@'|6$]+}fH

这是@quintopia的answer的递归算法的迭代实现。

在线尝试!

怎么运行的

SS'_     e# Push two spaces and an underscore.
L        e# Push "".
ri       e# Read an integer I from STDIN.
{        e# For each H in [0 ... I-1]:
  [      e#   Set an array marker.
    H)   e#     Push Push H+1.
    '_*  e#     Push a string of that many underscores.
    _2>  e#   Push a copy and remove the first two underscores.
    N    e#   Push a linefeed.
    @    e#   Rotate the longer string of underscores on top of it.
    h'A+ e#   Add H to the character 'A', pushing the corresponding letter.
    '|  e#    Push a vertical bar.
    @   e#    Rotate the string of underscores on top of it.
    '|  e#    Push another vertical bar.
    6$  e#    Push a copy of the previous iteration (initially "").
  ]     e#   Wrap everything up to the former marker in an array.
}fH     e#

1

JavaScript(ES6),162个字节

n=>(a=[...Array(1<<n)]).map((_,i)=>i?(a[i]=String.fromCharCode(64+(n=1+Math.log2(i&-i)))+`|${"_".repeat(n)}|`,a[i-1]+='_'.repeat(--n&&--n)):a[i]='  _')&&a.join`\n`

\n文字换行符在哪里。


\n最后,如果有人想知道的话。
CalculatorFeline

1

Python 2中,123个 121字节

f=lambda n:n*[n]and f(n-1)+[n]+f(n-1)
L=f(input('  _\n'))
for i,j in zip(L,L[1:]+L):print'%c|%s|'%(64+i,'_'*i)+'_'*(j+~i)

ideone链接 (由于@ xsot,-2字节)

f生成ABACABA序列作为数字列表,例如f(3) = [1, 2, 1, 3, 1, 2, 1]。与ABACABA序列挑战相比,输入的偏移量为1,这使我们可以打入f

第一行单独打印,然后使用考虑当前编号和下一个编号的表达式打印所有其他行。只是为了好玩,使用来打印第一行input()


您可以替换[0]L
xsot

@xsot嗯,谢谢,效果很好:)(就像xnor发布答案一样!)
Sp3000

1

Pyth- 64 62字节

也许可以打更多的高尔夫球,但目前为止还足够好。

Lsl.&Jhb_J"  _"Vtt^2Qpr@G=ZyN1p"|_"p*\_Zp\|W<=hZyhNp\_)d)"A|_|

在这里尝试!

说明:

            |Predefined vars: Q = evaluated input, G = lowercase alphabet
L           |Lambda definition. y(b) = return (following code)
   .&       |bitwise and
     Jhb    |J = b + 1, pass b + 1 to the bitwise and
        _J  |-J
  l         | base 2
 s          |̲c̲o̲n̲v̲e̲r̲t̲ ̲t̲o̲ ̲i̲n̲t̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲
          "  _"                              |print "  _" with a trailing newline
               Vtt^2Q                        |For N in 2^Q - 2
                     pr      1               |print in caps
                         =ZyN                |Z = y(N) remember the first lambda?
                       @G                    |G[Z], basically convert 1-26 to A-Z
                              p"|_"          |print "|_", no trailing newline
                                   p*\_Z     |print "_" Z times
                                        p\|  |̲p̲r̲i̲n̲t̲ ̲"̲|̲"̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲ ̲
                                           W<=hZyhN             |While ++Z<y(N+1)
                                                   p\_          |print "_"
                                                      )k        |end while,
                                                                |print newline
                                                        )"A|_|  |end for,
                                                                |print "A|_|"

0

蟒3.5 - 262个 236 220字节:

-16个字节,感谢@CatsAreFluffy!现在,我的整个功能终于可以放在一行中了!:)

from collections import*
def a(v):o=OrderedDict;j=[chr(i+97)for i in range(26)];d=o((j[i],('  '+'_'*(i+1)+'\n'+j[i]+'|'+'_'*(i+1)+'|'))for i in range(26));f=lambda w:'a'[w:]or f(w-1)+j[w]+f(w-1);[print(d[g])for g in f(v)]

它可能会有点长,并且可能会在建筑物之间打印出新的线条,但需要做什么。您可以自己进行测试以确认。

编辑:

我以前的打高尔夫球代码无法正确打印图案。但是,现在上面显示的一个可以了,在我看来它确实很好。您也可以自己运行它来确认。

注意:该程序在每个“建筑物”后面打印所有小写字母。我希望可以。

取消说明的非高尔夫版本:

from collections import*
def a(v):
    o=OrderedDict # Assign the OrderedSict function to "o"
    j=[chr(i+97)for i in range(26)] # Create a list with all 26 lowercase letters of the alphabet
    d=o((j[i],('  '+'_'*(i+1)+'\n'+j[i]+'|'+'_'*(i+1)+'|'))for i in range(26)) # Create a dict assigning each letter it's corresponding building with its corresponding length
    f=lambda w:'a'[w:]or f(w-1)+j[w]+f(w-1) # Return the ABACABA sequence based on the user input
    [print(d[g])for g in f(v)] # Print out the building according to the sequence returned by the above lambda function (thanks to @CatsAreFluffy for this method to print it! :) )

基本上,我要做的是先导入collections模块的Ordered Dictionary函数,然后创建一个有序字典,将列表“ j”中的每个小写字母分配给其对应的建筑物,并在其下划线加相应的长度。然后,我根据用户的输入,使用f=lambda w:"a"[w:]or f(w-1)+j[w]+f(w-1)函数来计算序列,然后根据返回的序列,打印出带有相应字母的建筑物。


您可以导入OrderedDicto吗?和更改op,以pitemj也有效。
Rɪᴋᴇʀ

您可以删除if(所有输入均为1≤v≤26),更改range(26)range(v),然后使用return"\n".join(f(v))代替for
CalculatorFeline

-2bytes:使用from collections import*o=OrderedDict代替from collections import OrderedDict as o
CalculatorFeline

@CatsAreFluffy实际上,更改range(26)为会range(v)导致Index Error。同样,这样做return"\n".join(f(v))只会返回序列,而不会返回建筑物本身。除此之外,您的技巧还不错。谢谢!:)
R. Kap

好吧,我还没有Python 3.5(我有3.4.1),也许是时候升级了……
CalculatorFeline

0

Ruby,129个字节

匿名函数,返回多行字符串。

->x{a=->n{n<1?[]:(b=a[n-1];b+[n]+b)}
r="  _
"
a[x].zip(a[x][1,9**x]<<0).map{|n,m|r+=(64+n).chr+"|#{?_*n}|#{?_*(m+~n)if m>n}
"}
r}

0

JavaScript(ES6),143

反引号内有2个重要的换行符。

n=>`  _
`+(r=n=>n?[...r(n-1),n,...r(n-1)]:[])(n).map((x,i,t,u=n=>'|'+'_'.repeat(n>0&&n))=>String.fromCharCode(x+64)+u(x)+u(t[i+1]-x-1)).join`
`

...或138(如果字母可以小写)。

n=>`  _
`+(r=n=>n?[...r(n-1),n,...r(n-1)]:[])(n).map((x,i,t,u=n=>'|'+'_'.repeat(n>0&&n))=>(x+9).toString(36)+u(x)+u(t[i+1]-x-1)).join`

少打高尔夫球

n=>{
  // recursive function for ABACABA returning an array of integers
  var r=n=>n?[...r(n-1),n,...r(n-1)]:[]
  // function to build "|__..."
  // if argument <=0 just returns the vertical bar
  var u=n=>'|'+'_'.repeat(n>0&&n)
  var t = r(n)
  t = t.map((x,i)=>
    // current building + extension to the len of next building if needed
    String.fromCharCode(x+64)+u(x)+u(t[i+1]-x-1)
  )
  return ' _\n' // the top line is fixed
    + t.join('\n')
}

测试

solution=
n=>`  _
`+(r=n=>n?[...r(n-1),n,...r(n-1)]:[])(n).map((x,i,t,u=n=>'|'+'_'.repeat(n>0&&n))=>String.fromCharCode(x+64)+u(x)+u(t[i+1]-x-1)).join`
`

function update() {
  var n=+N.value
  if (n>=0 && n<=26) O.textContent=solution(n)
}

update()
#N { width: 2em }
N:<input id=N value=4 oninput='update()'><pre id=O></pre>


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.