Berechnen Sie die Delacorte-Zahl eines Quadrats

12

Herausforderung: Berechnung einer Delacorte-Zahl in einer beliebigen Sprache durchführen. Kürzester Code gewinnt.

Für eine gegebene quadratische Matrix von verschiedenen ganzen Zahlen 1..n² (mögliche Seitenlänge n mindestens zwischen 3 und 27) ist ihre Delacorte-Zahl die Summe der Produkte gcd (a, b) × distance² (a, b) für jedes einzelne ganzzahliges Paar {a, b}.

Das folgende Beispiel zeigt ein 3 × 3-Quadrat mit einer Delacorte-Zahl von 160.

3 2 9
4 1 8
5 6 7

In diesem Quadrat haben wir 36 verschiedene Paare zu berechnen, zum Beispiel das Paar 4 und 6: gcd (4, 6) × distance ² (4, 6) = 4

Ein weiteres Beispielquadrat zum Testen - es hat eine Delacorte-Nummer von 5957:

10  8 11 14 12
21  4 19  7  9
 5 13 23  1 16
18  3 17  2 15
24 22 25  6 20

Die Delacorte-Nummern stammen aus diesem Programmierwettbewerb - siehe dort für weitere Details ... Der Wettbewerb endete im Januar 2015. Es hat großen Spaß gemacht!

Regeln:

Notwendige Zeilenumbrüche zählen als 1 Zeichen. Sie können Ihre Golf-Lösung mit Zeilenumbrüchen veröffentlichen, diese werden jedoch nur bei Bedarf in dieser Sprache gezählt.

Sie können wählen, wie Sie mit Ein- und Ausgaben umgehen möchten, und müssen nicht das erforderliche Framework für Ihre Sprache wie Standard-Includes oder Hauptfunktionsheader zählen. Es zählt nur der tatsächliche Code (einschließlich Verknüpfungen / Alias-Definitionen), wie in diesem C # -Beispiel:

namespace System
{
    using Collections.Generic;
    using I=Int32; //this complete line counts
    class Delacorte
    {
        static I l(I[]a){return a.Length;} //of course this complete line counts

        static void CalculateSquare(int[] a, out int r)
        {
            r=0;for(I i=l(a);i-->0;)r+=a[i]; //here only this line counts
        }

        static void Main()
        {
            int result;
            CalculateSquare(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, out result);
            Console.Write(result); //should output 140 for the example
            Console.ReadKey();
        }
    }
}

Sie können das Quadrat auch als zweidimensionales Array oder über eine Eingabeaufforderung oder als Zeichenfolge oder einen Standardauflistungstyp eingeben. Ein zweidimensionales Array ist die einzige Möglichkeit, die Seitenlänge des Quadrats nicht selbst berechnen zu müssen.
Eine Unterfunktion für die eigentliche Arbeit ist nicht erforderlich, Sie können den Code auch direkt in Main () einfügen.

Noch mehr Vorbereitungen sind kostenlos möglich, wie hier:

using System;
unsafe class Delacorte
{
    static void CalculateSquare(int* a, out int r)
    {
        r=0;while(*a>0)r+=*a++; //only this line counts
    }

    static void Main()
    {
        var input = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; //adding a terminator
        int result;
        fixed (int* a = &input[0]) //necessary in C#
            CalculateSquare(a, out result);
        Console.Write(result);
        Console.ReadKey();
    }
}

Wenn Sie nicht sicher sind, ob Ihre langwierige Vorbereitung im Sinne dieser Regeln ist oder als Betrug bezeichnet werden könnte, fragen Sie einfach :)

maf-soft
quelle
Klingt wie, im Falle von Python, sind alle Includes kostenlos? Dies kann zu seltsamen Optimierungen führen ...
Falko
@Falko, die Frage ist, was sind Standard-Includes? Bitte versuchen Sie, den Geist der Regeln zu verstehen und sie an Ihre Sprache anzupassen. Also nein: siehe mein usingBeispiel - wenn es verwendet wird, um eine Bibliothek einzuschließen, weil Sie sonst keine Funktion aufrufen könnten, ist es kostenlos. Wenn Sie damit einen kurzen Alias ​​für irgendetwas definieren, zählt die gesamte Anweisung.
maf-soft
@Optimizer: Die Bedeutung der Distanzfunktion ist im Link etwas versteckt : Es ist das Quadrat der euklidischen Distanz zwischen den beiden Feldern.
Falko
@Optimizer, anstatt es genau zu definieren, habe ich ein Beispiel gegeben, damit Sie sicher sein können, was gemeint ist. Ich dachte, das ist genug und fügte Spaß hinzu ...
maf-soft
Und ich muss sagen, obwohl es eine berechtigte Frage ist, scheint es so, als hättest du sie hier veröffentlicht, um endlich an diesem Wettbewerb teilnehmen zu können;)
Optimizer

