Geister und Kürbisse

15

Hier ist ein ASCII-Kürbis, der in eine Kürbislaterne geschnitzt ist. Ist es nicht süß?

((^v^))

Hier ist ein ASCII-Geist. Schau wie gruselig es ist!

\{O.O}/

Offensichtlich müssen die Kürbisse auf dem Boden sein, mit einem Abstand zwischen ihnen, damit sie nicht verrotten.

Geister stehen jedoch gerne auf Kürbissen, sodass sie noch gruseliger sind . Sie müssen sich jedoch auf zwei Kürbisse stellen, sonst wird ihr gespenstisches Gewicht den Kürbis unter ihnen zerdrücken. Aber wegen , wie sie ihre geisterhafte Magie funktioniert, können mehrere Geister stapeln und mit anderen teilen Kürbisse, vorausgesetzt , dass die Geister sind entweder Split gleichmäßig auf den unteren Kürbisse oder den unteren Geister. Mit anderen Worten, eine Form wie eine menschliche Pyramide bilden . Beachten Sie, dass Geister nur dann auf Geister stapeln können, wenn sich ein Kürbis darunter befindet (so funktioniert die Magie).

Wenn zwei nicht negative ganze Zahlen gegeben sind gund pdie Anzahl der gHosts und pUmpkins repräsentieren, wird gemäß den obigen Pyramidenstapelregeln die am weitesten links liegende Formation ausgegeben, die möglichst kompakt ist. Übrig gebliebene Kürbisse und Geister (dh solche, die nicht die Pyramide bilden) gehen rechts auf den Boden.

Zur Verdeutlichung sind diese Formationen in Ordnung (durch leere Zeilenumbrüche getrennt) und dienen als Beispiel-E / A:

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

Diese Formationen sind nicht 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^))

Eingang

Zwei nicht negative ganze Zahlen in einem beliebigen Format . Mindestens eine der Zahlen ist ungleich Null. Sie können die Eingaben in beliebiger Reihenfolge vornehmen (z. B. in den Beispielen, in denen ich zuerst Kürbisse hatte). Geben Sie in Ihrer Antwort an, wie Sie Eingaben vornehmen.

Ausgabe

Eine ASCII-artige Darstellung der Geister und Kürbisse nach den obigen Regeln. Führende / nachfolgende Zeilenumbrüche oder andere Leerzeichen sind optional, sofern die Geister und Kürbisse richtig ausgerichtet sind.

Regeln

  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig. Bei einer Funktion können Sie die Ausgabe zurückgeben, anstatt sie zu drucken.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.
AdmBorkBork
quelle
Was ist die richtige Formation für 7 Kürbisse und 6 Geister?
Neil
@Neil Da nach den Regeln die kompakteste Ausgabe ganz links verlangt wird, ist dies eine Pyramide von 6 Geistern auf 4 Kürbissen, und zusätzlich 3 Kürbisse auf der rechten Seite. Ich werde es als Beispiel hinzufügen.
AdmBorkBork
Nun, Ihre Verwendung von Compact hat mich verwirrt - ich könnte alle Geister in die gleiche Reihe bringen, das ist also vertikal kompakter!
Neil
Werden Kürbisse immer vor Geistern geliefert?
Gabriel Benamy
2
Ich mag, dass die Geister und Kürbisse eine menschliche Pyramide machen
MayorMonty

Antworten:

5

JavaScript (ES7), 166 164 159 Bytes

5 Bytes gespart dank 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):''

Formatiert und kommentiert

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

Grundlegende Mathematik

Der schwierige Teil ist, die optimale Breite Gder Geisterpyramide herauszufinden .

Die Anzahl der Geister gin einer solchen Pyramide ergibt sich aus:

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

Umgekehrt ist die Breite einer Pyramide, die gGeister enthält, die wahre Wurzel der resultierenden quadratischen Gleichung:

G² + G - 2g = 0

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

G = (-1 ± √Δ) / 2

Dies führt zu folgender reellen Wurzel (auch Dreieckswurzel genannt ):

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

Die Breite der Pyramide ist jedoch auch durch die Anzahl der Kürbisse begrenzt: Wir können nicht mehr als p-1Geister über pKürbisse haben. Daher die endgültige Formel, die im Code verwendet wird:

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

ES6-Version, 173 171 166 Bytes

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

Testfälle (ES6)

Arnauld
quelle
1
Ich denke j=(g+g)**.5+.5|0sollte funktionieren.
Neil
Schöne Erklärung!
AdmBorkBork
@Neil Das ist kürzer und zuverlässiger. (Meine Methode hatte einige ungültige Werte, beginnend mit g = 5051.) Danke.
Arnauld
3

Perl, 246 Byte (Zeilenumbrüche sind nicht Teil des Codes und dienen ausschließlich der Lesbarkeit)

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

Akzeptiert zwei Zahlen: zuerst Kürbisse, dann Geister. Beispieleingabe:

5 20

Beispielausgabe:

                \{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
quelle
Oh, Sie haben meine Formulierung etwas anders gelesen, als ich es beabsichtigt hatte - Geister können nur dann auf Geister gestapelt werden, wenn sich ein Kürbis darunter befindet, andernfalls müssen sie zur richtigen Einzelfeile wechseln. Aus diesem Grund sind im 0p 4gTestfall alle Geister in einer Zeile angeordnet und nicht gestapelt.
AdmBorkBork
@TimmyD Okay, ich habe es jetzt behoben. Ich muss ein bisschen Golf spielen, um es zu reduzieren.
Gabriel Benamy