Erzeugen Sie Pascals Braid


32

Das ist Pascals Braid:

 1 4  15  56   209   780    2911    10864     40545      151316      564719
1 3 11  41  153   571   2131    7953     29681     110771      413403      1542841
 1 4  15  56   209   780    2911    10864     40545      151316      564719

Ich habe das total erfunden. Blaise Pascal hatte, soweit ich das beurteilen kann, kein Zopf, und wenn er es tat, bestand es wahrscheinlich aus Haaren anstelle von Zahlen.

Es ist wie folgt definiert:

  1. Die erste Spalte hat eine Single 1in der Mitte.
  2. Die zweite Spalte hat 1oben und unten ein.
  3. Jetzt wechseln wir zwischen einer Zahl in der Mitte oder zwei Kopien einer Zahl oben und unten.
  4. Wenn die Zahl oben oder unten steht, handelt es sich um die Summe der beiden benachbarten Zahlen (z 56 = 15 + 41. B. ). Wenn Sie Ihren Kopf ein wenig neigen, ist dies wie ein Schritt in Pascals Dreieck.
  5. Wenn die Zahl in die Mitte geht, ist es die Summe aller drei benachbarten Zahlen (zB 41 = 15 + 11 + 15).

Ihre Aufgabe wird es sein, dieses Geflecht (teilweise) zu drucken.

Eingang

Sie sollten ein Programm oder eine Funktion schreiben, die eine einzelne Ganzzahl erhält nund den Index der letzten auszugebenden Spalte angibt.

Sie können wählen, ob die erste Spalte (nur eine einzige 1in der mittleren Zeile) n = 0oder entspricht n = 1. Dies muss eine konsistente Wahl für alle möglichen Eingaben sein.

Ausgabe

Gib Pascals Braid in die ndritte Spalte aus. Das Leerzeichen muss genau dem obigen Beispiellayout entsprechen, außer dass Sie die kürzeren Zeilen mit Leerzeichen auf die Länge der längeren Zeilen auffüllen und optional einen einzelnen Zeilenvorschub ausgeben können.

Mit anderen Worten, jede Spalte sollte genau so breit sein wie die Zahl (oder das Paar gleicher Zahlen) in dieser Spalte, die Zahlen in aufeinanderfolgenden Spalten sollten sich nicht überlappen und es sollten keine Leerzeichen zwischen den Spalten vorhanden sein.

Sie können das Ergebnis entweder an STDOUT (oder an die nächstgelegene Alternative) ausgeben oder beim Schreiben einer Funktion entweder eine Zeichenfolge mit demselben Inhalt oder eine Liste mit drei Zeichenfolgen (eine für jede Zeile) zurückgeben.

Weitere Details

Sie können davon ausgehen, dass dies nnicht weniger als der Index der ersten Spalte ist (also nicht weniger als 0oder 1abhängig von Ihrer Indizierung). Sie können auch davon ausgehen, dass die letzte Zahl im Geflecht kleiner als 256 ist oder die größte Zahl, die durch den systemeigenen Ganzzahltyp Ihrer Sprache dargestellt werden kann, je nachdem, welcher Wert größer ist . Also , wenn Ihre Mutter Integer - Typ nur Bytes speichern kann, können Sie davon ausgehen , dass der größte nist 9oder 10(je nachdem , ob Sie verwenden 0- oder 1-basiert n) , und wenn es 32-Bit - Integer unterzeichnet speichern kann, nwird in den meisten 33oder 34.

Es gelten die Standardregeln für . Der kürzeste Code gewinnt.

OEIS

Hier einige relevante OEIS-Links. Natürlich enthalten diese Spoiler für verschiedene Arten, die Zahlen im Geflecht zu generieren:

Testfälle

Diese Testfälle verwenden eine Indexierung auf 1 Basis. Jeder Testfall besteht aus vier Zeilen, von denen die erste die Eingabe und die restlichen drei die Ausgabe sind.

1

1

---
2
 1
1
 1
---
3
 1
1 3
 1
---
5
 1 4
1 3 11
 1 4
---
10
 1 4  15  56   209
1 3 11  41  153
 1 4  15  56   209
