Побудуйте напівзігзаг


29

Вам буде введено додатне ціле число Nяк вхідне. Ваше завдання - побудувати напівзігзаг із Nсторін, кожна довжиною N. Оскільки досить важко чітко описати завдання, ось кілька прикладів:

  • N = 1:

    О
    
  • N = 2:

    О
     ОО
    
  • N = 3:

    ОО
     ОО
      ТОВ
    
  • N = 4:

    OOOOO
     ОО
      ОО
       ТОВО
    
  • N = 5:

    OOOOOO
     ТОВ
      ТОВ
       ТОВ
        OOOOOO
    
  • N = 6:

    OOOOOOO
     ТОВ
      ТОВ
       ТОВ
        ТОВ
         OOOOOOOOOOOO
    
  • N = 7:

    OOOOOOOOO
     ТОВО
      ТОВО
       ТОВО
        ТОВО
         ТОВО
          OOOOOOOOOOOOOOOO
    
  • Більший тестовий випадок з N = 9

Як бачите, напівзігзаг складається з чергуються діагональних і горизонтальних ліній, і він завжди починається з верхньої лівої в нижню праву діагональну лінію. Зверніть увагу, що символи на горизонтальних лініях розділені пробілом.

Правила

  • Ви можете вибрати будь-який символ, який не є пробілом, а не O, він може бути навіть непослідовним.

  • Ви можете вивести / повернути результат у вигляді рядка або у вигляді списку рядків, кожна з яких представляє один рядок .

  • У вас може бути зворотний або провідний новий рядок.

  • Застосовуються лазівки за замовчуванням .

  • Ви можете приймати введення та забезпечувати вихід будь-яким стандартним значенням .

  • Якщо можливо, додайте посилання для тестування до вашої заявки. Я підтримаю будь-яку відповідь, яка показує зусилля з гольфу та має пояснення.

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



Чи потрібно ставити проміжки між O, які є горизонтальними?
HatsuPointerKun

1
@HatsuPointerKun Зверніть увагу, що символи на горизонтальних лініях розділені пробілом. - Так, вам потрібно поставити пробіли.
Містер Xcoder

1
Ага, так. Я повинен навчитися читати. Спасибі
HatsuPointerKun

1
@JohnHamilton відповідей повинні теоретично працювати для будь-якого числа заданого в якості вхідних даних. Вони не повинні турбуватися про те, що може містити екран.
Містер Xcoder

Відповіді:


10

Вугілля деревне , 24 байти

FN«↶§7117ι×⁺#× ﹪ι²⁻Iθ¹»#

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

-5 завдяки Нілу .

AST:

Program
├F: For
│├N: Input number
│└Program
│ ├↶: Pivot Left
│ │└§: At index
│ │ ├'7117': String '7117'
│ │ └ι: Identifier ι
│ └Print
│  └×: Product
│   ├⁺: Sum
│   │├'#': String '#'
│   │└×: Product
│   │ ├' ': String ' '
│   │ └﹪: Modulo
│   │  ├ι: Identifier ι
│   │  └2: Number 2
│   └⁻: Difference
│    ├I: Cast
│    │└θ: Identifier θ
│    └1: Number 1
└Print
 └'#': String '#'

Для Вугілля було занадто легко :)
Містер Xcoder

@ Mr.Xcoder Це відчуває себе насправді необуреним ... не впевнений, як його грати в гольф.
Ерік Аутгольфер

ОП заявила, що персонаж може бути будь-яким і йому не потрібно бути послідовним, тому я збирався щось робити за рамками FN§⟦↘→↗→⟧ι⁻Iθ¹→(лише 15 байт), але списки напрямків, здається, не працюють правильно у вугільному вугіллі. Шкода.
Чарлі

@CarlosAlejo Спробував це, але, на жаль, це не працює.
Ерік Аутгольфер

1
@CarlosAlejo FN✳§⟦↘→↗→⟧ι⁻θ¹Oпрацюватиме після того, як Денніс витягнеться і буде спрямований у напрямку
лише ASCII

