Fantômes et citrouilles

15

Voici une citrouille ASCII sculptée dans un Jack-o-Lantern. N'est-ce pas mignon?

((^v^))

Voici un fantôme ASCII. Regardez comme c'est effrayant!

\{O.O}/

De toute évidence, les citrouilles doivent être au sol, avec un espace entre elles pour ne pas pourrir.

Les fantômes, cependant, aiment se tenir au-dessus des citrouilles, ils sont donc encore plus effrayants . Cependant, ils doivent se tenir sur deux citrouilles, sinon leur poids fantomatique écrasera la citrouille sous eux. Mais, en raison de la façon dont fonctionne leur magie fantomatique , plusieurs fantômes peuvent empiler et partager des citrouilles, à condition que les fantômes soient répartis également sur les citrouilles inférieures ou les fantômes inférieurs. En d'autres termes, former une forme comme une pyramide humaine . Notez que les fantômes ne peuvent pas s'accumuler sur les fantômes à moins qu'il n'y ait une citrouille en dessous (c'est ainsi que la magie fonctionne).

Étant donné deux nombres entiers non négatifs get p, représentant le nombre d' ghôtes et de pumpkins, génère la formation la plus compacte la plus à gauche possible, en suivant les règles d'empilement pyramidales ci-dessus. Les restes de citrouilles et de fantômes (c'est-à-dire ceux qui ne forment pas la pyramide) vont au sol à droite.

Pour plus de clarté, ces formations sont OK (saut de ligne vierge séparé), et servent d'exemple d'E / S:

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^))

Ces formations ne sont pas OK

\{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^))

Contribution

Deux entiers non négatifs dans n'importe quel format pratique . Au moins l'un des nombres sera différent de zéro. Vous pouvez prendre les entrées dans l’un ou l’autre ordre (c’est-à-dire dans les exemples que j’ai eu en premier), veuillez préciser comment vous prenez les entrées dans votre réponse.

Production

Une représentation ASCII des fantômes et des citrouilles, en suivant les règles ci-dessus. Les sauts de ligne de début / fin ou d'autres espaces blancs sont facultatifs, à condition que les fantômes et les citrouilles s'alignent correctement.

Règles

  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source
Quelle est la bonne formation pour 7 citrouilles et 6 fantômes?
Neil
@Neil Puisque les règles demandent la sortie la plus compacte à gauche, ce serait une pyramide de 6 fantômes sur 4 citrouilles, avec 3 citrouilles supplémentaires à droite. Je vais l'ajouter comme exemple.
AdmBorkBork
Eh bien, votre utilisation de compact m'a confondu - je pouvais mettre tous les fantômes sur la même ligne, donc c'est plus compact verticalement!
Neil
Les citrouilles seront-elles toujours fournies avant les fantômes?
Gabriel Benamy
2
J'aime que les fantômes et les citrouilles forment une pyramide humaine
MayorMonty

Réponses:

5

JavaScript (ES7), 166 164 159 octets

5 octets enregistrés grâce à Neil

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):''

Formaté et commenté

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

Mathématiques sous-jacentes

La partie délicate est de trouver la largeur optimale Gde la pyramide fantôme.

Le nombre de fantômes gdans une telle pyramide est donné par:

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

Réciproquement, la largeur d'une pyramide contenant des gfantômes est la vraie racine de l'équation quadratique résultante:

G² + G - 2g = 0

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

G = (-1 ± √Δ) / 2

Ce qui conduit à la vraie racine suivante (également connue sous le nom de racine triangulaire ):

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

Cependant, la largeur de la pyramide est également limitée par le nombre de citrouilles: nous ne pouvons avoir que des p-1fantômes sur les pcitrouilles. D'où la formule finale utilisée dans le code:

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

Version ES6, 173 171 166 166 octets

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):''

Cas de test (ES6)

Arnauld
la source
1
Je pense que ça j=(g+g)**.5+.5|0devrait marcher.
Neil
Belle explication!
AdmBorkBork
@Neil C'est plus court et plus fiable. (Ma méthode avait des valeurs non valides, commençant à g = 5051.) Merci.
Arnauld du
3

Perl, 246 octets (les sauts de ligne ne font pas partie du code et sont fournis uniquement à des fins de lisibilité)

($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;

Accepte deux nombres: les citrouilles en premier, suivis des fantômes. Exemple d'entrée:

5 20

Exemple de sortie:

                \{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}/ 
Gabriel Benamy
la source
Oh, vous avez lu ma formulation un peu différente de la façon dont j'avais l'intention - les fantômes ne peuvent s'empiler sur les fantômes que s'il y a une citrouille en dessous, sinon ils doivent aller dans le bon fichier unique. C'est pourquoi le 0p 4gcas de test a tous les fantômes dans une ligne, plutôt qu'empilés.
AdmBorkBork
@TimmyD D'accord, je l'ai corrigé maintenant. Je devrai cependant faire un peu de golf pour le réduire.
Gabriel Benamy