---
15
 1 4  15  56   209   780    2911
1 3 11  41  153   571   2131    7953
 1 4  15  56   209   780    2911
---
24
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560
1 3 11  41  153   571   2131    7953     29681     110771      413403      1542841
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560

Das Format kommt mir wie ein kleines Chamäleon vor.
Undichte Nonne

3
@LeakyNun Ich habe diese Herausforderung in der Sandbox ausprobiert und ungefähr halb so viele Bytes für die Berechnung des Geflechts aufgewendet wie für das Drucken. Dies scheint mir eine hervorragende Balance für eine Herausforderung im Bereich der ASCII-Kunst zu sein .
FryAmTheEggman

4
@LeakyNun Ich hatte gehofft, dass sowohl die Sequenzerstellung als auch die ASCII-Grafik wichtige Bestandteile der Herausforderung sind, da die meisten Sprachen wahrscheinlich eine dieser beiden Sprachen besser beherrschen werden. Daher hielt ich es für interessant, sie zu verwechseln. Und es wird eine zusätzliche Komponente eingeführt, bei der es nicht offensichtlich ist, ob es besser ist, oben / unten und in der Mitte getrennt zu generieren oder die gesamte Sache zu generieren und dann die Halbierungen herauszuschneiden.
Martin Ender


Bisher hat noch niemand eine Lösung in Pascal geschrieben. Das macht mich traurig.
Dynamitereed

Antworten:


5

Jelly , 31 30 29 Bytes

Q;S⁹o_
3ḶḂç@⁸СIµa"Ṿ€o⁶z⁶Zµ€Z

Dies ist eine monadische Verbindung; Es akzeptiert einen 0-basierten Spaltenindex als Argument und gibt eine Liste von Zeichenfolgen zurück.

Probieren Sie es online!

Wie es funktioniert

Q;S⁹o_                  Helper link.
                        Arguments: [k, 0, k] and [0, m, 0] (any order)

Q                       Unique; deduplicate the left argument.
 ;                      Concatenate the result with the right argument.
  S                     Take the sum of the resulting array.
   ⁹o                   Logical OR with the right argument; replaces zeroes in the
                        right argument with the sum.
     _                  Subtract; take the difference with the right argument to
                        remove its values.
                        This maps [k, 0, k], [0, m, 0] to [0, k + m, 0] and
                        [0, m, 0], [k, 0, k] to [m + 2k, 0, m + 2k].


3ḶḂç@⁸СIµa"Ṿ€o⁶z⁶Zµ€Z  Monadic link. Argument: A (array of column indices)

3Ḷ                      Yield [0, 1, 2].
  Ḃ                     Bit; yield [0, 1, 0].
        I               Increments of n; yield [].
      С                Apply...
   ç@                       the helper link with swapped arguments...
     ⁸                      n times, updating the left argument with the return
                            value, and the right argument with the previous value
                            of the left one. Collect all intermediate values of
                            the left argument in an array.
         µ         µ€   Map the chain in between over the intermediate values.
            Ṿ€          Uneval each; turn all integers into strings.
          a"            Vectorized logical AND; replace non-zero integers with
                        their string representation.
              o⁶        Logical OR with space; replace zeroes with spaces.
                z⁶      Zip with fill value space; transpose the resulting 2D
                        array after inserting spaces to make it rectangular.
                  Z     Zip; transpose the result to restore the original shape.
                     Z  Zip; transpose the resulting 3D array.

12

Pyth , 44 Bytes

Die Nummerngenerierung dauerte 20 Bytes und die Formatierung 24 Bytes.

jsMC+Led.e.<bkC,J<s.u+B+hNyeNeNQ,1 1Qm*;l`dJ

Probieren Sie es online!

jsMC+Led.e.<bkC,J<s.u+B+hNyeNeNQ,1 1Qm*;l`dJ   input as Q
                   .u          Q,1 1           repeat Q times, starting with [1,1],
                                               collecting all intermediate results,
                                               current value as N:
                                               (this will generate
                                                more than enough terms)
                       +hNyeN                  temp <- N[0] + 2*N[-1]
                     +B      eN                temp <- [temp+N[-1], temp]