7

Python 2 , 157 153 байт

n=input()
o,s=q='O '
def p(k,t=q*n+s*(4*n-6)):print(t*n)[k*~-n:][:n*3/2*~-n+1]
p(2)
for i in range(n-2):p(0,i*s+s+o+s*(4*n-7-2*i)+o+s*(2*n+i-2))
n>1>p(5)

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

  • n*3/2*~-n+1 - ширина кожного рядка: ⌊3n / 2⌋ · (n − 1) + 1 символ.
  • Рядок q*n+s*(4*n-6)представляє верхній і нижній рядки. Якщо ми повторимо його і скибочку, [2*(n-1):]отримаємо верхній ряд; якщо ми наріжемо, [5*(n-1):]отримаємо нижній ряд. Звідси визначення pта заклики до p(2)та p(5). Але оскільки нам так чи інакше потрібно повторення та нарізка довжини рядків для всіх інших рядків, ми повторно використовуємо його pв циклі.
  • Це i*s+s+o+…просто нудний вираз для середніх рядів.
  • n>1>p(5)буде коротке замикання, якщо n≯1, внаслідок чого, p(5)його не оцінюють. Отже, це скорочення if n>1:p(5).

Ого, дивовижне рішення, таке розумне. Ви заробили мою нагороду
містер Xcoder

Нічого собі, ніколи не знав, що Python мав коротке замикання на таких порівняннях +1.
Zacharý

6

Mathematica, 126 125 121 112 104 89 86 байт

