Calcola il numero di Delacorte di un quadrato


12

Sfida: implementare il calcolo di un numero Delacorte in qualsiasi lingua. Il codice più corto vince.

Per una data matrice quadrata di interi distinti 1..n² (possibile lunghezza laterale n almeno tra 3 e 27), il suo numero Delacorte è la somma dei prodotti gcd (a, b) × distanza² (a, b) per ogni distinto coppia di numeri interi {a, b}.

L'esempio seguente mostra un quadrato 3 × 3 con un numero Delacorte di 160.

3 2 9
4 1 8
5 6 7

In questo quadrato abbiamo 36 coppie distinte da calcolare, ad esempio le coppie 4 e 6: gcd (4, 6) × distanza ² (4, 6) = 4

Un altro quadrato di esempio per i test: questo ha un numero Delacorte di 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

I numeri di Delacorte sono tratti da questo concorso di programmazione - vedi qui per ulteriori dettagli ... Il concorso si è concluso a gennaio 2015. È stato molto divertente!

Regole:

Le interruzioni di riga necessarie valgono come 1 carattere. È possibile pubblicare la soluzione golfata con interruzioni di riga, ma vengono conteggiate solo se necessario in quella lingua.

Puoi scegliere come gestire l'input e l'output e non devi contare il framework necessario della tua lingua, come le inclusioni standard o le intestazioni delle funzioni principali. Conta solo il codice effettivo (comprese le definizioni collegamento / alias), come in questo esempio 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();
        }
    }
}

È inoltre possibile inserire il quadrato come matrice bidimensionale o da un prompt o come stringa o un tipo di raccolta standard. Un array bidimensionale è l'unico modo per non dover calcolare da soli la lunghezza laterale del quadrato.
Non è richiesta una sotto-funzione per il lavoro effettivo, è inoltre possibile inserire il codice direttamente in Main ().

Ancora più preparazione è consentita gratuitamente, come qui:

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

Se non sei sicuro che la tua lunga preparazione sia nello spirito di queste regole o possa essere chiamato imbroglio, chiedi semplicemente :)


Sembra che, nel caso di Python, tutte le inclusioni siano gratuite? Ciò può causare alcune strane ottimizzazioni ...
Falko,

@Falko, la domanda è: cosa sono gli standard inclusi? Cerca di comprendere lo spirito delle regole e adattale alla tua lingua. Quindi no: vedi il mio usingesempio - se viene usato per includere una libreria perché altrimenti non potresti chiamare alcuna funzione, è gratuito. Se lo usi per definire un breve alias per qualsiasi cosa, l'intera istruzione conta.
Maf-soft

@Optimizer: il significato della funzione di distanza è in qualche modo nascosto nel collegamento : è il quadrato della distanza euclidea tra i due campi.
Falko,

@Optimizer, invece di definirlo esattamente, ho fatto un esempio, quindi puoi essere sicuro di cosa si intende. Ho pensato che fosse abbastanza e aggiunto divertimento ...
maf-soft

E devo dire che, sebbene sia una domanda legittima, sembra che tu l'abbia pubblicato qui per poter finalmente partecipare a quel concorso;)
Ottimizzatore,

Risposte:


6

APL (38)

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

Questa è una funzione che prende una matrice come argomento giusto, in questo modo:

      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

Spiegazione:

  • ⊂¨⍳⍴Z←⍵: archivia la matrice in Z. Crea un elenco di ogni possibile coppia di coordinate in Z.
  • ∘.{... }⍨: per ciascuna coppia di coordinate, combinata con ciascuna coppia di coordinate:
    • +/⊃×⍨⍺-⍵: calcola distance^2: sottrai la prima coppia di coordinate dalla seconda, moltiplica entrambe per se stesse e somma il risultato
    • ∨/Z[⍺⍵]: ottieni il numero Zper entrambe le coppie di coordinate e trova il GCD
    • ×: moltiplicali l'uno per l'altro
  • +/∊: somma gli elementi del risultato di quello
  • .5×: moltiplicare per 0,5 (perché abbiamo contato ogni coppia diversa da zero due volte prima)

Questo sarebbe 72 byte se contiamo utilizzando UTF-8 byte.
kennytm,

2
@KennyTM: il set di caratteri APL si inserisce in un byte. Esistono codifiche che usano questo. APL precede Unicode da decenni. Sembra essere accettato su questo sito per contare i caratteri APL come byte, purché non vengano utilizzati caratteri Unicode. (ad es. usando punti di codice Unicode per codificare stringhe o qualcosa del genere).
marinus