now, we would have generated [[1, 1], [3, 4], [11, 15], [41, 56], ...]

jsMC+Led.e.<bkC,J<s                 Qm*;l`dJ
                  s                            flatten
                 <                  Q          first Q items
                J                              store in J
                                     m    dJ   for each item in J:
                                         `     convert to string
                                        l      length
                                      *;       repeat " " that many times

jsMC+Led.e.<bkC,
              C,     transpose, yielding:
[[1, ' '], [1, ' '], [3, ' '], [4, ' '], [11, '  '], ...]
(each element with as many spaces as its length.)
        .e            for each sub-array (index as k, sub-array as b):
          .<bk            rotate b as many times as k

[[1, ' '], [' ', 1], [3, ' '], [' ', 4], [11, '  '], ...]

jsMC+Led
    +Led              add to each sub-array on the left, the end of each sub-array
   C                  transpose
 sM                   sum of each sub-array (reduced concatenation)
j                     join by new-lines

7
Das ist das größte Pyth-Programm, das ich je gesehen habe.
Imallett


7

MATL , 38 Bytes

1ti:"yy@oQ*+]vG:)!"@Vt~oX@o?w]&v]&hZ}y

Probieren Sie es online!

Die Berechnung eines Arrays mit den (eindeutigen) Zahlen benötigt die ersten 17 Bytes. Für die Formatierung werden die restlichen 21 Bytes benötigt.

Erläuterung

Teil 1: Generiere die Zahlen

Dies erzeugt einen Array mit den Zahlen von der ersten und zweiten Reihe , um zunehmend: [1; 1; 3; 4; 11; 15; ...]. Es beginnt mit 1, 1. Jede neue Nummer wird iterativ aus den beiden vorhergehenden erhalten. Davon wird die Sekunde mit 1oder multipliziert2 dem Iterationsindex Abhängigkeit davon und dann zur ersten aufsummiert, um die neue Zahl zu erhalten.

Die Anzahl der Iterationen entspricht der Eingabe n. Dies bedeutet, dass n+2Zahlen generiert werden. Nach der Generierung muss das Array gekürzt werden, damit nur die ersten nEinträge erhalten bleiben.

1t      % Push 1 twice
i:      % Take input n. Generage array [1 2 ... n]
"       % For each
  yy    %   Duplicate the two most recent numbers
  @o    %   Parity of the iteration index (0 or 1)
  Q     %   Add 1: gives 1 for even iteration index, 2 for odd
  *+    %   Multiply this 1 or 2 by the most recent number in the sequence, and add
       %    to the second most recent. This produces a new number in the sequence
]       % End for each
v       % Concatenate all numbers in a vertical array
G:)     % Keep only the first n entries

Teil 2: Formatieren Sie die Ausgabe

Für jede Zahl in dem erhaltenen Array werden zwei Zeichenfolgen generiert: Zeichenfolgendarstellung der Zahl und eine Zeichenfolge mit derselben Länge, die aus dem wiederholten Zeichen 0 besteht (das Zeichen 0 wird in MATL als Leerzeichen angezeigt). Für gleichmäßige Iterationen werden diese beiden Zeichenfolgen vertauscht.

Die beiden Zeichenfolgen werden dann vertikal verkettet. So werden n2D- ·Zeichen- Arrays wie folgt erzeugt ( zur Darstellung von Zeichen 0):

·
1

1
·

· 
3

4
·

·· 
11

15
··

Diese Arrays werden dann horizontal verkettet, um sie zu erzeugen

·1·4··15
1·3·11··

Schließlich wird dieses 2D-Zeichen-Array in zwei Zeilen aufgeteilt, und die erste Zeile wird oben auf dem Stapel dupliziert. Die drei Zeichenfolgen werden der Reihe nach in einer anderen Zeile angezeigt, um die gewünschte Ausgabe zu erzielen

!       % Transpose into a horizontal array [1 1 3 4 11 15 ...]
"       % For each
  @V    %   Push current number and convert to string
  t~o   %   Duplicate, negate, convert to double: string of the same length consisting 
        %   of character 0 repeated
  X@o   %   Parity of the iteration index (1 or 0)
  ?     %   If index is odd
    w   %     Swap
  ]     %   End if
  &v    %   Concatenate the two strings vertically. Gives a 2D char array representing
        %   a "numeric column" of the output (actually several columns of characters)
]       % End for
&h      % Concatenate all 2D char arrays horizontally. Gives a 2D char array with the
        % top two rows of the output