(m=" "&~Array~{#,#^2-#+1};Do[m[[1[i,#,-i][[j~Mod~4]],j#-#+i+1-j]]="X",{j,#},{i,#}];m)&
  • #є вхідним номером для анонімної функції (закінчується фіналом &).
  • m=" "&~Array~{#,#^2-#+1};робить матрицю символів простору потрібного розміру, заповнюючи масив заданих розмірів #,#^2-#+1виходами постійної анонімної функції "вивести пробіл" " "&.
  • Do[foo,{j,#},{i,#}]це пара вкладених циклів do, де jдіапазон від 1до #і всередині цього iдіапазону від 1до #.
  • m[[1[i,#,-i][[j~Mod~4]],j#-#+i+1-j]]="X"встановлює відповідну частину матриці символом Xна основі jі i. -iВикористовує негативну індексацію , щоб зберегти байти з #-i+1. (Я забув написати Mod[j,4]як j~Mod~4у оригінальній версії цього коду.) Jenny_mathy зазначила, що ми можемо використовувати модульний залишок для індексації до списку безпосередньо (а не використовувати Switch), щоб зберегти 9 байт, і JungHwan Min зазначив, що ми цього не зробили ' не потрібно використовувати, ReplacePartоскільки ми можемо встановити частину масиву, яка 1[i,#,-i][[j~Mod~4]]використовує дивну поведінку та загальність [[foo]]для збереження байтів на{1,i,#,-i}[[j~Mod~4+1]]
  • Оскільки мета встановив, що список символів - це рядок (як вказував JungHwan Min ), нам не потрібно відображати будь-яку функцію в рядках матриці символів, оскільки це вже список "string" s.

Ви можете перевірити це в пісочниці Wolfram Cloud , вставивши такий код, як наступний, та натиснувши Shift + Enter або numpad Enter:

(m=" "&~Array~{#,#^2-#+1};Do[m[[1[i,#,-i][[j~Mod~4]],j#-#+i+1-j]]="X",{j,#},{i,#}];m)&@9//MatrixForm

1
Дуже хороша! ви можете замінити StringJoin на "" <> # &, щоб зберегти 4 байти
J42161217

@Jenny_mathy Дякую за пораду! Це здається досить корисним.
Марк С.

2
Ви також можете замінити перемикач [...] на {1, i, #, - i} [[j ~ Mod ~ 4 + 1]] і зберегти 9 байт!
J42161217

1
Тут вам насправді не потрібно ReplacePart. m=ReplacePart[...]може бути m[[{1,i,#,-i}[[j~Mod~4+1]],j#-#+i+1-j]]="X"- Ви можете зі списку. Це позбавляється від 15 байт. SetPart
JungHwan Min

1
{1,i,#,-i}[[j~Mod~4+1]]також може бути 1[i,#,-i][[j~Mod~4]]. Цей трюк працює, тому що [[0]]повертає Headвираз.
JungHwan Min

4

C ++, 321 234 байт

-87 байт завдяки Захарі

#include<vector>
#include<string>
auto z(int n){std::vector<std::string>l;l.resize(n,std::string(n*n+n/2*(n-1),32));l[0][0]=79;int i=0,j,o=0;for(;i<n;++i)for(j=1;j<n;++j)l[i%4?i%4-1?i%4-2?0:n-j-1:n-1:j][i*n+j-i+(o+=i%2)]=79;return l;}

Повертає вектор рядків


Я отримав його до 318 байт: repl.it/JpJ2
Zacharý

Виправлення, я зменшив його до 239 байт : repl.it/JpJ2/1
Zacharý

Вибачте за спам, 234 байти: repl.it/JpJ2/3
Zacharý

1
Що я можу сказати, крім того, як ти запрошений!
Zacharý

@ Zacharý велике спасибі, пане
HatsuPointerKun

4

Математика, 179 байт

Rotate[(c=Column)@(t=Table)[{c@(a=Array)[" "~t~#<>(v="o")&,z,0],c@t[t[" ",z-1]<>v,z-1],c@a[t[" ",z-2-#]<>v&,z-1,0],c@t[v,z-Boole[!#~Mod~4<1]-1]}[[i~Mod~4+1]],{i,0,(z=#)-1}],Pi/2]&

редагувати для @JungHwanMin


Я не очікував, що це буде так коротко, молодець!
Містер Xcoder

Лише питання: Чи Mod[z,4]==0можна замінити Mod[z,4]<1?
Містер Xcoder

так, я можу
покатати

3
Я дійсно не знаю , Mathematica, але ви можете замінити Mod[#,4]з #~Mod~4на -1 байт?
Містер Xcoder

1
На жаль ... випадково заперечено. Чи можете ви відредагувати відповідь, щоб я міг перевернути її догори дном?
JungHwan Min

4

05AB1E , 21 20 19 байт

Код

Використовується новий режим полотна:

Fx<)Nè'ONÉúR3212NèΛ

Використовує кодування 05AB1E . Спробуйте в Інтернеті!

Пояснення:

F                      # For N in range(0, input)
 x<)                   #   Push the array [input, 2 × input - 1]
    Nè                 #   Retrieve the Nth element
      'ONÉúR           #   Push "O" if N is odd, else "O "
            3212Nè     #   Retrieve the Nth element of 3212
                  Λ    #   Write to canvas

Для введення 6 це дає такі аргументи (у тому самому порядку) для полотна:

[<num>, <fill>, <patt>]
[6,     'O',     3]
[11,    'O ',    2]
[6,     'O',     1]
[11,    'O ',    2]
[6,     'O',     3]
[11,    'O ',    2]

Щоб пояснити, що робить полотно, ми вибираємо перший набір аргументів із наведеного вище списку.

Цифра 6 визначає довжину рядка, який буде записаний на полотно. Наповнювач використовується для написання на полотні, що в даному випадку є O. Він циклічно проходить через рядок наповнювача. Напрямок рядка визначається підсумковим аргументом, напрямком. Напрямки:

7  0  1
 \ | /
6- X -2
 / | \
5  4  3

Це означає, що 3 задають напрямок на південний схід , який також можна спробувати в Інтернеті .


також зауважте, що режим полотна знаходиться в стадії розробки та дуже нестабільний
Аднан

: O 05AB1E мутує на вугілля (також це побиття вугілля O_o)
лише ASCII

@ ASCII only Так, я побачив зростання всіх мов на основі ASCII (вугілля, SOGL, V тощо) і побачив, як 05AB1E відточується на задньому плані, тому мені довелося щось з цим зробити: p
Аднан

значить, ви скопіювали вугілля? : P 05ab1e навіть має полотно та спрямовану друк (хоча вугілля підтримує лише такий стиль друку з довжиною через python)
лише ASCII

2

SOGL V0.12 , 36 байт

╝.H∫2\?.╝}F2%?№@.┌Ο};1w⁄Hh1ž}.4%1>?№

Спробуйте тут!

Основна ідея полягає в тому, щоб для кожного числа вхідного діапазону вибирати або додавання діагоналі, або горизонтальну пунктирну частину, і в цьому випадку вона поверне масив для легшого додавання. Пояснення:

╝                                     get a diagonal from the bottom-left corner with the length of the input - the starting canvas
 .H∫                        }         for each number in the range [1,inp-1] do, pushing counter
    2\?  }                              if it divides by 2, then
       .╝                                 create another diagonal of the input
          F2%                           push counter % 2
             ?     }                    if that [is not 0]
              №                           reverse the current canvas upside down
               @.┌Ο                       get an alternation of spaces and dashes with the dash amount of the input length
                    ;                   get the canvas on top of the stack
                     1w⁄                get its 1st element length
                        H               decrease it
                         h              swap the bottom 2 items - the canvas is now at the bottom and the current addition ontop
                          1             push 1
                           ž            at 1-indexed coordinates [canvasWidth-1, 1] in the canvas insert the current part made by the Ifs
                             .4%1>?   if input%4 > 1
                                   №    reverse the array vertically

Якщо введення 1 не було дозволене, то ο.∫2%?.╝}F2\?№@.┌Ο};1w⁄Hh1ž}.4%1>?№також працювало б. Якби дозволені випадкові числа, що плавали навколо, також працювали .∫2%?.╝}F2\?№@.┌Ο};1w⁄Hh1ž}.4%1>?№б. Якби я не лінувався і не реалізовувався , }F2%?міг би замінити його на -4 байти


2

Математика, 106 87 байт

SparseArray[j=i=1;k=#-1;Array[{j+=Im@i;k∣#&&(i*=I);j,#+1}->"o"&,l=k#+1,0],{#,l}," "]&

Повертає a SparseArray об'єкт Strings. Щоб візуалізувати вихід, ви можете додати Grid@. Уводить помилку для випадку 1, але це ігнорувати безпечно.

Пояснення

j=i=1

Встановити iіj 1.

k=#-1

Встановити k на вхід - 1.

l=k#+1

набір lдляk*input + 1

Array[ ..., l= ...,0]

Ітераційні lчаси, починаючи з 0, збільшуючись 1щоразу ...


j+=Im@i

Додайте уявний компонент iдо j...

k∣#&&(i*=I)

Якщо поточна ітерація ділиться на k, помножимо iна уявну одиницю ...

{... j,#+1}->"o"

Створіть Ruleоб’єкт, який змінює елемент у позиції {j, current iteration + 1}на"o"


SparseArray[ ...,{#,l}," "]

Створіть SparseArrayоб’єкт, використовуючи створені Ruleоб’єкти, з розмірністю {input, l}, використовуючи " "як порожнє.

Спробуйте це на Wolfram Sandbox!


1
в справі n = 3 щось не так
J42161217

1
n = 2, 4,5,6 також мають проблеми з правильністю, але я думаю, що це працює для 7 і вище. Мені цікаво: чи є прецедент щодо того, чи SparseArrayвважається масив? Це може бути візуалізовані з допомогою Gridабо MatrixForm, але я зазвичай не брати до уваги це «список рядків» тут. Якщо 2D-масив символів достатній, наприклад, це скорочує 8 байт мого рішення (наприклад, до допомоги Jenny_mathy).
Марк С.

1
@MarkS. Крім того, масив рядків добре за мета-консенсусом . Якщо щось незрозуміло, будь ласка, попросіть ОП (як він / вона робить правила, а не ми). Простий пошук "SparseArray" на цьому веб-сайті дає безліч SparseArrayвідповідей, тому я вважаю, що це добре.
JungHwan Мін

1
@MarkS. Також на цій сторінці є багато хитрощів щодо гри в гольф Mathematica.
JungHwan Min

1
@JungHwanMin Я редагував свою відповідь так, як ви запитували
J42161217

2

Пітон 3 , 228 226 224 215 197 195 байт

-11 байт Завдяки @Mr. Xcoder

-2 байти Завдяки @Mr. Xcoder

def f(n,s=range):
 x=y=t=c=0;z=[]
 for i in s(n*n-n+2):c+=i%(n-(2<=n))<1;z+=[[x,y]];t=max(t,x);x+=2-c%2;y+=[-1,1][c%4<3]*(c%2)
 return'\n'.join(''.join(' O'[[k,j]in z]for k in s(t))for j in s(n))

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

Пояснення та код без гольфу:

def f(n):
 x=y=t=c=0;z=[]                       #initialize everything
 for i in range(n*n-n+2):             #loop n*n-n+2 times which is the numberr of 'o's expected
    c+=i%[~-n,n]<n-1                  #if one cycle has been completed, increase c by 1, if n>1.                                            
    z+=[[x,y]]                        #add [x,y] to z(record the positions of 'o')
    t=max(t,x)                        #trap maximum value of x-coordinate(to be used later while calculatng whole string)
    r=[[2,0],[1,1],[2,0],[1,-1]][c%4] #r gives direction for x and y to move, adjust it as per c i.e. cycles
    x+=r[0];y+=r[1]                   #yield newer values of x and y 
 return '\n'.join(''.join(' o'[[k,j]in z]for k in range(t))for j in range(n)) #place space or 'o' accordingly as per the recorded posititons in z

1
Дуже приємна робота. Вітаємо!
Містер Xcoder

@ Mr.Xcoder Дякую Треба сказати, що це було важко, особливо виникли проблеми з визначення правильного діапазону.
officialaimm


1
215 байт , if 2>n:return'o'досить зайве. Я зробив обхід з c+=i%[~-n,n][2>n]<1замість c+=i%~-n<1.
Містер Xcoder

1
Вибачте за дуже пізнє покращення, 195 байт
містер Xcoder

1

Haskell , 197 байт

a n c=take(2*n)$cycle$c:" "
r i n x y=take(div(3*n)2*(n-1)+1)$(' '<$[1..i])++(cycle$"O "++(a(2*n-i-3)y)++"O "++(a(n+i-2)x))
z n=take n$(r 0 n 'O' ' '):[r i n ' ' ' '|i<-[1..n-2]]++[r(n-1)n ' ' 'O']

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

Завдяки @Lynn: фіксували пробіли між Os на горизонтальних сегментах зигзагу, але це коштувало багато байтів!

Деякі пояснення:

  • rце рядок виводу: він має 0 y y y y y 0 x x x 0 y ...формат, кількість xта yзалежно від рядка та початковогоn
  • для верхнього ряду, x='0' іy=' '
  • для середніх рядів, x=' 'іy=' '
  • для нижнього ряду, x=' 'іy='0'
  • take(div(3*n)2*(n-1)+1) обрізає нескінченний ряд у потрібному місці
  • кожен вихід має один верхній і один нижній ряд, за винятком випадків, коли n=1: take nобробляє цей випадок.

Чудово гольф! Ви можете скинути пару цих просторів, я думаю. І replicate n xможе бути замінений на x<$[1..n]. Крім того, у вашій відповіді бракує пробілів між Os на горизонтальних відрізках зигзагу.
Лінн

@Lynn дякую! з пробілами на горизонтальних сегментах, мій метод стає громіздким, але я хотів все-таки виправити код ...
jferard

Ви можете значно заощадити, скориставшись операторами та видаливши зайві пробіли, дивіться тут .
ბიმო

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