Візуалізуйте теорему Нікомаха


35

Теорема Ніхомаха відносить квадрат суми до суми кубів:

Теорема Ніхомаха

і має прекрасну геометричну візуалізацію:

Візуалізація

Завдання: Створіть 2d частину цієї візуалізації в ascii.

Вам потрібно буде забезпечити, щоб ваша візуальна розмежування підтримувалася вашою діаграмою. Це найпростіше зробити з чотирма "кольорами", хоча це можна досягти лише трьома (див. Останній приклад нижче). За допомогою чотирьох кольорів ви використовуєте два для розрізнення регіонів у межах "смужки" (тобто різних частин, що складають один куб), і два для розрізнення сусідніх смуг. Ви також можете використовувати більше чотирьох кольорів, якщо хочете. Якщо щось із цього заплутане, наведений нижче приклад повинен уточнити.

Введення-виведення

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

Це кодовий гольф, зі стандартними правилами.

Зразки виходів

N = 1

#

N = 2

#oo   
o@@   
o@@   

N = 3

#oo+++
o@@+++
o@@+++
+++###
+++###
+++###

N = 4

#oo+++oooo
o@@+++oooo
o@@+++@@@@
+++###@@@@
+++###@@@@
+++###@@@@
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo
oo@@@@oooo

N = 5

#oo+++oooo+++++
o@@+++oooo+++++
o@@+++@@@@+++++
+++###@@@@+++++
+++###@@@@+++++
+++###@@@@#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
oo@@@@oooo#####
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++
+++++#####+++++

Три кольорові версії для N = 4, завдяки @BruceForte:

#oo+++oooo
o##+++oooo
o##+++####
+++ooo####
+++ooo####
+++ooo####
oo####++++
oo####++++
oo####++++
oo####++++

6
Чотириколірна теорема: D
Leaky Nun

1
Чи можете ви додати вихід за N = 5?
Уріель

1
@Uriel Готово. Дивіться мою редакцію.
Йона

Спасибі! Також чи можу я перемикати @ і os лише на зовнішній смузі в N = 4? Чи має бути результатом суворої заміни цих текстів іншою схемою?
Уріель

@Uriel перемикання нормально. Важливо лише те, що сусідні кольори не конфліктують, так що видно візерунок.
Йона

Відповіді:


17

MATL , 30 28 27 байт

t:P"@:s:@/Xk&+@+8MPt&(]30+c

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

Особливості бонусу:

  • Для 26 байт наступна модифікована версія дає графічний вихід :

    t:P"@:s:@/Xk&+@+8MPt&(]1YG
    

    Спробуйте в MATL Online!

  • Зображення просить певного кольору , і воно коштує лише 7 байт:

    t:P"@:s:@/Xk&+@+8MPt&(]1YG59Y02ZG
    

    Спробуйте в MATL Online!

  • Або скористайтеся довшою версією (37 байт), щоб побачити, як поступово будується матриця символів :

    t:P"@:s:@/Xk&+@+8MPt&(t30+cD9&Xx]30+c
    

    Спробуйте в MATL Online!

Приклади виходів

Для введення 8, подано нижче основна версія, графічний вихід та кольоровий графічний вихід.

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення

Пояснення

Загальна процедура

Чисельна матриця будується від зовнішнього до внутрішнього шарів Nкроками, де Nє вхід. Кожен крок перезаписує внутрішню (верхню ліву) частину попередньої матриці. Наприкінці числа в отриманій матриці змінюються на символи.

Приклад

Для введення 4перша матриця є

10 10  9  9  9  9  8  8  8  8
10 10  9  9  9  9  8  8  8  8
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 9  9  8  8  8  8  7  7  7  7
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6
 8  8  7  7  7  7  6  6  6  6

Як другий крок - матриця

7 7 7 6 6 6
7 7 7 6 6 6
7 7 7 6 6 6
6 6 6 5 5 5
6 6 6 5 5 5
6 6 6 5 5 5

переписується у верхню половину останньої. Потім те ж саме робиться і з

6 5 5
5 4 4
5 4 4

і нарешті с

3

Отримана матриця дорівнює

3 5 5 6 6 6 8 8 8 8
5 4 4 6 6 6 8 8 8 8
5 4 4 6 6 6 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
6 6 6 5 5 5 7 7 7 7
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6
8 8 7 7 7 7 6 6 6 6

