Hakenlänge Produkt

27

Ein junges Diagramm ist eine Anordnung von Feldern in linksbündigen Zeilen und obenbündigen Spalten. Für jedes Kästchen sind alle darüber und links davon befindlichen Felder belegt.

XXXXX
XXX
XXX
X

Die Hakenlänge einer Box ist die Anzahl der Boxen rechts in der Reihe und darunter in der Spalte, die sich ebenfalls einmal selbst zählen. Zum Beispiel hat die zweite Box eine Hakenlänge von 6:

X****
X*X
X*X
X

Hier sind alle Hakenlängen:

86521
532
421
1

Ihr Ziel ist es , hier das Produkt der Hakenlängen zu berechnen 8*6*5*2*1*5*3*2*4*2*1*1 = 115200.

(Informieren Sie sich über die Hakenlängenformel, wenn Sie daran interessiert sind, warum dieser Ausdruck wichtig ist.)

Eingabe: Eine Sammlung von Zeilengrößen als Zahlen wie [5,3,3,1]oder als wiederholtes unäres Symbol wie [[1,1,1,1,1], [1,1,1], [1,1,1], [1]]oder "XXXXX XXX XXX X". Sie können davon ausgehen, dass die Liste aufsteigend oder absteigend sortiert ist. Die Liste ist nicht leer und enthält nur positive ganze Zahlen.

Ausgabe: Das Produkt der Hakenlängen, das eine positive ganze Zahl ist. Sorgen Sie sich nicht um Integer-Überläufe oder Laufzeit.

Integrierte Funktionen, die sich speziell mit Young-Diagrammen oder Ganzzahlpartitionen befassen, sind nicht zulässig.

Testfälle:

[1] 1
[2] 2
[1, 1] 2
[5] 120
[2, 1] 3
[5, 4, 3, 2, 1] 4465125
[5, 3, 3, 1] 115200
[10, 5] 798336000
xnor
quelle

Antworten:

13

CJam, 20 bis 19 Bytes

{ee::+W%}_q~%z%:+:*

Dies nimmt die unäre Liste im CJam-Stil in aufsteigender Reihenfolge auf. Beispielsweise:

[[1] [1 1 1] [1 1 1] [1 1 1 1 1]]

gibt

115200

Wie es funktioniert

Diese Version wird von Dennis zur Verfügung gestellt und nutzt die Tatsache, dass eine Block ArrayList %noch in CJam: D funktioniert

{       }_             e# Put this block on stack and make a copy
          q~           e# Read the input and evaluate it to put the array of arrays on stack
            %          e# Use the copy of the block and map the array using that block
 ee                    e# Here we are mapping over each unary array in the input. ee converts
                       e# the array to [index value] pair.
   ::+                 e# Add up each index value pair. Now we have the horizontal half of
                       e# hook length for each row
      W%               e# Reverse the array to make sure the count is for blocks to the right
             z%        e# Transpose and do the same mapping for columns
               :+      e# Now we have all the hook lengths. Flatten the array
                 :*    e# Get the product of all hook lengths.

Dies ist die ursprüngliche 20-Byte-Version

1q~:,Wf%z:ee{:+)*}f/

Dies nimmt eine CJam-Style-Liste mit Zeilengrößen in aufsteigender Reihenfolge auf. Beispielsweise:

[1 3 3 5]

gibt

115200

Wie es funktioniert

Wenn wir es uns ansehen, ist die Hook-Länge jedes Blocks in einem Young-Blockdiagramm die Summe des Indexes dieses Blocks in seiner Zeile und Spalte, wobei rückwärts gezählt wird. dh Starten Sie den Index in jeder Zeile von rechts und den Index in jeder Spalte von unten.

Wir nehmen die Eingabe in aufsteigender Reihenfolge der Zeilengröße, um den Index in jeder Spalte einfach von unten zu starten. Zuerst erhalten wir den Index pro Zeile und kehren ihn um. Dann transponieren wir. Da die ursprüngliche Zeilenreihenfolge umgekehrt wurde, ergibt die Indexaufnahme in diesem transponierten Diagramm direkt den Index von unten nach oben.

Code-Erweiterung

1                       e# This serves as the initial term for product of hook lengths
 q~                     e# Read the input and eval it to put an array on stack
   :,                   e# For each row-size (N), get an array of [0..N-1]
     Wf%                e# Reverse each row so that each row becomes [N-1..0]
        z               e# Transpose for the calculation of blocks below each block
         :ee            e# Enumerate each row. Convert it into array of [index value] pairs
            {    }f/    e# Apply this mapping block to each cell of each row
             :+         e# Add the index value pair. Here, index is the blocks below the
                        e# block and value is the blocks to the right of it in the Young diag
               )        e# Increment the sum by 1 to account for the block itself
                *       e# Multiply it with the current holding product, starting with 1

Probieren Sie es hier online aus

Optimierer
quelle
{ee::+W%}_q~%z%:+:*(19 Bytes) Eingabeformat:[[1][1 1 1][1 1 1][1 1 1 1 1]]
Dennis
@Dennis Nice (ab) Verwendungszweck für %: P
Optimizer
6