@marinus, sembra ragionevole. Cosa ne pensi dei caratteri Unicode in Mathematica?
Maf-soft

@ maf-soft: beh, se esiste una codifica esistente in base alla quale tutti i caratteri utilizzati si adattano all'interno di un byte (quindi include sia i caratteri "speciali" che "normali", quindi non possono esserci più di 256 unici caratteri), quindi può essere conteggiato come un byte per carattere. Altrimenti, non può. Tuttavia, se Mathematica utilizza meno di 128 caratteri Unicode univoci, possono essere banalmente mappati nella metà superiore del byte, con ASCII nella metà inferiore. [1/2].
marinus,

@ maf-soft: questa sarebbe una nuova codifica (~ "lingua"), quindi, dovresti fornire un programma traduttore e potresti usarlo solo su domande più recenti del tuo programma traduttore, secondo la regola che afferma che puoi rispondere alle domande solo nelle lingue precedenti alla domanda (questo per impedire a qualcuno di definire una lingua con un comando a 1 byte per risolvere esattamente la domanda). [2/2]
marinus,

5

Matematica (83 82 79 69 67 66)

Preparazione

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

Codice

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

Se contiamo usando i caratteri Unicode: 62 :

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

È possibile utilizzare la versione UTF di '-> `: 
swish

@swish ->accetta 2 caratteri e accetta 1 carattere, tuttavia ->richiede 2 byte e richiede 3 byte in UTF-8. Quindi potrebbe essere più lungo a seconda delle metriche.
kennytm,

Bene, guarda la soluzione APL, quindi immagino che la metrica sia in caratteri su questo;)
swish

@swish Questo è qualcosa che OP dovrebbe chiarire poiché UTF-8 byte è l'impostazione predefinita se non dichiarata :)
kennytm

@KennyTM - Non sono sicuro di cosa sia meglio. Mi piacerebbe seguire ciò che è comune su questo sito. Al momento non ho tempo per scoprirlo. Qualcuno potrebbe aiutare con alcuni link? È inoltre possibile utilizzare la chat menzionata nei commenti OP.
Maf-soft

5

Python - 128 112 90 89 88

Preparazione:

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

Calcolo del numero Delacorte (la linea che conta):

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

Produzione:

print D

Risultato:

5957

2
Puoi comprimere entrambi i forloop in un singolo generatore e sumfarlo una volta. Inoltre, puoi salvare P(R,R)in una variabile *x,=product(R,R)utilizzando, con l'assegnazione stellata per fare una copia. Ancora meglio, puoi renderlo il prodotto quadruplo product(R,R,R,R)e farlo for j,n,i,m in product(*[R]*4).
xnor

@xnor: Fantastico! *[R]*4è quello che cercavo da solo ma non riuscivo a lavorare.
Falko,

1
visto che la tua preparazione non conta per il conteggio dei byte, non puoi fare qualcosa di simile from fractions import gcd as gper salvare byte nella sezione importante?
FlipTack

3

Pyth 43

Questa risposta potrebbe quasi certamente essere ulteriormente approfondita; In particolare non mi piace il calcolo della distanza.

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

Per configurarlo, archivia l'array lineare nella variabile J. Puoi farlo scrivendo:

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

Provalo online .

Emette un float. Penso che sia legittimo, per favore dimmi se ho infranto una regola :)

Spiegazione:

                                             : 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

Wow, ho finalmente battuto Pyth con APL.
marinus,

@marinus Haha, ci sto ancora provando, ma penso che mi hai battuto, almeno :)
FryAmTheEggman

Wow, questo è pazzo. Sto leggendo il doc.txt ora ma trovo davvero difficile da leggere!
rubik,

@rubik Almeno non è APL: D Il documento non è accurato al 100% perché l'intero linguaggio è gestito da un ragazzo: isaacg . Se hai domande, sentiti libero di chiedermelo in chat :)
FryAmTheEggman

2

CJam, 55

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

Prende la matrice come STDIN nel seguente formato:

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

Provalo online qui


Penso che potresti codificare la matrice gratuitamente e utilizzarlo {}per creare un blocco piuttosto che usare lo stdin. Inoltre, stai scaricando la matrice in una matrice unidimensionale? Penso che puoi prendere la matrice già formattata, vedi gli esempi dell'OP. (Non conosco bene CJam, quindi prendilo con un
po

Leggere la matrice e convertirla in un unico elenco è la q~]parte. che è più breve rispetto a quando lo codifico e uso un blocco (immagino)
Optimizer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.