Нарешті, 30додається до кожного запису, а отримані цифри інтерпретуються як кодові точки та перетворюються в символи (таким чином, починаючи з 33відповідного !).

Побудова проміжних матриць

Для введення Nврахуйте зменшення значень kвід Nдо 1. Для кожного генерується kвектор цілих чисел від 1до k*(k+1), а потім кожен запис ділиться на kі округляється. Як приклад, наводимо k=4це (усі блоки мають розмір, kкрім останнього):

1 1 1 1 2 2 2 2 3 3

тоді як для k=3результату буде (всі блоки мають розмір k):

1 1 1 2 2 2

Цей вектор додається, що відповідає елементу трансляції, до перенесеної себе копії; а потім kдодається до кожного запису. За k=4це дає

6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
6  6  6  6  7  7  7  7  8  8
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
7  7  7  7  8  8  8  8  9  9
8  8  8  8  9  9  9  9 10 10
8  8  8  8  9  9  9  9 10 10

Це одна з проміжних матриць, показаних вище, за винятком того, що вона перевернута горизонтально і вертикально. Отже, все, що залишилося, - це перевернути цю матрицю і записати її у верхній лівий кут "накопиченої" матриці поки що, ініціалізований на порожню матрицю для першого ( k=N) кроку.

Код

t       % Implicitly input N. Duplicate. The first copy of N serves as the
        % initial state of the "accumulated" matrix (size 1×1). This will be 
        % extended to size N*(N+1)/2 × N*(N+1)/2 in the first iteration
 :P     % Range and flip: generates vector [N, N-1, ..., 1]
"       % For each k in that vector
  @:    %   Push vector [1, 2, ..., k]
  s     %   Sum of this vector. This gives 1+2+···+k = k*(k+1)/2
  :     %   Range: gives vector [1, 2, ..., k*(k+1)/2]
  @/    %   Divide each entry by k
  Xk    %   Round up
  &+    %   Add vector to itself transposed, element-wise with broadcast. Gives
        %   a square matrix of size k*(k+1)/2 × k*(k+1)/2
  @+    %   Add k to each entry of the this matrix. This is the flipped
        %   intermediate matrix
  8M    %   Push vector [1, 2, ..., k*(k+1)/2] again
  Pt    %   Flip and duplicate. The two resulting, equal vectors are the row and
        %   column indices where the generated matrix will be written. Note that
        %   flipping the indices has the same effect as flipping the matrix
        %   horizontally and vertically (but it's shorter)
  &(    %   Write the (flipped) intermediate matrix into the upper-left
        %   corner of the accumulated matrix, as given by the two (flipped)
        %   index vectors 
]       % End
30+     % Add 30 to each entry of the final accumulated matrix
c       % Convert to char. Implicitly display

Я взагалі не знаю MATL, але чи можете ви зберегти будь-які байти, взявши mod10, а не додавши 30 і перетворивши на символи?
користувач2390246

Або навіть mod4 ...
користувач2390246

@ user2390246 Ви маєте на увазі зберігати їх як числа з однією цифрою і уникати перетворення на знаки? Це не спрацювало, оскільки числова матриця буде надрукована з пробілами між числами. Але спасибі за ідею все одно :-)
Луїс Мендо