Antworten:

6

APL (38)

{.5×+/∊∘.{(∨/Z[⍺⍵])×+/⊃×⍨⍺-⍵}⍨⊂¨⍳⍴Z←⍵}

Dies ist eine Funktion, die eine Matrix als richtiges Argument verwendet:

      sq5←↑(10 8 11 14 12)(21 4 19 7 9)(5 13 23 1 16)(18 3 17 2 15)(24 22 25 6 20)
      sq5
10  8 11 14 12
21  4 19  7  9
 5 13 23  1 16
18  3 17  2 15
24 22 25  6 20
      {.5×+/∊∘.{(∨/Z[⍺⍵])×+/⊃×⍨⍺-⍵}⍨⊂¨⍳⍴Z←⍵}sq5
5957

Erläuterung:

  • ⊂¨⍳⍴Z←⍵: Speichern Sie die Matrix in Z. Machen Sie eine Liste aller möglichen Koordinatenpaare in Z.
  • ∘.{...}⍨ : für jedes Koordinatenpaar, kombiniert mit jedem Koordinatenpaar:
    • +/⊃×⍨⍺-⍵: Berechnung distance^2 : subtrahiere das erste Koordinatenpaar vom zweiten, multipliziere beide mit sich selbst und summiere das Ergebnis
    • ∨/Z[⍺⍵]: Holen Sie sich die Nummer in Z für beide Koordinatenpaare ein und suchen Sie die GCD
    • ×: multiplizieren sie miteinander
  • +/∊: summiere die Elemente des Ergebnisses davon
  • .5×: mit 0,5 multiplizieren (da wir jedes Paar ungleich Null zweimal früher gezählt haben)
Marinus
quelle
Dies wären 72 Bytes, wenn wir UTF-8-Bytes verwenden.
Kennytm
2
@KennyTM: Der APL-Zeichensatz passt in ein Byte. Es gibt Codierungen, die dies verwenden. APL ist Jahrzehnte älter als Unicode. Es scheint auf dieser Site akzeptiert zu sein, APL-Zeichen als Bytes zu zählen, solange keine Unicode-Zeichen verwendet werden. (dh mit Unicode-Codepunkten zum Codieren von Zeichenfolgen oder so etwas.)
Marinus
@marinus, das hört sich vernünftig an. Was halten Sie von den Unicode-Zeichen in Mathematica?
maf-soft
@ maf-soft: na ja, wenn es eine Kodierung gibt, bei der alle verwendeten Zeichen in ein Byte passen (also sowohl die Sonderzeichen als auch die normalen Zeichen enthalten), kann es nicht mehr als 256 eindeutige Zeichen geben Zeichen), dann kann es als ein Byte pro Zeichen gezählt werden. Wenn nicht, kann es nicht. Wenn Mathematica jedoch weniger als 128 eindeutige Unicode-Zeichen verwendet, können diese einfach in die obere Hälfte des Bytes und ASCII in die untere Hälfte abgebildet werden. [1/2].
Marinus
@ maf-soft: Dies wäre jedoch eine neuartige Codierung (~ "Sprache"). Sie müssten also ein Übersetzerprogramm bereitstellen, und Sie könnten es nach der Regel nur für Fragen verwenden, die neuer sind als Ihr Übersetzerprogramm Das heißt, Sie können Fragen nur in Sprachen beantworten, die vor der Frage liegen (dies verhindert, dass jemand eine Sprache mit einem 1-Byte-Befehl definiert, um die Frage genau zu lösen). [2/2]
Marinus
5

Mathematica (83 82 79 69 67 66)

Vorbereitung

a={{10,8,11,14,12},{21,4,19,7,9},{5,13,23,1,16},{18,3,17,2,15},{24,22,25,6,20}}

Code

#/2&@@Tr[ArrayRules@a~Tuples~2/.{t_->u_,v_->w_}->u~GCD~w#.#&[t-v]]

Wenn wir mit Unicode-Zeichen zählen: 62 :

Tr[ArrayRules@a~Tuples~2/.{t_u_,v_w_}u~GCD~w#.#&[t-v]]〚1〛/2
kennytm
quelle
Sie können die UTF-Version von '-> `: 
swish
@swish ->benötigt 2 Zeichen und 1 Zeichen, jedoch ->2 Byte und 3 Byte in UTF-8. Je nach Metrik kann es also länger dauern.
kennytm
Schauen Sie sich die APL-Lösung an, ich denke, die Metrik ist in Zeichen für diese;)
swish
@swish Das ist etwas, was OP klarstellen sollte, da UTF-8-Bytes die Standardeinstellung sind, wenn nicht anders angegeben :)
kennytm
@KennyTM - Ich bin mir nicht sicher, was das Beste ist. Ich möchte gerne nachverfolgen, was auf dieser Site so üblich ist. Momentan habe ich keine Zeit, es herauszufinden. Könnte jemand mit ein paar Links helfen? Sie können auch den in den OP-Kommentaren erwähnten Chat verwenden.
maf-soft
5

