Привиди і гарбузи


15

Ось гарбуз ASCII, вирізаний у ліхтар Jack-o-Lantern. Хіба це не мило?

((^v^))

Ось привид ASCII. Подивіться, як це моторошно!

\{O.O}/

Очевидно, гарбузи повинні бути на землі, з проміжком між ними, щоб вони не гнили.

Привиди, однак, люблять стояти на вершках гарбуза, тому вони ще дурніші . Однак їм доводиться стояти на двох гарбузах, інакше їх примарна вага розчавить гарбуз під ними. Але, завдяки тому, як працює їх примарна магія , кілька привидів можуть складати гарбуз і ділитися гарбузами, за умови, що привиди або рівномірно розбиваються на нижні гарбузи, або на нижніх привидах. Іншими словами, утворюючи форму, як людська піраміда . Зауважте, що привиди не можуть укладатися на привидів, якщо під ними не є гарбуз (саме так працює магія).

З огляду на два невід’ємні цілі числа, gі p, що представляють кількість gхостів та pамфінок, виведіть найбільш компактне можливе ліве утворення, дотримуючись вищезазначених правил укладання піраміди. Залишилися гарбузи та привиди (тобто ті, що не утворюють піраміди) йдуть по землі праворуч.

Для уточнення ці формації в порядку (порожній новий рядок відокремлено) і служать прикладом вводу / виводу:

0p 1g
\{O.O}/

1p 0g
((^v^))

1p 1g
((^v^)) \{O.O}/

2p 1g
    \{O.O}/
((^v^)) ((^v^))

2p 2g
    \{O.O}/
((^v^)) ((^v^)) \{O.O}/

3p 1g
    \{O.O}/
((^v^)) ((^v^)) ((^v^))

3p 2g
    \{O.O}/ \{O.O}/
((^v^)) ((^v^)) ((^v^))

3p 3g
        \{O.O}/
    \{O.O}/ \{O.O}/
((^v^)) ((^v^)) ((^v^))

