Utwórz miasto ABACABA

17

Oto trzecie miasto ABACABA:

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

Jest on wykonany z sekwencji ABACABA , która jest w zasadzie:

  • A (pierwsza iteracja)
  • miejsce B - AB
  • powtórz A - ABA (2. iteracja)
  • Miejsce C - ABAC
  • Powtórz ABA - ABACABA (3. iteracja)

i masz pomysł.

Budynki mają wysokość (odpowiadającą liczbie znaków podkreślenia) równą literom zamienionym na liczby jako A = 1, B = 2 itd.

Wejście

Liczba iteracji 1 <= n <= 26.

Wynik

Miasto ABACABA rzędu n , w tym litery na początku wiersza.

Społeczność
źródło
@DonMuesli Haha tak. Czy odnośnik będzie dotyczył?
1
Co musimy wygenerować, gdy liczba wzrośnie powyżej 26?
Adnan
Tak, proszę: D (to nie będzie łatwe, prawda?)
1
To nie będzie liczone jako prawidłowe dane wejściowe.
2
Czy dane wejściowe mogą wynosić zero, a jeśli tak, jakie powinny być dane wyjściowe? Również nie zaszkodzi wymienić pierwsze, powiedzmy, 4 wejścia i oczekiwane wyniki.
Zgarb,

Odpowiedzi:

6

Python 2, 82 bajty

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

Zauważyłem, że nikt nie opublikował metody rekurencji binarnej i postanowiłem spróbować ... a teraz, dzięki sztuczce zapożyczonej z Sherlocka9, jest to najkrótsza odpowiedź na pytanie w pythonie! (Ponadto, dzięki xnor za jeszcze jedno skrócenie.) (A potem Dennis, który ogolił garść więcej ...)

Nie golfowany:

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())
kwintopia
źródło
Myślę, że to rozumiem i to całkiem sprytne. Całkowicie przegapiłem tę miłą rekurencję. Możesz zapisać niektóre znaki, łącząc je po obu stronach, zamiast je przechowywać s, i ustawiając drugą linię jako funkcję f=lambda n:n*"?"and f(n-1)+"_"*(n-2)+"\n%c|%s|"%(64+n,"_"*n)+f(n-1);lambda n:" _"+f(n)
anonową
Myślałem o zrobieniu tego dalej ...
kwintopia
@ 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)powinna działać.
Dennis
@ Dennis Sugeruję wdrożenie powyższego rozwiązania w Pyth. Podejrzewam, że może być krótszy niż 59 bajtów ... Zrobiłbym to, ale w tym momencie jest tylko w połowie mój ...
kwintopia
1
81 bajtów jako program, taka sama długość jak funkcja.
xnor
3

Python 2, 99 bajtów

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

Aby znaleźć inumer th sekwencji ABACABA, pisz iw formacie binarnym, policz liczbę końcowych zer i dodaj jeden. Używamy klasycznej sztuczki bitowej i&-ido znalezienia największej potęgi 2tego podziału i, a następnie obliczamy długość bitu. Tak naprawdę liczymyi od 2**n-1do 0, co jest w porządku, ponieważ sekwencja ABACABA jest symetryczna.

Śledzimy zarówno bieżącą, jak i ostatnią liczbę sekwencji za pomocą „poprzedniej” zmiennej b . To pokazuje nam, ile znaków podkreślenia należy wydrukować jako „zwis”. Ostateczny budynek jest rysowany poprawnie bez zwisu, ponieważ 0jest traktowany jako bitowy 1.

Format ciągu do drukowania jest pobierany ze Sp3000 , podobnie jak sztuczka polegająca inputna wydrukowaniu pierwszego wiersza.

xnor
źródło
3

MATL , 59 bajtów

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

Używa bieżącej wersji (15.0.0) języka.

Wypróbuj online!


(Jeśli litery nie musiałyby być zawarte w danych wyjściowych: działałyby następujące, 48 bajtów):

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

Wyjaśnienie

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
Luis Mendo
źródło
Bardzo ładna odpowiedź, ale musisz także wysyłać litery przed budynkami: str.
Adnan
Rozwiązany. W każdym razie oczekiwanie na wyjaśnienie OP
Luis Mendo
1
Właściwie już o to zapytałem, ale usunąłem swój komentarz. To była odpowiedź: p.
Adnan
Bardzo eleganckie rozwiązanie.
2

CJam, 37 35 bajtów

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