Досить справедливо. Що відбувається з n> 226? Хіба це не вийде за межі дійсних символів? (Не дивно, що
тайм-

@ user2390246 Так, для високих вхідних цифр воно виходить назовні. І якщо ми розглянемо символи ASCII, максимальна точка коду дорівнює 127, тому вона вийде назовні ще швидше. Але, як ви помітили, у нього втрачається пам'ять до того, як це станеться (отримана матриця char занадто велика). У будь-якому випадку, дозволено працювати лише із заданими розмірами вводу через обмеження пам'яті чи типів даних
Luis Mendo

7

Python 2 , 187 178 164 162 152 байт

-8 байт завдяки Mr.Xcoder
-1 байт завдяки Стівену
-10 байт завдяки Джонатану Фреху

g=lambda y:y>1and[l+y*f(y,i)for i,l in enumerate(g(y-1))]+y*[''.join(f(y,i)for i in range(y*-~y/2))]or['#']
f=lambda y,i:'0@+#'[(y*~-y/2%y+i)/y%2+y%2*2]

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


Бо коли ви приїдете додому, 179 байт .
Містер Xcoder


1
Чи дозволяється не включати кількість байтів імені функції лямбда, коли ви використовуєте її рекурсивно, тобто використовуєте її ім'я в решті коду?
Джонатан Фрех

sum(range(y))%y->y*~-y/2%y
Джонатан Фрех

@JonathanFrech Так, коли це рекурсивно, воно повинно бути там.
прут

7

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

F⮌…·¹N«≔⊘×ι⊕ιθF⊕⊘ι«F§#+@⁺ικ«UO⁻θ×ικθλUOθ⁻θ×ικλ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Попередня 50-байтна версія з поясненням: Спробуйте в Інтернеті!

F⮌…·¹N«≔÷×ι⁺¹ι²θF⁺¹÷鲫F§#+@⁺ικ«UO⁻θ×ικθλUOθ⁻θ×ικλ

F     «     Loop over
  …·¹       Inclusive range from 1 to
     N      Input as a number
 ⮌          Reversed

   ι⁺¹        Add 1 to current index
  ×   ι       Multiply by current index
 ÷     ²      Divide by 2
≔       θ     Assign to q

F     «      Loop over
             Implicit range from 0 to
   ÷ι²       Half the current index
 ⁺¹          Plus 1

F       «    Loop over
  #+@        Literal string
 §           Circularly indexed by
     ⁺ικ     Sum of outer and inner index

    ×ικ     Multiply outer and inner index
  ⁻θ        Subtract from q
UO     θλ   Draw an oblong (q-ik, q) using that character

UOθ⁻θ×ικλ   Draw an oblong (q, q-ik) using that character

Примітка: я перебираю цикл над символом, а не намагаюся призначити символ безпосередньо lтому, що ви не можете безпосередньо призначити результат індексації рядка змінної, оскільки це неоднозначна конструкція у вугільному вугіллі. На щастя, кількість байтів однакова.


Технічно ви можете зі змінною ASCII, оскільки її порядок аргументів відмінено (зауважте, що для доступу до неї потрібен оператор, щоб він був менш гострим)
лише для ASCII,

5

C (gcc) , 135 128 120 байт

f(n,m,i,x,y,k){for(m=n*-~n/2,i=m*m;i--;printf("\n%d"+!!(~i%m),(x/k+y/k+k)%3))for(x=i%m,y=i/m,k=n;x>=k&y>=k;x-=k--)y-=k;}

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

Використовує лише три кольори.

Концептуально працює на сітці, оберненій на 180 градусів:

000111
000111
000111
111220
111220
111001

І обчислює кольори за формулою:

c(x,y,n) = c(x-n,y-n,n-1)                   if x >= n and y >= n
         = (x div n + y div n + n) mod 3    otherwise


@JonathanFrech Це неправда C і перерветься з gcc -O2.
nwellnhof

Досить справедливо; чи можливо, що другий код працює лише для трьох кольорів через модуль три ( g(i%m,i/m,n)%3)?
Джонатан Фрех

Запропонувати x/k&&y/kзамістьx>=k&y>=k
roofcat

2

R , 131 126 123 байт

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

function(n){l=w=sum(1:n)
m=matrix(,l,l)
for(i in n:1){m[l:1,l:1]=outer(x<-(1:l-1)%/%i,x,`+`)+i
l=l-i}
write(m%%4,"",w,,"")}

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

Для цього використовується той же алгоритм, що і відповідь MATL @LuisMendo . Єдина відмінність полягає в тому, що замість перетворення в символи матриця виводиться зі всіма значеннями mod4, щоб гарантувати, що кожен елемент є одним символом ascii.


1
123 байти! Я повернув forцикл на -1 байт :)
Джузеппе

1

Пітон 2 , 176 175 байт

n=input()
R,J=range,''.join;r=[]
for i in R(n+1):
 S=sum(R(i));c='AxBo'[i%2::2]
 for j in R(S):r[~j]+=c[j/i%2]*i
 r+=[J(c[-j/i%2]for j in R(S+i,0,-1))]*i
for l in r:print J(l)

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


Якщо ви визначите J="".join;(+10 байт) і замініть обидва "".joins (-2 * 7 = -14 байт) на J(+2 байти), ви можете зберегти байт (оскільки після printбайта +1 повинен бути додатковий пробіл ) .
Джонатан Фрех
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.