Calculer le nombre Delacorte d'un carré

12

Défi: implémenter le calcul d'un numéro Delacorte dans n'importe quelle langue. Le code le plus court gagne.

Pour une matrice carrée donnée d'entiers distincts 1..n² (longueur de côté possible n au moins entre 3 et 27), son nombre Delacorte est la somme des produits pgc (a, b) × distance² (a, b) pour chaque distinct paire d'entiers {a, b}.

L'exemple suivant montre un carré 3 × 3 avec un nombre Delacorte de 160.

3 2 9
4 1 8
5 6 7

Dans ce carré, nous avons 36 paires distinctes à calculer, par exemple la paire 4 et 6: pgcd (4, 6) × distance ² (4, 6) = 4

Un autre exemple de carré pour les tests - celui-ci a un numéro Delacorte de 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

Les numéros Delacorte sont tirés de ce concours de programmation - voir ici pour plus de détails ... Le concours s'est terminé en janvier 2015. C'était très amusant!

Règles:

Les sauts de ligne nécessaires comptent pour 1 caractère. Vous pouvez publier votre solution golfée avec des sauts de ligne, mais ils ne sont comptés que si nécessaire dans cette langue.

Vous pouvez choisir comment gérer les entrées et les sorties et vous n'avez pas à compter le cadre nécessaire de votre langage, comme les en-têtes standard ou les fonctions principales. Seul le code réel compte (y compris les définitions de raccourci / alias), comme dans cet exemple C #:

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();
        }
    }
}

Vous pouvez également saisir le carré sous forme de tableau à deux dimensions ou à partir d'une invite ou sous forme de chaîne ou d'un type de collection standard. Un tableau à deux dimensions est le seul moyen de ne pas avoir à calculer vous-même la longueur du côté du carré.
Une sous-fonction pour le travail réel n'est pas requise, vous pouvez également placer le code directement dans Main ().

Encore plus de préparation est autorisée gratuitement, comme ici:

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();
    }
}

Si vous ne savez pas si votre longue préparation est dans l'esprit de ces règles ou pourrait être qualifiée de tricherie, demandez simplement :)

maf-soft
la source
On dirait que, dans le cas de Python, toutes les inclusions sont gratuites? Cela peut provoquer des optimisations étranges ...
Falko
@Falko, la question est: que sont les inclusions standard? Veuillez essayer de comprendre l'esprit des règles et de les adapter à votre langue. Donc, non: voir mon usingexemple - s'il est utilisé pour inclure une bibliothèque car sinon vous ne pourriez pas appeler une fonction, c'est gratuit. Si vous l'utilisez pour définir un alias court pour quoi que ce soit, l'instruction entière compte.
maf-soft
@Optimizer: La signification de la fonction de distance est quelque peu cachée dans le lien : c'est le carré de la distance euclidienne entre les deux champs.
Falko
@Optimizer, au lieu de le définir exactement, j'ai donné un exemple, vous pouvez donc être sûr de ce que cela signifie. Je pensais que cela suffisait et ajoutait du plaisir ...
maf-soft
Et je dois dire que bien que ce soit une question légitime, il semble que vous l'ayez posté ici pour enfin pouvoir participer à ce concours;)
Optimizer

Réponses:

6

APL (38)

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

C'est une fonction qui prend une matrice comme argument de droite, comme ceci:

      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

Explication:

  • ⊂¨⍳⍴Z←⍵: stocker la matrice dans Z. Faites une liste de chaque paire de coordonnées possible Z.
  • ∘.{... }⍨: pour chaque paire de coordonnées, combinée à chaque paire de coordonnées:
    • +/⊃×⍨⍺-⍵: calculer distance^2: soustraire la première paire de coordonnées de la seconde, multiplier les deux par elles-mêmes et additionner le résultat
    • ∨/Z[⍺⍵]: obtenir le nombre Zpour les deux paires de coordonnées et trouver le GCD
    • ×: multipliez-les les uns par les autres
  • +/∊: additionner les éléments du résultat de cette
  • .5×: multipliez par 0,5 (car nous avons compté chaque paire non nulle deux fois plus tôt)
