Нарисуй большой ASCII X


20

проблема

Вдохновленный предыдущим испытанием, делающим что-то подобное

С учетом положительного целочисленного ввода nвыведите форму, которая следует этому шаблону:

вход n=1:

* *
 *
* *

вход n=2:

**  **
 ****
  **
 ****
**  **

вход n=3:

***   ***
 *** ***
  *****
   ***
  *****
 *** ***
***   ***

и так далее...

У него есть эти свойства:

n*2+1 высокие линии

«руки» n широко, за исключением случаев, когда они сливаются

центральная линия nширокая

если nчетные линии выше и ниже центра n*2широкие

если nнечетно, линии выше и ниже центра n*2-1широкие

правила

  • Конечные переводы приняты
  • Применяются стандартные лазейки
  • Кратчайшие байты выигрывают
  • Вывод может быть распечатан или строка или массив строк

Правки

  • n=0 не нужно обрабатывать
  • Трейлинг допускается

2
Это нормально, если на выходе 1вместо *и 0вместо пробела?
JungHwan Мин.

Могут ли наши шаблоны быть проиндексированы?
Утренняя монахиня

@JungHwanMin Я разрешаю, но тогда вам не разрешают выигрывать, возможно, это повлияет на вас, если за вас проголосуют больше всего.
LiefdeWen

@LeakyNun 0 Индексируется хорошо
LiefdeWen

Ответы:


9

Древесный уголь , 13 12 байт

Спасибо @ErikTheOutgolfer за байт

FN«PX⁺*×*Iθ→

Попробуйте онлайн!

Это мой первый в истории ответ на вопрос об угле, и я уверен, что он не так хорош, как мог, но я решил, что начну где-нибудь.

 FN«            # For input() (i in range(0,input()))
     P           # Print
       X          # In an 'X' shape
        ⁺*×*Iθ   # '*'+'*'*int(first_input)
               →  # Move the cursor right one


@EriktheOutgolfer Я знал, что должен быть способ сделать это! Спасибо!
nmjcman101

И да, это на самом деле кажется, как гольф, как это может быть.
Эрик Outgolfer

@EriktheOutgolfer Это было не раньше, чем вы все равно пришли :)
nmjcman101

1
@thomasrutter Charcoal имеет свою собственную кодовую страницу с 256 байтами , где каждый из этих символов равен 1 байту. Так что он не закодирован в ASCII, где некоторые из этих символов действительно будут состоять из нескольких байтов. nmjcman101 +1 между прочим Вчера я тоже пробовал свой первый ответ на древесный уголь, но он не сработал за те несколько минут, которые у меня были до того, как я вернулся домой с работы. Таким образом, вы победили меня в этом. Я узнал кое-что из твоего ответа, так что спасибо за это.
Кевин Круйссен

13

MATL , 16 байт

EQXyG:Y+tP+g42*c

Попробуйте онлайн!

объяснение

Рассмотрим ввод 2в качестве примера. Содержимое стека показано ниже.

EQ    % Implicitly input n. Push 2*n+1
      %   STACK: 5
Xy    % Identity matrix of that size
      %   STACK: [1 0 0 0 0;
                  0 1 0 0 0;
                  0 0 1 0 0;
                  0 0 0 1 0;
                  0 0 0 0 1]
G:    % Push [1 2 ... n]
      %   STACK: [1 0 0 0 0;
                  0 1 0 0 0;
                  0 0 1 0 0;
                  0 0 0 1 0;
                  0 0 0 0 1],
                 [1 2]
Y+    % 2D convolution, extending size
      %   STACK: [1 2 0 0 0 0;
                  0 1 2 0 0 0;
                  0 0 1 2 0 0;
                  0 0 0 1 2 0;
                  0 0 0 0 1 2]
tP+   % Duplicate, flip vertically, add
      %   STACK: [1 2 0 0 2 1;
                  0 1 2 1 2 0;
                  0 0 1 4 0 0;
                  0 1 2 1 2 0;
                  1 2 0 0 1 2]
g     % Convert to logical
      %   STACK: [1 1 0 0 1 1;
                  0 1 1 1 1 0;
                  0 0 1 1 0 0;
                  0 1 1 1 1 0;
                  1 1 0 0 1 1]
42*   % Multiply by 42.
      %   STACK: [42 42  0  0 42 42;
                   0 42 42 42 42  0;
                   0  0 42 42  0  0;
                   0 42 42 42 42  0;
                  42 42  0  0 42 42]