Z}      % Split this array into its two rows
y       % Push a copy of the first row. Implicitly display

6

Haskell, 101 Bytes

a=1:1:t
t=3:4:zipWith((-).(4*))t a
g(i,x)=min(cycle" 9"!!i)<$>show x
f n=[zip[y..y+n]a>>=g|y<-[0..2]]

Definiert eine Funktion f :: Int → [String].

  • Michael Klein erinnerte mich daran, dass ich unlinesdas Ergebnis nicht aufrufen musste , um 7 Bytes zu sparen. Vielen Dank!

  • Ich sparte ein Byte durch den Ersatz " 9"!!mod i 2mit cycle" 9"!!i.

  • Drei weitere Bytes durch Schreiben von zwei kerncursiven Listen anstelle von drop.

  • Meine Freundin wies darauf hin, dass ich zwei weitere Bytes einsparen kann, indem ich meine Antworten bei 0anstatt bei beginne 1.


3

C 183 177 176 Bytes

#define F for(i=0;i<c;i++)
int i,c,a[35],t[9];p(r){F printf("%*s",sprintf(t,"%d",a[i]),r-i&1?t:" ");putchar(10);}b(n){c=n;F a[i]=i<2?1:a[i-2]+a[i-1]*(i&1?1:2);p(0);p(1);p(0);}

Erläuterung

C wird niemals einen Preis für Kürze gegen eine höhere Sprache gewinnen, aber die Übung ist interessant und eine gute Übung.

Das Makro F spart sechs Bytes auf Kosten der Lesbarkeit. Variablen werden global deklariert, um Mehrfachdeklarationen zu vermeiden. Ich brauchte einen Zeichenpuffer für sprintf, aber da K & R die Typprüfung nicht beherrscht, können sprintf und printf t [9] als Zeiger auf einen 36-Byte-Puffer interpretieren. Dadurch wird eine separate Erklärung gespeichert.

#define F for(i=0;i<c;i++)
int i,c,a[35],t[9];

Hübsche Druckfunktion, wobei r die Zeilennummer ist. Sprintf formatiert die Zahl und berechnet die Spaltenbreite. Um Platz zu sparen, rufen wir dies einfach dreimal auf, einmal für jede Ausgabezeile. Der Ausdruck ri & 1 filtert, was gedruckt wird.

p(r) {
    F
        printf("%*s", sprintf(t, "%d", a[i]), r-i&1 ? t
                                                    : " ");
    putchar(10);
}

Einstiegspunktfunktion, Argument ist Anzahl der Spalten. Berechnet das Array a der Spaltenwerte a [] und ruft dann die Druckfunktion p einmal für jede Ausgabezeile auf.

b(n) {
    c=n;
    F
        a[i] = i<2 ? 1
                   : a[i-2] + a[i-1]*(i&1 ? 1
                                          : 2);
    p(0);
    p(1);
    p(0);
}

Beispielaufruf (nicht in Antwort und Byteanzahl enthalten):

main(c,v) char**v;
{
    b(atoi(v[1]));
}

Aktualisiert

Integrierte den Inline-Sprintf-Vorschlag von Tomsmeding. Dadurch wurde die Anzahl von 183 auf 177 Zeichen reduziert. Auf diese Weise können Sie auch die geschweiften Klammern um den printf (sprintf ()) - Block entfernen, da es sich nur um eine Anweisung handelt, die jedoch nur ein Zeichen gespeichert hat, da sie weiterhin ein Leerzeichen als Trennzeichen benötigt. Also runter auf 176.


Können Sie die Definition des wVerwendungsorts nicht inline angeben ? Sie scheinen es nur einmal zu benutzen.
Tomsmeding

Sie können nicht itoaanstelle von Sprintf verwenden?
Giacomo Garabello