Jest to iteracyjna implementacja algorytmu rekurencyjnego z odpowiedzi @ quintopia .

Wypróbuj online!

Jak to działa

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#
Dennis
źródło
1

JavaScript (ES6), 162 bajty

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`

Gdzie \njest dosłowny znak nowej linii.

Neil
źródło
\njest na końcu, jeśli ktoś się zastanawia.
CalculatorFeline
1

Python 2, 123 121 bajtów

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)

link ideone (-2 bajty dzięki @xsot)

fgeneruje sekwencję ABACABA jako listę liczb, np f(3) = [1, 2, 1, 3, 1, 2, 1]. Przesunięcie danych wejściowych o 1 w porównaniu do wyzwania sekwencji ABACABA pozwala nam zagrać w bajtf .

Pierwszy wiersz jest drukowany osobno, a następnie wszystkie inne wiersze są drukowane przy użyciu wyrażenia uwzględniającego bieżący numer i następny numer. Dla zabawy pierwsza linia jest drukowana przy użyciu input().

Sp3000
źródło
Można wymienić [0]z L.
xsot
@xsot Ah dzięki, to działa całkiem dobrze :) (tak jak xnor wysyła odpowiedź!)
Sp3000
1

Pyth - 64 62 bajty

Prawdopodobnie można by grać w golfa więcej, ale na razie wystarczy.

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

Wypróbuj tutaj!

Wyjaśnienie:

            |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|_|"
K Zhang
źródło
0

Python 3.5 - 262 236 220 bajtów:

-16 bajtów dzięki @CatsAreFluffy! Moja cała funkcja może teraz być wreszcie w jednym wierszu! :)

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

Może być trochę długi i może drukować nowe linie między budynkami, ale robi to, czego potrzebuje. Możesz to przetestować samodzielnie, aby to potwierdzić.

EDYTOWAĆ:

Mój poprzedni kod w golfa nie wydrukował właściwie żadnego wzoru. Jednak teraz ten pokazany powyżej ma i moim zdaniem robi to dobrze. Możesz również uruchomić go dla siebie, aby to potwierdzić.

Uwaga: Program drukuje wszystkie małe litery za każdym „budynkiem”. Mam nadzieję, że to w porządku.

Wersja bez golfa z Objaśnieniem:

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

Zasadniczo to, co robię, to najpierw zaimportować funkcję Uporządkowanego słownika modułu kolekcji, a następnie utworzyć uporządkowany słownik, przy czym każda mała litera na liście „j” jest przypisana do odpowiedniego budynku, z odpowiednią długością w podkreśleniach. Następnie obliczam sekwencję, na podstawie danych wejściowych użytkownika, używając f=lambda w:"a"[w:]or f(w-1)+j[w]+f(w-1)funkcji, a następnie na podstawie sekwencji zwróconej przez to, budynki, z odpowiadającymi im literami, są drukowane.

R. Kap
źródło
Można importować OrderedDictjako ozamiast? I zmienia opsię pi itemdo jroboty też.
Rɪᴋᴇʀ
Możesz upuścić if(wszystkie dane wejściowe to 1≤v≤26), zmienić range(26)na range(v)i użyć return"\n".join(f(v))zamiast for.
CalculatorFeline
-2 bajty: użyj from collections import*i o=OrderedDictzamiastfrom collections import OrderedDict as o
CalculatorFeline
@CatsAreFluffy Właściwie zmiana range(26)na range(v)wyniki w Index Error. Ponadto, robi return"\n".join(f(v))tylko zwraca sekwencję, ale nie same budynki. Poza tym twoje wskazówki były całkiem dobre. Dzięki! :)
R. Kap
Cóż, nie do końca mam Python 3.5 (mam 3.4.1), może czas na uaktualnienie ...
CalculatorFeline
0

Ruby, 129 bajtów

Funkcja anonimowa zwraca ciąg wielowierszowy.

->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}
Wartość tuszu
źródło
0

JavaScript (ES6), 143

W backtickach znajdują się 2 nowe linie, które są znaczące i zostały policzone.

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

... lub 138, jeśli litery mogą być małe.

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`

Mniej golfa

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

Test

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>

edc65
źródło
0

PowerShell, 67 bajtów

1..(Read-Host)|%{'  _'}{$x+=@([char]($_+96)+'|'+'_'*$_+'|')+$x}{$x}
Jonathan Leech-Pepin
źródło