Crea una ciudad ABACABA


17

Aquí está la tercera ciudad de ABACABA:

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

Está hecho de la secuencia ABACABA , que es básicamente:

  • A (primera iteración)
  • lugar B - AB
  • repetir A - ABA (segunda iteración)
  • Lugar C - ABAC
  • Repetir ABA - ABACABA (3ra iteración)

y te haces una idea.

Los edificios tienen una altura (correspondiente al número de guiones bajos) igual a las letras convertidas en números como A = 1, B = 2, etc.

Entrada

Una iteración número 1 <= n <= 26.

Salida

La ciudad de ABACABA de orden n , incluidas las letras al comienzo de las líneas.


@DonMuesli Jaja sí. Se hará un hipervínculo en cuestión.

1
¿Qué necesitamos para generar cuando el número sea mayor que 26?
Adnan

Sí, por favor: D (no iba a ser fácil, ¿verdad?)

1
Eso no contará como entrada válida.

2
¿Puede la entrada ser cero y, de ser así, cuál debería ser la salida? Además, no estaría de más enumerar las primeras, digamos, 4 entradas y salidas esperadas.
Zgarb

Respuestas:


6

Python 2, 82 bytes

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

Noté que nadie había publicado el método de recursividad binaria y decidí intentarlo ... y ahora, con un truco prestado de Sherlock9, ¡es la respuesta más corta de Python! (Además, gracias a xnor por una reducción más). (Y luego Dennis, que se afeitó un puñado más ...)

Sin golf:

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

Creo que entiendo esto y es bastante inteligente. Extrañaba totalmente esta agradable recursión. Puede guardar algunos caracteres concatenando en ambos lados en lugar de almacenarlos s, y haciendo que la segunda línea sea una función 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

Estaba pensando en hacer eso después ...
quintopia

@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)debería funcionar.
Dennis

@ Dennis sugiero implementar la solución anterior en Pyth. Sospecho que podría ser más corto que 59 bytes ... Lo haría, pero en este punto, es solo la mitad mía ...
quintopia

1
81 bytes como programa, la misma longitud que una función.
xnor

3

Python 2, 99 bytes

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

Para encontrar el inúmero th de la secuencia ABACABA, escriba ien binario, cuente el número de ceros finales y agregue uno. Usamos el clásico truco de bits i&-ipara encontrar la mayor potencia de 2esas divisiones i, luego calculamos la longitud de bits. En realidad, hacemos una cuenta iregresiva de 2**n-1a 0, lo cual está bien porque la secuencia ABACABA es simétrica.

Rastreamos tanto el número actual como el último de la secuencia con la ayuda de una variable "anterior" b. Esto nos dice cuántos guiones bajos para imprimir como "saliente". El edificio final se dibuja correctamente sin sobresalir porque 0se trata como si tuviera una longitud de bits 1.

El formato de cadena para imprimir se toma de Sp3000 , como es el truco de usar inputpara imprimir la primera línea.


3

MATL , 59 bytes

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

Esto usa la versión actual (15.0.0) del lenguaje.

Pruébalo en línea!


(Si las letras no tuvieran que incluirse en la salida: lo siguiente funcionaría, 48 bytes):

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

Explicación

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

Muy buena respuesta, pero también necesita imprimir las letras en frente de los edificios: p.
Adnan

Resuelto Esperando la aclaración de OP de todos modos
Luis Mendo

1
De hecho, ya pregunté esto, pero eliminé mi comentario. Sin embargo, esta fue la respuesta: p.
Adnan

Una solución muy elegante.

2

CJam, 37 35 bytes

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

Esta es una implementación iterativa del algoritmo recursivo de la respuesta de @ quintopia .

Pruébalo en línea!

Cómo funciona

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 bytes

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`

¿Dónde \nestá el carácter literal de nueva línea?


\nes al final, si alguien se lo preguntaba.
CalculatorFeline

1

Python 2, 123 121 bytes

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)

enlace ideone (-2 bytes gracias a @xsot)

fgenera la secuencia ABACABA como una lista de números, por ejemplo f(3) = [1, 2, 1, 3, 1, 2, 1]. El desplazamiento de la entrada por 1 en comparación con el desafío de secuencia ABACABA nos permite jugar desde un byte f.

La primera línea se imprime por separado, después de lo cual todas las demás líneas se imprimen utilizando una expresión que tiene en cuenta el número actual y el siguiente número. Solo por diversión, la primera línea se imprime usando input().


Se puede reemplazar [0]con L.
xsot

@xsot Ah, gracias, eso funciona bastante bien :) (¡así como xnor publica una respuesta!)
Sp3000

1

Pyth - 64 62 bytes

Probablemente se podría jugar más al golf, pero lo suficientemente bueno por ahora.

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

Pruébalo aquí!

Explicación:

            |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

Python 3.5 - 262 236 220 bytes:

-16 bytes gracias a @CatsAreFluffy! ¡Toda mi función ahora puede finalmente estar en una sola línea! :)

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

Puede ser un poco largo y puede imprimir nuevas líneas entre edificios, pero hace lo que necesita. Puede probarlo usted mismo para confirmarlo.

EDITAR:

Mi código de golf anterior no imprimió el patrón correcto en absoluto. Sin embargo, ahora el que se muestra arriba lo hace, y lo hace bien en mi opinión. También puede ejecutarlo usted mismo para confirmar eso.

Nota: El programa imprime todas las letras minúsculas detrás de cada "edificio". Espero que esté bien.

Versión sin golf con explicación:

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! :) )

Básicamente, lo que estoy haciendo es importar primero la función de diccionario ordenado del módulo de colecciones y luego crear un diccionario ordenado, con cada letra minúscula en la lista "j" asignada a su edificio correspondiente, con su longitud correspondiente en guiones bajos. Luego calculo la secuencia, en base a la entrada del usuario, usando la f=lambda w:"a"[w:]or f(w-1)+j[w]+f(w-1)función, y luego en función de la secuencia devuelta por eso, se imprimen los edificios, con la letra correspondiente de cada uno.


¿Se puede importar OrderedDictcomo en su olugar? Y cambiando opa py itema jtambién funciona.
Rɪᴋᴇʀ

Puedes colocar el if(todas las entradas son 1≤v≤26), el cambio range(26)a range(v), y utilizar return"\n".join(f(v))en lugar de la for.
CalculatorFeline

-2bytes: uso from collections import*y en o=OrderedDictlugar defrom collections import OrderedDict as o
CalculatorFeline

@CatsAreFluffy En realidad, cambiar range(26)a range(v)resultados en un Index Error. Además, hacer return"\n".join(f(v))SOLO devolverá la secuencia, pero no los edificios en sí. Aparte de eso, tus consejos fueron bastante buenos. ¡Gracias! :)
R. Kap

Bueno, no tengo Python 3.5 (tengo 3.4.1), tal vez es hora de actualizar ...
CalculatorFeline

0

Rubí, 129 bytes

Función anónima, devuelve una cadena multilínea.

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

Hay 2 líneas nuevas dentro de los backticks que son significativas y contadas.

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

... o 138 si las letras pueden estar en minúsculas.

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`

Menos golf

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

Prueba

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>


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.