Створіть бінарну лінійку


22

Давши число n , генеруйте перші n стовпців цього шаблону:

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

Висота стовпця при (1-індексованому) n - кількість кінцевих 0бітів у бінарному поданні n 'плюс один. В результаті нижній шар заповнює кожен стовпчик, другий шар - кожен другий стовпчик, третій шар - кожен четвертий стовпець тощо.

Правила

  • Ви можете вводити та виводити будь-який стандартний метод.
  • Ви можете припустити, що вхід є цілим числом від 1 до 999 включно.
  • Вихід може містити будь-яку кількість пробілів, якщо шаблон є неушкодженим.
  • Візерунок повинен бути 1-індексованим та у тому ж форматі, як показано тут.
  • Ви можете використовувати будь-який символ, який не є пробілом, замість цього #, але ви не можете змінити пробільний символ.

Тестові кейси

1
#

2
 #
##

3
 # 
###

4
   #
 # #
####

5
   # 
 # # 
#####

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

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

Кілька великих тестів можна знайти тут .

Оцінка балів

Це , тому виграє найкоротший код у байтах на кожній мові.



Тепер я можу виміряти відстань у двійковій! О зачекайте ...
Okx

2
1. Чи повинна лінійка бути горизонтальною? 2. Чи повинні бути маркування #?
Джонатан Аллан

1
@JonathanAllan 1. Так, і 2. Ні, вони можуть бути будь-яким одним непросторовим символом. Я додав це до правил.
ETHproductions

Послідовність на OEIS: A001511
Не дерево

Відповіді:


11

Python 2 , 54 байти

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

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

Друкує з великою кількістю провідних пробілів. Кожен рядок, iвідлік від nповторення шаблону 2**i-1пробілів, що супроводжується символом a #. Ця картина повторюється до ширини лінійки, яка є входом 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

10

Python 3 , 74 байти

n=int(input())
a=1
while a<n:a*=2
while a:print(("%%%dd"%a%4*n)[:n]);a//=2

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


Нічого собі, мені потрібно було трохи часу, щоб зрозуміти, як створюються рядки. Молодці.
ETHproductions

2
a=2**len(bin(n))за 72 байти
ов

2
Він швидко потрапить на помилки пам’яті та надрукує купу зайвого простору (дозволено) - але ви можете зробити 54 за допомогою Python 2 .
Джонатан Аллан

9

V , 17 , 16 байт

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

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

Hexdump:

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

Дякуємо @KritixiLithos за збереження одного байта!

Цей алгоритм жахливо неефективний, але він повинен теоретично працювати для будь-якого введення розміру.

Це працює, генеруючи перші n ітерацій наступного шаблону:

#

 #
##

   #
 # #
####

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

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

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

А потім рубати всі, крім перших n стовпців. Таким чином, це призведе до тонни провідних пробілів, але ОП заявила:

Вихід може містити будь-яку кількість пробілів, якщо шаблон є неушкодженим

Пояснення:

é#                      " 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):''

Збережено 1 байт завдяки @ETHProductions, а потім ще 2 байти, коли я побачив, що будь-який символ може бути використаний.

Рекурсивне рішення.

Тестові приклади:

Анімація:


1
Молодці. Ви можете змінити , c/2|0щоб c>>1зберегти байти.
ETHproductions

Приємно, мені потрібно розібратися на своїх розрядних операторах.
Рік Хічкок

4

APL (Dyalog) , 21 байт

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

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

'# '[… `] Індексуйте рядок за допомогою

 отримати вхід

 що багато я ntegers

2⊥⍣¯1 перетворити в двійковий, використовуючи стільки цифр, скільки потрібно (по одному номеру в кожному стовпці )

 перевернути догори дном

∨⍀ вертикальне кумулятивне АБО зменшення

0⍪ з'єднати нулі зверху

 перевернути догори дном (тобто знову створити резервну копію)

1+ додати один (для індексації на основі 1)





2

Japt , 20 17 байт

Збережено 3 байти завдяки @Shaggy та @ETHproductions

õ_¤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щоб захопити тільки остаточні 1і все трейлинг 0s в n. Не впевнений, чи це допоможе, але варто зняти ...
ETHproductions

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 - це чудова мова для гри з трюками з булевими виразами, що дозволяє вирішити, чи слід ставити пробіл або a, #висловлюючись виразом 32+3*!(i&m). Пробіл має значення ASCII 32, #ASCII 35, тому ми отримуємо пробіл, якщо встановлено будь-який біт у масці i.


Вам навіть потрібен int i,l,m?
Zacharý

@ZacharyT Ні, виявляється, я цього не зробив. Дякуємо, що
зберегли

2

Піт , 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! Тепер я пов’язав github pyth . Я подумав Спробуйте! посилання на Інтернет-Виконавця було б достатньо.
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

Математика, 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),"")

Добре. 'splaining time.

По-перше, замініть кожен 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.

The 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 Тільки Ах, вікі можуть зробити оновлення. (Або я припускаю, що я міг би це зробити, якщо ви хочете надати мені дозвіл на редагування ...)
Ніл,

@ ASCII Тільки так, я мав би пам’ятати, що з codegolf.stackexchange.com/a/119904 ...
Ніл

У вас є обліковий запис GitHub?
Лише ASCII

@ ASCII-тільки у мене є два ... Я не можу вирішити, який з них підходить ...
Ніл

1

J, 38 байт

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

Не великий. Lmk, якщо кількість байтів вимкнено - я в телефоні.


Мені здається 38, якщо тільки 3на початку не введено…
ETHproductions

@ETHproductions спасибі, сором, що перехід від мовчазного визначення не врятував жодних байт ...
cole

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



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