Python - 128 112 90 89 88

Vorbereitung:

import pylab as pl
from fractions import gcd
from numpy.linalg import norm
from itertools import product

A = pl.array([
    [10,  8, 11, 14, 12],
    [21,  4, 19,  7,  9],
    [ 5, 13, 23,  1, 16],
    [18,  3, 17,  2, 15],
    [24, 22, 25,  6, 20]])

Berechnung der Delacorte-Zahl (die Zeile, die zählt):

D=sum(gcd(A[i,j],A[m,n])*norm([m-i,n-j])**2for j,n,i,m in product(*[range(len(A))]*4))/2

Ausgabe:

print D

Ergebnis:

5957
Falko
quelle
2
Sie können beide forSchleifen zu einem einzigen Generator und zu einem einzigen zusammenfassen sum. Sie können auch P(R,R)in einer Variablen speichern *x,=product(R,R), indem Sie die markierte Zuweisung verwenden, um eine Kopie zu erstellen. Noch besser, Sie können es zum vierfachen Produkt machenproduct(R,R,R,R) und es einfach tun for j,n,i,m in product(*[R]*4).
Xnor
@xnor: Großartig! *[R]*4ist das, wonach ich selbst gesucht habe, aber nicht zur Arbeit kommen konnte.
Falko
1
Da Ihre Vorbereitung nicht für die Byteanzahl zählt, können Sie nicht so etwas wie from fractions import gcd as gdas Speichern von Bytes in dem wichtigen Abschnitt tun ?
FlipTack
3

Pyth 43

Diese Antwort könnte mit ziemlicher Sicherheit weiter verfolgt werden. Besonders die Entfernungsberechnung gefällt mir nicht.

K^lJ.5VJFdUN~Z*i@JN@Jd+^-/dK/NK2^-%dK%NK2;Z

Um dies einzurichten, speichern Sie das linearisierte Array in der Variablen J. Sie können dies tun, indem Sie Folgendes schreiben:

J[3 2 9 4 1 8 5 6 7)

Probieren Sie es online aus .

Gibt einen Float aus. Ich halte das für legitim, bitte sag mir, wenn ich gegen eine Regel verstoßen habe :)

Erläuterung:

                                             : Z=0 (implicit)
K^lJ.5                                       : K=sqrt(len(J))
      VJ                                     : for N in range(len(J))
        FdUN                                 : for d in range(N)
            ~Z*                              : Z+= the product of
               i@JN@Jd                       : GCD(J[N],J[d])
                      +^-/dK/NK2^-%dK%NK2    : (d/K-N/K)^2 + (d%K-N%K)^2 (distance)
                                         ;Z  : end all loops, and print Z
FryAmTheEggman
quelle
Wow, ich habe endlich Pyth mit APL besiegt.
Marinus
@ Marinus Haha, ich versuche es immer noch, aber ich glaube, du hast mich geschlagen, zumindest :)
FryAmTheEggman
Wow, das ist verrückt. Ich lese jetzt die doc.txt, aber ich finde es wirklich schwer zu lesen!
Rubik
@rubik Zumindest ist es nicht APL: D Das Dokument ist nicht 100% genau, weil diese ganze Sprache von einem Mann gepflegt wird : isaacg . Wenn Sie Fragen haben, können Sie mich / ihn
gerne
2

CJam, 55

q~:Q__,mqi:L;m*{_~{_@\%}h;\[Qf#_Lf/\Lf%]{~-_*}/+*}%:+2/

Nimmt die Matrix als STDIN im folgenden Format:

[10  8 11 14 12
 21  4 19  7  9
  5 13 23  1 16
 18  3 17  2 15
 24 22 25  6 20]

Probieren Sie es hier online aus

Optimierer
quelle
Ich denke, Sie könnten die Matrix kostenlos {}hartcodieren und verwenden , um einen Block zu erstellen , anstatt stdin zu verwenden. Speichern Sie die Matrix auch in einem eindimensionalen Array? Ich denke, Sie können die bereits formatierte Matrix nehmen, siehe die Beispiele des OP. (Ich kenne CJam nicht gut, also nimm das mit einem Körnchen Salz;))
FryAmTheEggman
Das Lesen der Matrix und das Konvertieren in eine einzelne Liste ist der q~]Teil. Das ist kürzer als wenn ich es hart codiere und einen Block benutze (ich denke)
Optimizer