Призраки и тыквы


15

Вот тыква ASCII, вырезанная в Джек-о-Фонарь. Разве это не мило?

((^v^))

Вот призрак ASCII. Посмотрите, как это жутко!

\{O.O}/

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

Призраки, однако, любят стоять на вершине тыквы, поэтому они даже жуткие . Однако им приходится стоять на двух тыквах, иначе их призрачный вес раздавит тыкву под ними. Но из-за того, как работает их призрачная магия , несколько призраков могут складывать и делить тыквы, при условии, что призраки либо делятся равномерно на нижних тыкв или нижних призраков. Другими словами, образуя форму, похожую на человеческую пирамиду . Обратите внимание, что призраки не могут складываться на призраках, если под ними нет тыквы (так работает магия).

С учетом двух неотрицательных целых чисел gи p, представляющих количество gхостов и pumpkins, выведите наиболее компактную из возможных левых формаций, следуя приведенным выше правилам стекирования пирамид. Оставшиеся тыквы и призраки (то есть те, которые не образуют пирамиду) уходят на землю справа.

Для пояснения, эти формирования в порядке (разделены пробелами) и служат примером ввода / вывода:

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
Мне нравится, что призраки и тыквы создают человеческую пирамиду
MayorMonty

Ответы:


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.