c     % Convert to char. Char 42 is '*'. Char 0 is displayed as space
      %   STACK: ['**  **';
                  ' **** ';
                  '  **  ';
                  ' **** ';
                  '**  **']

Ты быстрее меня ...
Дрянная Монахиня

@LeakyNun Очень редко :-)
Луис Мендо

Я бы хотел, чтобы у Джелли была свёртка 2D ... Мне нужно было добавить 0 в каждой строке, а затем применить векторизованную сумму ...
Leaky Nun


1
@ LuisMendo В моем сердце вы победитель в использовании свертки, возвращает такие приятные воспоминания.
LiefdeWen

9

Желе , 15 байт

Ḥ‘Ḷ⁶ẋ;€”*ẋ$»Ṛ$Y

Попробуйте онлайн!


Очень хорошо. 8 байтов меньше меня.
Утренняя монахиня

@LeakyNun Прямой подход очень помогает.
Эрик Outgolfer

Очень хороший подход
Джонатан Аллан

@JonathanAllan Да, особенно когда ты учишься »векторизоваться ...
Эрик Аутгольфер

1
Мне очень нравится ваше имя пользователя! Но я бы хотел, чтобы вы использовали вместо этого «vi» или «vim», чтобы вы могли выбрать «Эрик, король vi» ... (здесь поклонник Монти Пайтона ...)
Оливье Дюлак

4

V , 18 17 байт

Сохраненный байт благодаря трюку ввода @ DJMcMayhem.

Àé*ÄJÀälÀñ2ÙÀl2x>

Попробуйте онлайн!

объяснение

Àé*ÄJÀäl

Это вставки [n]*'*'+[n]*' '+[n]*'*'

        Àñ        ' [arg] times
          2Ù      ' Duplicate the current line down twice
            Àl    ' Move right [arg] times
              2x  ' Delete two characters
                > ' Indent this line one space

Каждая итерация цикла, из которого идет буфер

|**   ***

к

***   ***
 |** ***
***   ***

Где |курсор с *под ним


Вау. Вы waaay outgolfed меня. Молодец! Несколько советов: вы можете сделать Àé*ÄJÀälвместо Àá*Àá Àá*, и вы можете сделать <M-c>, то есть ã(мнемоника: центр ), чтобы перейти к середине строки, которая на байт короче, чем Àl. Попробуйте онлайн!
DJMcMayhem

@DJMcMayhem Я пытаюсь поговорить с тобой в разных местах. Я собираюсь украсть первое предложение, которое я думаю, но <M-c>перерывы для больших чисел
nmjcman101

3

05AB1E , 18 байт