J, 24 Bytes

*/@,@(1|@-+/\."1++/\)@:>

25 Bytes (mit Erklärung):

*/@,@(+/\."1|@<:@++/\)@:>

Übernimmt die Eingabe als Liste aufsteigender Listen mit unären Ziffern, ähnlich wie im Beispiel [[1], [1,1,1], [1,1,1], [1,1,1,1,1]].

Verwendung:

   f=.*/@,@(+/\."1|@<:@++/\)@:>

   f 1;1 1 1;1 1 1;1 1 1 1 1
115200

Methode

  • Erstellen Sie eine binäre Matrix aus der Eingabe
  • Berechnen Sie die Laufdifferenzen in beiden Dimensionen.
  • Addiere für jede Zelle die beiden Ergebnisse, subtrahiere 1, nimm den absoluten Wert (um die ursprünglich null Zellen auf 1 abzubilden)
  • Ravel die Matrix und nimm das Produkt der Zahlen.

Zwischenergebnisse werden in der Eingabe angezeigt 1 1 1 1 1;1 1 1;1 1 1;1 (5,3,3,1 in unary)( dies gilt für eine frühere Version mit absteigender Länge, jedoch mit derselben Methode ):

   ]c=.1 1 1 1 1;1 1 1;1 1 1;1
┌─────────┬─────┬─────┬─┐
│1 1 1 1 1│1 1 1│1 1 1│1│
└─────────┴─────┴─────┴─┘

   (>)  c
1 1 1 1 1
1 1 1 0 0
1 1 1 0 0
1 0 0 0 0

   (+/\.@:>)  c
4 3 3 1 1
3 2 2 0 0
2 1 1 0 0
1 0 0 0 0

   (+/\."1@:>)  c
5 4 3 2 1
3 2 1 0 0
3 2 1 0 0
1 0 0 0 0

   ((+/\."1++/\.)@:>)  c
9 7 6 3 2
6 4 3 0 0
5 3 2 0 0
2 0 0 0 0

   ((+/\."1<:@++/\.)@:>)  c
8  6  5  2  1
5  3  2 _1 _1
4  2  1 _1 _1
1 _1 _1 _1 _1

   ((+/\."1|@<:@++/\.)@:>)  c
8 6 5 2 1
5 3 2 1 1
4 2 1 1 1
1 1 1 1 1

   (,@(+/\."1|@<:@++/\.)@:>)  c
8 6 5 2 1 5 3 2 1 1 4 2 1 1 1 1 1 1 1 1

   (*/@,@(+/\."1|@<:@++/\.)@:>)  c
115200

Explizite Version mit gleicher Länge:

3 :'*/,|<:(+/\."1++/\)>y'

Probieren Sie es hier online aus.

randomra
quelle
4

Pyth - 21 Bytes

Ich verliere eine Menge Bytes in der vertikalen Berechnung. Ich werde mich darauf konzentrieren, das zu spielen.

*Fs.em+lf>Td>Qkt-bdbQ

Nimmt Eingaben wie [5, 3, 3, 1].

Probieren Sie es hier online .

Maltysen
quelle
4

Pyth, 18 Bytes

*Fsm.e+k-bdf>TdQeQ

Nimmt die Eingabe in aufsteigender Reihenfolge vor [1, 3, 3, 5].

Demonstration.


Alternative Lösung, 19 Byte

*Fs.em+s>Rd<Qk-bdbQ
isaacg
quelle
3

Python 2, 89 88 Bytes

p=j=-1;d={}
for n in input():j+=1;i=0;exec"a=d[i]=d.get(i,j);p*=n-i+j-a;i+=1;"*n
print-p

(Danke an @xnor für das Speichern eines verrückten Bytes durch Kombinieren von pund j)

Das d.getsieht für mich etwas verdächtig aus, aber sonst bin ich damit relativ zufrieden. Ich habe einige andere Ansätze ausprobiert, wie Rekursion und Zippen, aber dies ist der einzige, den ich unter 100 geschafft habe.

Übernimmt die Eingabe von STDIN als Liste in aufsteigender Reihenfolge, z [1, 3, 3, 5].

Sp3000
quelle
3

Haskell, 68 Bytes

f[]=1
f g@(h:t)=(h+length t)*f[x-1|x<-g,x>1]
p[]=1
p g@(_:t)=f g*p t

Anwendungsbeispiel: p [5,4,3,2,1]->4465125

fDurchsucht von links nach rechts, indem die Länge des äußersten Hakens mit einem rekursiven Aufruf an sich selbst multipliziert wird, wobei jedes Element der Eingabeliste um reduziert wird 1(beim Erreichen fallenlassen 0). pScannt von oben nach unten, indem fdie gesamte Liste mit pdem Schwanz multipliziert wird .

nimi
quelle
2

R, 174 Bytes

Also ... Diese Lösung ist ziemlich lang und könnte wahrscheinlich mehr Golf sein. Ich denke drüber nach !

v=c();d=length;m=matrix(-1,l<-d(a<-scan()),M<-max(a));for(i in 1:l)m[i,(1:a[i])]=c(a[i]:1);for(j in 1:M)m[,j]=m[,j]+c((((p=d(which(m[,j]>0)))-1)):0,rep(0,(l-p)));abs(prod(m))

Ungolfed:

v=c()          #Empty vector
d=length       #Alias

m=matrix(-1,l<-d(a<-scan()),M<-max(a)) #Builds a matrix full of `-1`

for(i in 1:l)
    m[i,(1:a[i])]=c(a[i]:1) #Replaces each row of the matrix by `n` to 1, `n` being the 
                            #corresponding input : each number is the number of non-empty
                            #cells at its left + itself

for(j in 1:M)
    m[,j]=m[,j]+c((((p=d(which(m[,j]>0)))-1)):0,rep(0,(l-p)))

    #This part calculates the number of "non-empty" (i.e. without `-1` in a column), -1,
    #because the count for the cell itself is already done.
    # Then, it creates a vector of those count, appending 0's at the end if necessary 
    #(this avoids recycling)

abs(prod(m)) #Outputs the absolute value of the product (because of the `-1`'s)
Frédéric
quelle
1

Python 2, 135 128 Bytes

Dies nimmt eine Python-Typ-Liste von stdin:

r=input()
c=[-1]*r[0]
for a in r:
 for b in range(a):c[b]+=1
s=1
y=0
for a in r:
 for x in range(a):s*=a-x+c[x]-y
 y+=1
print s

Dies ist eine sehr kanonische Implementierung, aber ich habe bisher noch nichts Klügeres gefunden. Ich habe das Gefühl, dass es auch mit "echten" Programmiersprachen viel kürzere Lösungen geben wird.

Wir erhalten die Anzahl der Kästchen in jeder Zeile als Eingabe. Diese Lösung zählt zuerst die Anzahl der Kästchen in jeder Spalte, in der sie gespeichert ist c(es ist tatsächlich die Anzahl minus 1, um die Verwendung in der späteren Berechnung zu vereinfachen). Dann durchläuft es alle Felder und multipliziert die Hakenlängen. Die Hakenlänge selbst ist trivial zu berechnen, sobald Sie die Anzahl der Kästchen in jeder Zeile und Spalte haben.

Reto Koradi
quelle
1
Sieht aus wie Sie nicht verwenden m?
Donnerstag,
Hätte schwören können, dass ich es gelöscht habe! Ich erinnere mich, dass ich bemerkt habe, dass ich es nur einmal verwendet habe und die einzige Verwendung ersetzt habe. Aber dann muss ich es versäumt haben, die Variable tatsächlich zu löschen. :(
Reto Koradi
1

JavaScript ( ES6 ) 69

Eine Funktion, die ein Array von Ganzzahlen in aufsteigender Reihenfolge verwendet.

Führen Sie das zu testende Snippet aus (nur Firefox)

F=x=>x.map(r=>{for(i=-1;++i<r;p[i]=-~p[i])t*=r-i+~~p[i]},p=[],t=1)&&t

// TEST
out=x=>O.innerHTML += x + '\n';

test=[
 {y:[1], h: 1}
,{y:[2], h: 2}
,{y:[1, 1], h: 2}
,{y:[5], h: 120}
,{y:[2, 1], h: 3}
,{y:[5, 4, 3, 2, 1], h: 4465125}
,{y:[5, 3, 3, 1], h: 115200}
,{y:[10, 5], h: 798336000}
]

test.forEach(t=>{ 
  t.y.reverse(); // put in ascending order
  r=F(t.y);
  out((r==t.h? 'Ok':'Fail')+' Y: ['+t.y+'] Result:'+r+' Check:'+t.h)
})  
<pre id=O></pre>

edc65
quelle
1

Python, 95 91 Bytes

Dies ist eine Python-Implementierung von Nimis Haskell-Antwort . Golfvorschläge sind willkommen.

f=lambda z:z==[]or(z[0]+len(z)-1)*f([i-1for i in z if~-i])
p=lambda z:z==[]or f(z)*p(z[1:])
Sherlock9
quelle
Willkommen beim Python-Golfen! Sie können tun, z and _ or 1als z==[]or _wenn zeine Liste ist, mit der Tatsache, dass True==1. Pythons Funktionsdeklarationen sind wortreicher als die von Haskell, daher lohnt es sich oft, eine einzige rekursive Funktion zu definieren, die sowohl die inneren als auch die äußeren rekursiven Schleifen ausführt, obwohl ich nicht weiß, wie machbar das hier ist.
xnor
@xnor "Willkommen beim Python-Golfen"?
Sherlock9
Oh, sorry, du spielst Golf in Python. Ich verbinde dich mit Actually.
xnor
@xnor Lange bevor ich anfing, spielte ich in Python Golf. Ich bin ein wenig beleidigt, an das Sie sich nicht erinnern können: P
Sherlock9
Ich kann nicht für xnor sprechen, aber ich erkenne Benutzer hauptsächlich an ihrem Avatar.
Dennis