Ich habe es in Betracht gezogen, aber es ist auf meinem System nicht vorhanden, und ich verwende den Rückgabewert von sprintf, um die Feldbreite festzulegen.
Maharvey67

2

PowerShell v2 +, 133 Byte

param($n)$a=1,1;1..$n|%{$a+=$a[$_-1]+$a[$_]*($_%2+1)};$a[0..$n]|%{$z=" "*$l+$_;if($i++%2){$x+=$z}else{$y+=$z}$l="$_".Length};$x;$y;$x

44 Bytes zur Berechnung der Werte, 70 Bytes zur Formulierung des ASCII

Übernimmt die Eingabe $nals nullindizierte Spalte. Legt den Beginn unseres Sequenzarrays fest $a=1,1. Wir machen dann eine Schleife $nmit 1..$n|%{...}, um das Array zu konstruieren. Bei jeder Iteration verketten wir die Summe von (vor zwei Elementen) + (voriges Element) * (ungerader oder gerader Index). Dies erzeugt $a=1,1,3,4,11...bis zu$n+2 .

Wir müssen also schneiden, $aum nur die ersten 0..$nElemente zu nehmen und diese durch eine andere Schleife zu leiten |%{...}. Bei jeder Iteration setzen wir den Helfer $zgleich einer Anzahl von Leerzeichen plus dem aktuellen Element als Zeichenfolge. Dann teilen wir uns auf, ob das durch ein einfaches ungerades / auf $x(die obere und untere Reihe) oder $y(die mittlere Reihe) verkettet wird . Dann berechnen wir die Anzahl der Leerzeichen, indem wir die aktuelle Zahl nehmen, sie stringifizieren und ihre nehmen .ifelse$l.Length

Schließlich setzen wir $x, $yund $xwieder an der Pipeline und die Ausgabe ist implizit. Da das Standardtrennzeichen .ToString()für ein Array beim Drucken auf STDOUT ein Zeilenumbruch ist, erhalten Sie diesen kostenlos.

Beispiel

PS C:\Tools\Scripts\golfing> .\pascal-braid.ps1 27
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560       7865521        29354524
1 3 11  41  153   571   2131    7953     29681     110771      413403      1542841       5757961       21489003
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560       7865521        29354524

0

PHP 265 Bytes

<?php $i=$argv[1];$i=$i?$i:1;$a=[[],[]];$s=['',''];$p='';for($j=0;$j<$i;$j++){$y=($j+1)%2;$x=floor($j/2);$v=$x?$y?2*$a[0][$x-1]+$a[1][$x-1]:$a[0][$x-1]+$a[1][$x]:1;$s[$y].=$p.$v;$a[$y][$x]=$v;$p=str_pad('',strlen($v),' ');}printf("%s\n%s\n%s\n",$s[0],$s[1],$s[0]);

Nicht golfen:

$a = [[],[]];
$s = ['',''];

$p = '';

$i=$argv[1];
$i=$i?$i:1;
for($j=0; $j<$i; $j++) {
    $y = ($j+1) % 2;
    $x = floor($j/2);

    if( $x == 0 ) {
        $v = 1;
    } else {
        if( $y ) {
            $v = 2 * $a[0][$x-1] + $a[1][$x-1];
        } else {
            $v = $a[0][$x-1] + $a[1][$x];
        }
    }
    $s[$y] .= $p . $v;
    $a[$y][$x] = $v;
    $p = str_pad('', strlen($v), ' ');
}

printf("%s\n%s\n%s\n", $s[0], $s[1], $s[0]);

Python 278 Bytes

import sys,math;a=[[],[]];s=['',''];p='';i=int(sys.argv[1]);i=1 if i<1 else i;j=0
while j<i:y=(j+1)%2;x=int(math.floor(j/2));v=(2*a[0][x-1]+a[1][x-1] if y else a[0][x-1]+a[1][x]) if x else 1;s[y]+=p+str(v);a[y].append(v);p=' '*len(str(v));j+=1
print ("%s\n"*3)%(s[0],s[1],s[0])

0

Ruby, 120 Bytes

Gibt eine mehrzeilige Zeichenfolge zurück.

Probieren Sie es online!