Å4bS{I·ƒDÂ~„ *èJ,À

Попробуйте онлайн!

объяснение

Пример для n=2

Å4                   # push a list of 4s with length as the input
                     # STACK: [4,4]
  b                  # convert each to binary
                     # STACK: [100, 100]
   S{                # split into digit list and sort
                     # STACK: [0, 0, 0, 0, 1, 1]
     I·ƒ             # input*2+1 times do
        D            # duplicate top of stack
                     # 1st iteration: [0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 1]
                     # 2nd iteration: [0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 0]
                     # 3rd iteration: [0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0]
         Â~          # or each item in the duplicate with its reverse
                     # 1st iteration: [0, 0, 0, 0, 1, 1], [1, 1, 0, 0, 1, 1]
                     # 2nd iteration: [0, 0, 0, 1, 1, 0], [0, 1, 1, 1, 1, 0]
                     # 3rd iteration: [0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0]
           „ *èJ     # use the resulting binary list to index into the string " *"
                     # 1st iteration: [0, 0, 0, 0, 1, 1], "**  **"
                     # 2nd iteration: [0, 0, 0, 1, 1, 0], " **** "
                     # 3rd iteration: [0, 0, 1, 1, 0, 0], "  **  "
                ,    # print
                 À   # rotate list left

3

V , 23 байта

Àé*ÄJÀälÀñÙãlxx>ñyHæGVp

Попробуйте онлайн!

HexDump:

00000000: c0e9 2ac4 4ac0 e46c c0f1 d9e3 6c78 783e  ..*.J..l....lxx>
00000010: f179 48e6 4756 70                        .yH.GVp

По какой-то причине эта задача значительно сложнее в V, чем предыдущая. Поскольку наш общий подход n раз, растущий 'x' здесь не сработает, мы вместо этого построим вершину X, скопируем ее и перевернем, а затем соединим две части вместе.

Объяснение:

Àé*ÄJÀäl                " Insert ('*' * n) + (' ' * n) + ('*' * n) 
                        " The obvious way would be 'Àé*ÀÁ ÀÁ*', but this 
                        " non-obvious way saves us a byte
        Àñ      ñ       " 'n' times:
          Ù             "   Duplicate this line (below us)
           ãl           "   Move to the center of this line
             xx         "   Delete two characters
               >        "   And indent this line with one space.

Делая отступ в конце цикла, мы можем использовать неявные окончания . Это также удобно создает n + 1 строк, которые являются точно верхней половиной «X». Допустим, входное значение было 4. Тогда на этом этапе буфер выглядит так:

****    ****
 ****  ****
  ********
   ******
    ****

И мы на последней строчке. Итак, мы:

                yH      " Copy the whole buffer and move to the first line
                  æG    " Reverse every line
                    Vp  " And paste what we just copied *over* the current
                        " line, deleting it in the process

ãxxСначала я тоже это сделал , но я думаю, что он сломался, например, при n = 8?
nmjcman101

@ nmjcman101 Ах, ты прав. Хорошо, если вы это сделаете ãl, или если вы сделаете отступ перед центрированием, но на самом деле это не спасает байты. Я не понимаю, почему это работает для меньших чисел, хотя.
DJMcMayhem

3

C #, 139 130 115 байтов

-1 байт, создав строку и вызвав ее WriteLine, сохранив при этом проверку новой строки.
-6 байт благодаря Кевину и его мастерским методам игры в гольф!
-2 байта путем замены n*3-nна n*2.
-15 байт после того, как Кевин любезно указал мне правильное направление: я могу просто вернуть строку вместо ее печати, сохранив, таким образом, вызов System.Console.WriteLine(). И некоторые другие советы также ...

n=>{var s="";for(int i,j=0;j<=n*2;j++,s+='\n')for(i=0;i<n*3;)s+=i>=j&i<j+n|i<=n*3-j-1&i++>=n*2-j?'*':' ';return s;}

Попробуйте онлайн!

Ungolfed:

class Program
{
    static void Main(string[] args)
    {
        System.Func<int, string> g = n =>
        {
            var s = "";
            for (int i, j = 0; j <= n*2; j++, s += '\n')
                for (i = 0; i < n*3;)
                    s += i >= j & i < j+n | i <= n*3-j-1 & i++ >= n*2-j ? '*' : ' ';
            return s;
        };

        System.Console.Write(f(1));
        System.Console.Write(f(2));
        System.Console.Write(f(3));
        System.Console.Write(f(5));
        System.Console.Write(f(8));

        System.Console.ReadKey();
    }
}

Он просто перебирает строки и столбцы пространства, необходимого для печати большого X, и печатает либо a, '*'либо a в ' 'зависимости от условия.


1
+1! Некоторые мелочи в гольф. Все &&может быть &и ||может быть |в этом случае. for(int j=0;может быть, for(int j=0,i;а затем вы можете удалить int перед iво внутренней петле. Кроме того, после первого изменения &и |вы также можете удалить i++внутреннюю часть цикла for и изменить i==n*3-1?...на i++==n*3-1?....
Кевин Круйссен

@KevinCruijssen большое спасибо! Я изменил внутренний цикл, и теперь я создаю строку, чтобы я мог позвонить WriteLine, сохранил только 1 байт. Так что теперь я не уверен, что делать с твоим последним советом.
Чарли

1
Кстати, почему System.Console.WriteLine? Возвращаем строку: n=>{string s="";for(int i,j=0;j<n*2+1;j++,s+="\n")for(i=0;i<n*3;)s+=i>=j&i<j+n|i<=n*3-j-1&i++>n*2-j-1?'*':' ';return s;}короче [ 120 байт ] (а также избавляемся от скобок, помещая все в цикл for. Вот TIO-ссылка чтобы показать, что она работает. Кроме того, не стесняйтесь добавлять это (или свое) TIO-ссылка на ваш ответ. :)
Кевин Круйссен

1
@KevinCruijssen Я не знал, что TIO может обрабатывать код C #! Я добавил WriteLineв код, потому что OP попросил вывести большой X, а не просто вернуть его, поэтому я чувствовал, что вывод X (путем вызова WriteLineметода) должен быть частью кода. Тем не менее, я до сих пор не привык к правилам код-гольфа и не знаю, какие лицензии я могу получить при написании кода. Я только что видел, что некоторые другие ответы здесь печатают X в коде, а некоторые другие печатают его в нижнем колонтитуле. Каков правильный подход в этом случае?
Чарли

1
Обычно по умолчанию допускается возврат строки, а также использование функции вместо программы, если не указано иное. Кроме того, в вопросе говорится: « Вывод может быть распечатан или является строкой или массивом строк », поэтому возврат строки возможен. :) И еще одна вещь, которую вы j<n*2+1можете играть в гольф: может быть j<=n*2. Я также создал порт Java 8 для вашего ответа с тем же количеством байтов, что, конечно, заслуживает вашего удивительного ответа.
Кевин Круйссен



2

MATLAB, 153 126 байт (17,6% ↓)

Благодаря комментарию @ LuisMendo, функция disp()может выводить символы без одинарных кавычек, поэтому я могу запретить использование fprintfс formatsи пропустить несколько байтов. Кроме того, его комментарий напоминает мне, что мне нужно использовать char(32)для представления пробела, а не char(0)(ноль).

n=input('')
r=2*n+1
c=3*n
a=0
for i=0:n-1
a=a+[zeros(r,i),diag(1:r),zeros(r,c-r-i)];
end
a((a+flipud(a))>0)=10
disp([a+32 ''])

Попробуйте онлайн!

MATLAB, 153 байта

n=input('')
r=2*n+1
c=3*n
a=0
for i=0:n-1 
a=a+[zeros(r,i),diag(1:r),zeros(r,c-r-i)];
end
a((a+flipud(a))>0)=42
fprintf([repmat('%c',1,c),'\n'],char(a)')

Пример результата: n = 10

**********          **********
 **********        ********** 
  **********      **********  
   **********    **********   
    **********  **********    
     ********************     
      ******************      
       ****************       
        **************        
         ************         
          **********          
         ************         
        **************        
       ****************       
      ******************      
     ********************     
    **********  **********    
   **********    **********   
  **********      **********  
 **********        ********** 
**********          **********

2

Python 2 , 93 90 89 83 байта

-3 байта благодаря Leaky Nun
-1 байт благодаря Zachary T
-6 байтов благодаря xnor

n=input()
x=n*'*'+n*'  '
exec"print`map(max,x,x[::-1])`[2::5];x=' '+x[:-1];"*(n-~n)

[Попробуйте онлайн!] [TIO-j3xwsktf]

Начинается со строки наподобие '*** 'for n=3, применяя map/maxдля выбора *пробелы для каждой позиции, затем добавляя пробел, удаляя последний символ из строки и повторяя все это.



Вы не можете заменить n*2*' 'на n*' '?
Захари

map(maxМожет быть сделано непосредственно без zip. Также n*2+1есть n-~n.
xnor

1

Haskell , 70 байт

f n=[[last$' ':['*'|y<-[1..n],(c-n-y)^2==r^2]|c<-[1..3*n]]|r<-[-n..n]]

Попробуйте онлайн!

Выводит список строк.

Для каждой позиции строки r, столбца c, используется формула, чтобы определить, попадает ли она в одну из двух диагональных полос, и так оно и есть *.



1

Javascript (ES2017), 155 157 байт

n=>[...e=[...Array(n+1)].map((a,i)=>[...d=((b=''.padEnd(n))[c='slice'](i)+'*'.repeat(n)+b[c](0,i))[c](n/2)].reverse().join``+d[c](n%1)),...e.reverse()[c](1)]

Возвращает массив строк. Я выполняю операции над массивами, затем отражаю их. Вероятно, это можно оптимизировать с помощью матриц, как и другие ответы, но я хотел быть уникальным.

Редактировать: Как отметил Нил, для четных значений nцентральная линия была не nширокой, поэтому я добавил модуль для определения четности / нечетности при разрезании столбца.

n=5
['*****     *****',
 ' *****   ***** ',
 '  ***** *****  ',
 '   *********   ',
 '    *******    ',
 '     *****     ',
 '    *******    ',
 '   *********   ',
 '  ***** *****  ',
 ' *****   ***** ',
 '*****     *****']

Ungolfed

n => {
  e = [...Array(n+1)].map((a, i) => {   // Create and iterate over array with n+1 elements
    b = ''.padEnd(n)                    // String of n spaces
    d = (b.slice(i) + '*'.repeat(n) + b.slice(0, i)).slice(n/2) // Create row string
    return [...d].reverse().join`` + d.slice(1) // Mirror and combine row horizontally
  })
  return [...e,...e.reverse().slice(1)] // Mirror and combine vertically
}

квадрант

n=5
   *****
  ***** 
 *****  
*****   
****    
***     

Зеркальный по горизонтали

n=5
*****     *****
 *****   ***** 
  ***** *****  
   *********   
    *******    
     *****     

Зеркальный по вертикали

n=5
*****     *****
 *****   ***** 
  ***** *****  
   *********   
    *******    
     *****     
    *******    
   *********   
  ***** *****  
 *****   ***** 
*****     *****

Это дает неправильный вывод для четного n- центральная линия не является nширокой.
Нил

0

Mathematica, 148 байт

T=Table;(a=Join[T[T["*",i],{i,(n=#)+2,2n,2}],T[Join[t=T["*",n],T[" ",y],t],{y,1,n,2}]];Column[Row/@Join[Reverse@a,{T["*",n]},a],Alignment->Center])&

0

R, 102 байта

Код:

n=scan();x=matrix(" ",M<-3*n,N<-2*n+1);for(i in 1:N)x[c(i-1+1:n,M+2-i-1:n),i]="*";cat(x,sep="",fill=M)

Тестовое задание:

> n=scan();x=matrix(" ",M<-3*n,N<-2*n+1);for(i in 1:N)x[c(i-1+1:n,M+2-i-1:n),i]="*";cat(x,sep="",fill=M)
1: 10
2: 
Read 1 item
**********          **********
 **********        ********** 
  **********      **********  
   **********    **********   
    **********  **********    
     ********************     
      ******************      
       ****************       
        **************        
         ************         
          **********          
         ************         
        **************        
       ****************       
      ******************      
     ********************     
    **********  **********    
   **********    **********   
  **********      **********  
 **********        ********** 
**********          **********

0

CJam, 24 байта

{:T2*){S*T'**+}%_W%..e>}

Это блок, который берет число из стека и выводит список строк в стек.

Объяснение:

{                        e# Stack:           | 2
 :T                      e# Store in T:      | 2, T=2
   2*                    e# Multiply by 2:   | 4
     )                   e# Increment:       | 5
      {                  e# Map over range:  | [0
       S                 e#   Push space:    | [0 " "
        *                e#   Repeat string: | [""
         T               e#   Push T:        | ["" 2
          '*             e#   Push char '*': | ["" 2 '*
            *            e#   Repeat char:   | ["" "**"
             +           e#   Concatenate:   | ["**"
              }%         e# End:             | ["**" " **" "  **" "   **" "    **"]
                _        e# Duplicate:       | ["**" " **" "  **" "   **" "    **"] ["**" " **" "  **" "   **" "    **"]
                 W%      e# Reverse:         | ["**" " **" "  **" "   **" "    **"] ["    **" "   **" "  **" " **" "**"]
                   ..e>  e# Overlay:         | ["**  **" " ****" "  **" " ****" "**  **"]
                       } e# End

0

Python 2 , 110 байт

x=a=0
n=c=input()
while x<2*n+1:
    print ' '*a+'*'*n+' '*c+'*'*(2*n-2*a-c)
    x+=1
    a=n-abs(n-x)
    c=max(0, n-2*a)

Эта программа разбивает каждую строку на 4 части: первые пробелы, первые звезды, вторые пробелы и затем вторые звезды. Для каждой горизонтальной линии X он вычисляет, сколько звездочек или пробелов необходимо для каждого из 4 участков линии, затем строит и печатает эту строку.


0

Сетчатка , 144 байта

.+
 $&$* $&$* $&
 
$`#$'¶
¶\d+$

( *)#( *)(\d+)
$1$3$**$2#$3$* #$2$3$**$1
( +)(\*+)( *)(# +#)\3\2\3 +
$3$2$1$4$1$2$3
+` (# +#)
$1 
+` #...
#
##

Попробуйте онлайн! Объяснение:

.+
 $&$* $&$* $&

Добавьте 2n + 1 пробел перед входным значением (по одному на каждую выходную строку).

$`#$'¶

Замените каждый пробел на #и соберите результаты. Это дает диагональную линию #s, заполненную пробелом с обеих сторон, с добавленным входным значением.

¶\d+$

Удалите исходное значение ввода, так как теперь у нас есть копия в каждой строке.

( *)#( *)(\d+)
$1$3$**$2#$3$* #$2$3$**$1

Создайте две диагональные линии n *s, с разделителем столбцов nпробелов, обернутых в пару #s.

( +)(\*+)( *)(# +#)\3\2\3 +
$3$2$1$4$1$2$3

На тех линиях, где *s ближе к середине, поменяйте местами две половины. Это дает вид, напоминающий > | | <.

+` (# +#)
$1 

Переместите | |s как можно дальше влево, создавая >> > <вид.

+` #...
#

Для каждого пробела между #s удалите три следующих символа. Это присоединяется > <к X.

##

Удалите ненужные теперь #s.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.