Створіть місто ABACABA


17

Ось третє місто ABACABA:

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

Він складається з послідовності ABACABA , яка в основному:

  • A (перша ітерація)
  • місце B - AB
  • повтор A - ABA (2-а ітерація)
  • Місце C - ABAC
  • Повторіть ABA - ABACABA (третя ітерація)

і ви отримуєте ідею.

Будівля має висоту (відповідає кількості підкреслень), рівну літерам, перетвореним на цифри, як A = 1, B = 2 тощо

Вхідні дані

Ітерація № 1 <= n <= 26.

Вихідні дані

Місто ABACABA порядку порядку n , включаючи букви на початку рядків.


@DonMuesli Ха-ха так. Чи буде гіперпосилання під питанням.

1
Що нам потрібно вивести, коли число стає вище 26?
Аднан

Так, будь ласка: D (це не буде легко?)

1
Це не зараховується як дійсне введення.

2
Чи може вхід дорівнювати нулю, і якщо так, яким повинен бути вихід? Крім того, не завадило б перерахувати перші, скажімо, 4 входи та очікувані результати.
Згарб

Відповіді:


6

Пітон 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, це найкоротший відповідь пітона! (Також дякую xnor за ще одне вкорочення.) (А потім Денніс, який поголив ще жменю ...)

Безумовно:

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 f=lambda n,s=1:n*"_"and" _"*s+f(n-1,0)+"_"*(n-2)+"\n%c|%s|"%(64+n,"_"*n)+f(n-1,0)має працювати.
Денніс

@Dennis Я пропоную реалізувати вищезазначене рішення в 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

Щоб знайти iчисло номер послідовності ABACABA, запишіть iу двійковій формі , порахуйте кількість проміжних нулів і додайте їх. Ми використовуємо класичний бітовий трюк, i&-iщоб знайти найбільшу силу, 2що ділиться i, а потім обчислимо бітну довжину. На насправді, ми розраховуємо iвниз від 2**n-1до0 , це добре , тому що послідовність 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

Дуже приємна відповідь, але також потрібно вивести букви перед будівлями: с.
Аднан

Вирішено. Чекаємо роз'яснення ОП у будь-якому випадку
Луїс Мендо

1
Я насправді це вже запитував, але я видалив свій коментар. Це була відповідь, хоча: с.
Аднан

Дуже елегантне рішення.

2

CJam, 37 35 байт

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

Це ітеративна реалізація рекурсивного алгоритму з відповіді @ quintopia .

Спробуйте в Інтернеті!

Як це працює

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-посилання (-2 байти завдяки @xsot)

fгенерує послідовність ABACABA у вигляді списку чисел, напр f(3) = [1, 2, 1, 3, 1, 2, 1]. Зсув вхідного сигналу на 1 порівняно із завданням послідовності ABACABA дозволяє нам гольф на байт f.

Перший рядок друкується окремо, після чого всі інші рядки друкуються за допомогою виразу, який враховує поточне число та наступне число. Для розваги перший рядок друкується за допомогою input().


Ви можете замінити [0]на L.
xsot

@xsot О, дякую, це працює дуже добре :) (так само, як xnor
розміщує

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

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

В основному те, що я роблю, - це спочатку імпортувати впорядкований словник модуля колекції, а потім створити впорядкований словник, при цьому кожна літера з нижнього регістру у списку "j" присвоюється відповідній будівлі з відповідною довжиною в підкресленнях. Потім я обчислюю послідовність, спираючись на введення користувача, використовуючи f=lambda w:"a"[w:]or f(w-1)+j[w]+f(w-1)функцію, а потім на основі послідовності, повернутої цим, будівлі з кожним відповідним буквою за ним роздруковуються.


Чи можете ви імпортувати OrderedDictяк oнатомість? І зміни opв pі itemв jтеж працює.
Rɪᴋᴇʀ

Ви можете впустити if(всі входи 1≤v≤26), зміни range(26)в range(v), і використовувати return"\n".join(f(v))замість for.
CalculatorFeline

-2байт: використання from collections import*та o=OrderedDictзамістьfrom collections import OrderedDict as o
CalculatorFeline

@CatsAreFluffy Насправді змінюється range(26)на range(v)результат у Index Error. Крім того, виконувати return"\n".join(f(v))буде ТОЛЬКО повертає послідовність, але не самі будівлі. Крім цих, ваші поради були досить хорошими. Спасибі! :)
Р. Кап

Ну, у мене не дуже Python 3.5 (у мене 3.4.1), можливо, прийшов час оновити ...
CalculatorFeline

0

Рубін, 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>


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.