marinus
la source
Ce serait 72 octets si nous comptons en utilisant des octets UTF-8.
kennytm
2
@KennyTM: le jeu de caractères APL tient dans un octet. Il existe des codages qui utilisent cela. APL est antérieure à Unicode de plusieurs décennies. Il semble être accepté sur ce site de compter les caractères APL comme octets, tant qu'aucun caractère Unicode n'est utilisé. (c'est-à-dire en utilisant des points de code Unicode pour coder des chaînes, ou quelque chose du genre.)
marinus
@marinus, cela semble raisonnable. Que pensez-vous des caractères unicode dans Mathematica?
maf-soft
@ maf-soft: eh bien, s'il existe un encodage existant par lequel tous les caractères utilisés s'inscrivent dans un octet (ce qui inclut à la fois les caractères "spéciaux" et "normaux", il ne peut donc pas y avoir plus de 256 uniques caractères), il peut alors être compté comme un octet par caractère. Sinon, ce n'est pas possible. Cependant, si Mathematica utilise moins de 128 caractères Unicode uniques, ils peuvent être mappés trivialement dans la moitié supérieure de l'octet, avec ASCII dans la moitié inférieure. [1/2].
marinus
@ maf-soft: ce serait un nouvel encodage (~ "langue"), donc vous auriez besoin de fournir un programme de traduction, et vous ne pourriez l'utiliser que sur des questions plus récentes que votre programme de traduction, selon la règle qui indique que vous ne pouvez répondre aux questions que dans des langues antérieures à la question (ceci pour empêcher quelqu'un de définir une langue avec une commande à 1 octet pour résoudre exactement la question). [2/2]
marinus
5

Mathematica (83 82 79 69 67 66)

Préparation

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]]

Si on compte en utilisant des caractères Unicode: 62 :

Tr[ArrayRules@a~Tuples~2/.{t_u_,v_w_}u~GCD~w#.#&[t-v]]〚1〛/2
kennytm
la source
Vous pouvez utiliser la version UTF de '-> `: 
swish
@swish ->prend 2 caractères et prend 1 caractère, cependant, ->prend 2 octets et prend 3 octets en UTF-8. Cela peut donc être plus long selon les métriques.
kennytm
Eh bien, regardez la solution APL, donc je suppose que la métrique est en caractères sur celle-ci;)
swish
@swish C'est quelque chose que OP devrait clarifier car les octets UTF-8 sont la valeur par défaut s'il n'est pas indiqué :)
kennytm
@KennyTM - Je ne sais pas ce qui est le mieux. Je voudrais suivre ce qui est courant sur ce site. Actuellement, je n'ai pas le temps de le découvrir. Quelqu'un pourrait-il m'aider avec des liens? Vous pouvez également utiliser le chat mentionné dans les commentaires OP.
maf-soft
5

Python - 128 112 90 90 89 88

Préparation:

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

Calcul du nombre Delacorte (la ligne qui compte):

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

Production:

print D

Résultat:

5957
Falko
la source
2
Vous pouvez réduire les deux forboucles en un seul générateur et une seule sumfois. En outre, vous pouvez enregistrer P(R,R)dans une variable en *x,=product(R,R)utilisant l'affectation suivie pour effectuer une copie. Encore mieux, vous pouvez en faire le produit quadruple product(R,R,R,R)et le faire for j,n,i,m in product(*[R]*4).
xnor
@xnor: Super! *[R]*4est ce que je cherchais moi-même mais je n'ai pas pu me mettre au travail.
Falko
1
étant donné que votre préparation ne compte pas dans le nombre d'octets, ne pouvez-vous pas faire quelque chose comme from fractions import gcd as genregistrer des octets dans la section importante?
FlipTack
3

Pyth 43

Cette réponse pourrait presque certainement être étudiée plus loin; Je n'aime pas particulièrement le calcul de la distance.

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

Pour configurer cela, stockez le tableau linéarisé dans la variable J. Vous pouvez le faire en écrivant:

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

Essayez-le en ligne .

Sort un flottant. Je pense que c'est légitime, dites-moi si j'ai enfreint une règle :)

Explication:

                                             : 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
la source
Wow, j'ai finalement battu Pyth avec APL.
marinus
@marinus Haha, j'essaie toujours, mais je pense que vous m'avez fait battre, au moins :)
FryAmTheEggman
Wow, c'est fou. Je lis le doc.txt maintenant mais je trouve ça très difficile à lire!
rubik
@rubik Au moins, ce n'est pas APL: D Le doc n'est pas précis à 100% parce que toute cette langue est maintenue par un gars: isaacg . Si vous avez des questions, n'hésitez pas à me les poser dans le chat :)
FryAmTheEggman
2

CJam, 55

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

Prend la matrice comme STDIN dans le format suivant:

[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]

Essayez-le en ligne ici

Optimiseur
la source
Je pense que vous pouvez coder en dur la matrice gratuitement et l'utiliser {}pour créer un bloc plutôt que d'utiliser stdin. De plus, jetez-vous la matrice dans un tableau unidimensionnel? Je pense que vous pouvez prendre la matrice déjà formatée, voir les exemples de l'OP. (Je ne connais pas bien CJam, alors prenez ceci avec un grain de sel;))
FryAmTheEggman
La lecture de la matrice et sa conversion en liste unique est la q~]partie. qui est plus court que lorsque je le code en dur et utilise un bloc (je suppose)
Optimizer