0p 4g
\{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/

3p 0g
((^v^)) ((^v^)) ((^v^))

7p 6g
            \{O.O}/
        \{O.O}/ \{O.O}/
    \{O.O}/ \{O.O}/ \{O.O}/
((^v^)) ((^v^)) ((^v^)) ((^v^)) ((^v^)) ((^v^)) ((^v^))

Ці утворення не в порядку

\{O.O}/
((^v^))

    \{O.O}/
((^v^))

((^v^)) ((^v^)) \{O.O}/

    \{O.O}/
    \{O.O}/
((^v^)) ((^v^))

            \{O.O}/
\{O.O}/ ((^v^)) ((^v^))

    ((^v^))
((^v^)) ((^v^))

      \{O.O}/
((^v^)) ((^v^))

Вхідні дані

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

Вихідні дані

ASCII-мистецтво зображення привидів і гарбузів, дотримуючись вищезазначених правил. Провідні / зворотні нові рядки або інші пробіли необов’язкові, за умови, що привиди та гарбуз належним чином розташовуються.

Правила

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

Яке правильне формування для 7 гарбузів та 6 привидів?
Ніл

@Neil Оскільки правила вимагають найбільш компактного лівого найвищого результату, це була б піраміда з 6 привидів зверху на 4 гарбузи, з додатковими 3 гарбузами праворуч. Я додам це як приклад.
AdmBorkBork

Ну, ваше використання компактних збентежило мене - я міг би поставити всіх привидів в один ряд, тож це компактніше вертикально!
Ніл

Чи завжди гарбузи будуть забезпечені перед привидами?
Габріель Бенамі

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

Відповіді:


5

JavaScript (ES7), 166 164 159 байт

Збережено 5 байт завдяки Нілу

f=(p,g,j=(g*2)**.5+.5|0,G=j>p-1?p?p-1:0:j,P=`
`,i=~j?g-G*++G/2:G,n=i>0?i>g?g:i:0)=>p|g?f(0,g-n,-1,G-1,P+'    ')+P+'((^v^)) '.repeat(p)+'\\{O.O}/ '.repeat(n):''

Відформатовано та прокоментовано

f = (                                    // given:
  p,                                     // - p = number of pumpkins
  g,                                     // - g = number of ghosts
  j = (g * 2) ** .5 + .5 | 0,            // - j = ceil(triangular root of g)
  G = j > p - 1 ? p ? p - 1 : 0 : j,     // - G = max(0, min(p - 1, j))
  P = '\n',                              // - P = padding string (+ line-break)
  i = ~j ?                               // - i =
    g - G * ++G / 2                      //   first iteration: g - G * (G + 1) / 2
  : G,                                   //   next iterations: G
  n = i > 0 ? i > g ? g : i : 0          // - n = max(0, min(i, g)) = number of
) =>                                     //   ghosts to print at this iteration
p | g ?                                  // if there's still something to print:
  f(                                     //   do a recursive call with:
    0,                                   //   - no pumpkin anymore
    g - n,                               //   - the updated number of ghosts
    -1,                                  //   - j = -1 (so that ~j == 0)
    G - 1,                               //   - one less ghost on the pyramid row
    P + '    '                           //   - updated padding string
  ) +                                    //   
  P +                                    //   append padding string
  '((^v^)) '.repeat(p) +                 //   append pumpkins
  '\\{O.O}/ '.repeat(n)                  //   append ghosts
: ''                                     // else: stop

Основна математика

Хитра частина полягає у тому, щоб з’ясувати оптимальну ширину Gпривидної піраміди.

Кількість привидів gу такій піраміді визначається:

g = 1 + 2 + 3 + ... + G = G(G + 1) / 2

Взаємно, ширина піраміди, що містить gпривидів, є справжнім коренем отриманого квадратичного рівняння:

G² + G - 2g = 0

Δ = 1² - 4(-2g)
Δ = 8g + 1

G = (-1 ± √Δ) / 2

Що призводить до наступного справжнього кореня (також відомого як трикутний корінь ):

G = (√(8g + 1) - 1) / 2

Однак ширина піраміди також обмежена кількістю гарбузів: у нас може бути не більше p-1привидів над pгарбузами. Звідси кінцева формула, що використовується в коді:

j = ⌈(√(8g + 1) - 1) / 2⌉
G = max(0, min(p - 1, j))

Версія ES6, 173 171 166 байт

f=(p,g,j=Math.pow(g*2,.5)+.5|0,G=j>p-1?p?p-1:0:j,P=`
`,i=~j?g-G*++G/2:G,n=i>0?i>g?g:i:0)=>p|g?f(0,g-n,-1,G-1,P+'    ')+P+'((^v^)) '.repeat(p)+'\\{O.O}/ '.repeat(n):''

Тестові приклади (ES6)


1
Я думаю, що j=(g+g)**.5+.5|0має працювати.
Ніл

Приємне пояснення!
AdmBorkBork

@Neil Це коротше і надійніше. (Мій метод мав деякі недійсні значення, починаючи з g = 5051.) Дякую.
Арнольд

3

Perl, 246 байт (нові рядки не входять до коду і надаються виключно для читабельності)

($c,$d)=<>=~/(\d+)/g;
$p="((^v^)) ";$g="\\{O.O}/ ";
for($f[0]=$c;$d>0;$d--){$f[$b+1]+1<$f[$b]?$f[++$b]++:$f[$b]++;$f[0]+=$d,$d=0 if$b==$c-1;$f[$b]==1?$b=0:1}
$h[0]=($p x$c).$g x($f[0]-$c);$h[$_].=$"x(4*$_).$g x$f[$_]for(1..$#f);
say join$/,reverse@h;

Приймає два числа: спочатку гарбузи, а потім привиди. Зразок введення:

5 20

Вибірка зразка:

                \{O.O}/ 
            \{O.O}/ \{O.O}/ 
        \{O.O}/ \{O.O}/ \{O.O}/ 
    \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ 
((^v^)) ((^v^)) ((^v^)) ((^v^)) ((^v^)) \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ \{O.O}/ 

О, ти читаєш моє формулювання дещо інакше, ніж те, що я мав намір - Привиди можуть складатись лише на привидів, якщо під ними є гарбуз, інакше їм потрібно перейти до правильного однофайлового файлу. Ось чому 0p 4gтестовий випадок містить усіх привидів у рядку, а не складених.
AdmBorkBork

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