->n{a=[1,1];(n-2).times{|i|a<<(2-i%2)*a[-1]+a[-2]}
z=->c{a.map{|e|c+=1;c%2>0?' '*e.to_s.size: e}*''}
[s=z[0],z[1],s]*$/}

0

Matlab, 223 Zeichen, 226 Bytes

function[]=p(n)
r=[1;1];e={(' 1 ')',('1 1')'}
for i=3:n;r(i)=sum((mod(i,2)+1)*r(i-1)+r(i-2));s=num2str(r(i));b=blanks(floor(log10(r(i)))+1);if mod(i,2);e{i}=[b;s;b];else e{i}=[s;b;s];end;end
reshape(sprintf('%s',e{:}),3,[])

Ungolfed und kommentiert:

function[]=p(n) 
r=[1;1];                                    % start with first two 
e={(' 1 ')',('1 1')'}                       % initialize string output as columns of blank, 1, blank and 1, blank, 1.
for i=3:n;                                  % for n=3 and up! 
    r(i)=sum((mod(i,2)+1)*r(i-1)+r(i-2));   % get the next number by 1 if even, 2 if odd times previous plus two steps back
    s=num2str(r(i));                        % define that number as a string
    b=blanks(floor(log10(r(i)))+1);         % get a number of space characters for that number of digits
    if mod(i,2);                            % for odds
        e{i}=[b;s;b];                       % spaces, number, spaces
    else                                    % for evens
        e{i}=[s;b;s];                       % number, spaces, number
    end;
end
reshape(sprintf('%s',e{:}),3,[])            % print the cell array of strings and reshape it so it's 3 lines high

0

PHP, 135 124 123 120 Bytes

<?while($i<$argv[1]){${s.$x=!$x}.=${v.$x}=$a=$i++<2?:$v1+$v+$x*$v;${s.!$x}.=str_repeat(' ',strlen($a));}echo"$s
$s1
$s";

unter ausnutzung impliziter typecasts und variabler variablen geht
ein drittel des codes (37 bytes) in die räume, insgesamt werden 64 bytes für die ausgabe verwendet

Nervenzusammenbruch

$i=0; $x=false; $v=$v1=1; $s=$s1='';    // unnecessary variable initializations
for($i=0;$i<$argv[1];$i++)  // $i is column number -1
{
    $x=!$x; // $x = current row: true (1) for inner, false (empty string or 0) for outer
    // calculate value
    $a=
        $i<2?               // first or second column: value 1
        :$v1+(1+$x)*$v      // inner-val + (inner row: 1+1=2, outer row: 1+0=1)*outer-val
    ;
    ${s.$x}.=${v.$x}=$a;    // replace target value, append to current row
    ${s.!$x}.=str_repeat(' ',strlen($a));    // append spaces to other row
}
// output
echo "$s\n$s1\n$s";

0

Batch, 250 Bytes

@echo off
set s=
set d=
set/ai=n=0,j=m=1
:l
set/ai+=1,j^^=3,l=m+n*j,m=n,n=l
set t=%s%%l%
for /l %%j in (0,1,9)do call set l=%%l:%%j= %%
set s=%d%%l%
set d=%t%
if not %i%==%1 goto l
if %j%==1 echo %d%
echo %s%
echo %d%
if %j%==2 echo %s%

Da die erste und dritte Zeile gleich sind, müssen wir nur zwei Zeichenfolgen erstellen. Hier wird ddie Zeichenfolge dargestellt, die mit dem letzten Eintrag endet, und sdie Zeichenfolge, die mit Leerzeichen endet. Die letzten vier Zeilen stellen sicher, dass sie in der richtigen Reihenfolge gedruckt werden. iist nur der Schleifenzähler (es ist etwas billiger als abwärts zu zählen %1). jist das Umschalten zwischen dem Verdoppeln der vorherigen Nummer vor dem Hinzufügen zur aktuellen Nummer, um die nächste Nummer zu erhalten. mund nenthalten diese Zahlen. lEr wird nicht nur temporär zur Berechnung der nächsten Zahl verwendet, ssondern erhält auch Ziffern, die durch Leerzeichen zum Ausfüllen ersetzt werden . sund dwerden jeweils über die Zwischenvariable ausgetauscht t.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.