Hitung Delacorte Number dari sebuah persegi

12

Tantangan: mengimplementasikan perhitungan Nomor Delacorte dalam bahasa apa pun. Kode terpendek menang.

Untuk matriks persegi yang diberikan bilangan bulat berbeda 1..n² (panjang sisi yang mungkin n setidaknya antara 3 dan 27), Nomor Delacorte-nya adalah jumlah dari produk gcd (a, b) × jarak² (a, b) untuk setiap perbedaan sepasang bilangan bulat {a, b}.

Contoh berikut menunjukkan kotak 3 × 3 dengan Delacorte Number 160.

3 2 9
4 1 8
5 6 7

Dalam kotak ini kita memiliki 36 pasangan berbeda untuk dihitung, misalnya pasangan 4 dan 6: gcd (4, 6) × jarak ² (4, 6) = 4

Contoh kuadrat lain untuk pengujian - ini memiliki Nomor Delacorte 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

Delacorte Numbers diambil dari kontes pemrograman ini - lihat di sana untuk detail lebih lanjut ... Kontes berakhir pada Januari 2015. Itu sangat menyenangkan!

Aturan:

Jeda baris yang diperlukan dihitung sebagai 1 karakter. Anda dapat memposting solusi golf Anda dengan jeda baris, tetapi mereka hanya dihitung jika perlu dalam bahasa itu.

Anda dapat memilih bagaimana menangani input dan output dan Anda tidak perlu menghitung kerangka kerja yang diperlukan dari bahasa Anda, seperti standar-termasuk atau header fungsi utama. Hanya kode aktual yang dihitung (termasuk pintasan / alias definisi), seperti dalam contoh C # ini:

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

Anda juga dapat memasukkan kotak sebagai array 2 dimensi atau dari prompt atau sebagai string atau beberapa tipe koleksi standar. Array 2 dimensi adalah satu-satunya cara untuk tidak menghitung panjang sisi kotak sendiri.
Sub-fungsi untuk pekerjaan yang sebenarnya tidak diperlukan, Anda juga bisa meletakkan kode langsung di dalam Main ().

Bahkan lebih banyak persiapan diperbolehkan secara gratis, seperti di sini:

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

Jika Anda tidak yakin apakah persiapan panjang Anda sesuai dengan aturan ini atau bisa disebut curang, tanyakan saja :)

maf-lembut
sumber
Kedengarannya seperti, dalam kasus Python, semua termasuk gratis? Ini dapat menyebabkan beberapa optimasi aneh ...
Falko
@ Talko, pertanyaannya adalah, apa yang termasuk standar? Cobalah memahami semangat peraturan dan menyesuaikannya dengan bahasa Anda. Jadi, tidak: lihat usingcontoh saya - jika digunakan untuk memasukkan perpustakaan karena jika tidak Anda tidak dapat memanggil beberapa fungsi, itu gratis. Jika Anda menggunakannya untuk mendefinisikan beberapa alias pendek untuk apa pun, seluruh instruksi diperhitungkan.
maf-soft
@Optimizer: Arti fungsi jarak agak tersembunyi di tautan : Ini kuadrat dari jarak euclidean antara kedua bidang.
Falko
@Optimizer, alih-alih mendefinisikannya dengan tepat, saya memberikan contoh, jadi Anda bisa yakin apa yang dimaksud. Saya pikir itu sudah cukup dan menambahkan kesenangan ...
maf-soft
Dan saya harus mengatakan bahwa meskipun ini adalah pertanyaan yang sah, sepertinya Anda telah mempostingnya di sini untuk akhirnya dapat mengikuti kontes itu;)
Pengoptimal

Jawaban:

6

APL (38)

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

Ini adalah fungsi yang mengambil matriks sebagai argumen yang tepat, seperti:

      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

Penjelasan:

  • ⊂¨⍳⍴Z←⍵: simpan matriks di Z. Buat daftar masing-masing pasangan koordinat yang memungkinkan di Z.
  • ∘.{... }⍨: untuk setiap pasangan koordinat, dikombinasikan dengan setiap pasangan koordinat:
    • +/⊃×⍨⍺-⍵: menghitung distance^2: kurangi pasangan koordinat pertama dari yang kedua, kalikan keduanya sendiri dan jumlah hasilnya
    • ∨/Z[⍺⍵]: dapatkan nomor Zuntuk kedua pasang koordinat, dan temukan GCD
    • ×: kalikan satu sama lain
  • +/∊: jumlah elemen dari hasil itu
  • .5×: kalikan dengan 0,5 (karena kami menghitung setiap pasangan bukan nol dua kali sebelumnya)
marinus
sumber
Ini akan menjadi 72 byte jika kita menghitung menggunakan UTF-8 byte.
kennytm
2
@ KennyTM: charset APL cocok dalam satu byte. Ada pengkodean yang menggunakan ini. APL mendahului Unicode oleh dekade. Tampaknya diterima di situs ini untuk menghitung karakter APL sebagai byte, selama tidak ada karakter Unicode yang digunakan. (yaitu menggunakan Unicode codepoints untuk mengkodekan string, atau sesuatu.)
marinus
@marinus, itu terdengar masuk akal. Apa pendapat Anda tentang karakter unicode di Mathematica?
maf-soft
@ maf-soft: well, jika ada pengkodean yang ada di mana semua karakter yang digunakan cocok dalam satu byte (sehingga mencakup karakter 'khusus' dan 'normal', jadi tidak mungkin ada lebih dari 256 karakter unik) karakter), maka dapat dihitung sebagai satu byte per karakter. Jika tidak, maka itu tidak bisa. Namun, jika Mathematica menggunakan kurang dari 128 karakter Unicode yang unik, mereka dapat dengan mudah dipetakan ke bagian atas byte, dengan ASCII di bagian bawah. [1/2].
marinus
@ maf-soft: ini adalah pengodean novel (~ "bahasa"), jadi Anda harus menyediakan program penerjemah, dan Anda hanya bisa menggunakannya pada pertanyaan yang lebih baru daripada program penerjemah Anda, sesuai aturan yang menyatakan Anda hanya dapat menjawab pertanyaan dalam bahasa yang mendahului pertanyaan (ini untuk mencegah seseorang mendefinisikan bahasa dengan perintah 1-byte untuk menyelesaikan pertanyaan dengan tepat). [2/2]
marinus
5

Mathematica (83 82 79 69 67 66)

Persiapan

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

Kode

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

Jika kami menghitung menggunakan karakter Unicode: 62 :

Tr[ArrayRules@a~Tuples~2/.{t_u_,v_w_}u~GCD~w#.#&[t-v]]〚1〛/2
kennytm
sumber
Anda dapat menggunakan versi UTF dari '-> `: 
desir
@swish ->mengambil 2 karakter dan mengambil 1 karakter, namun, ->mengambil 2 byte dan mengambil 3 byte di UTF-8. Jadi mungkin lebih lama tergantung pada metrik.
kennytm
Nah lihat solusi APL, jadi saya kira metrik dalam karakter yang satu ini;)
desir
@ harap Itu sesuatu yang harus diklarifikasi oleh OP karena byte UTF-8 adalah default jika tidak dinyatakan :)
kennytm
@ KennyTM - Saya tidak yakin yang terbaik. Saya ingin mengikuti apa yang umum di situs ini. Saat ini saya tidak punya waktu untuk mencari tahu. Bisakah seseorang membantu dengan beberapa tautan? Anda juga dapat menggunakan obrolan yang disebutkan dalam komentar OP.
maf-soft
5

Python - 128 112 90 89 88

Persiapan:

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

Menghitung Nomor Delacorte (baris yang diperhitungkan):

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

Keluaran:

print D

Hasil:

5957
Falko
sumber
2
Anda dapat menutup kedua forloop menjadi satu generator dan sumsekaligus. Selain itu, Anda dapat menyimpan P(R,R)ke variabel dengan *x,=product(R,R)menggunakan penugasan berbintang untuk membuat salinan. Bahkan lebih baik, Anda bisa menjadikannya produk empat kali lipat product(R,R,R,R)dan lakukan saja for j,n,i,m in product(*[R]*4).
xnor
@ xnor: Luar biasa! *[R]*4adalah apa yang saya cari sendiri tetapi tidak bisa mulai bekerja.
Falko
1
mengingat persiapan Anda tidak diperhitungkan dalam hitungan byte, tidak bisakah Anda melakukan sesuatu seperti from fractions import gcd as gmenyimpan byte di bagian penting?
FlipTack
3

Pyth 43

Jawaban ini hampir dapat dipastikan golf lebih lanjut; Saya khususnya tidak suka perhitungan jarak.

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

Untuk mengatur ini, simpan array linear-ized dalam variabel J. Anda dapat melakukan ini dengan menulis:

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

Cobalah online .

Output mengapung. Saya pikir ini sah, tolong beri tahu saya jika saya melanggar aturan :)

Penjelasan:

                                             : 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
sumber
Wow, saya akhirnya mengalahkan Pyth dengan APL.
marinus
@marinus Haha, saya masih mencoba, tapi saya pikir Anda mengalahkan saya, setidaknya :)
FryAmTheEggman
Wow, ini gila. Saya membaca doc.txt sekarang tetapi saya merasa sangat sulit untuk membaca!
rubik
@rubik Setidaknya bukan APL: D Doc tidak 100% akurat karena seluruh bahasa ini dijaga oleh satu orang: isaacg . Jika Anda memiliki pertanyaan, jangan ragu untuk bertanya kepada saya dalam obrolan :)
FryAmTheEggman
2

CJam, 55

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

Mengambil matriks sebagai STDIN dalam format berikut:

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

Cobalah online di sini

Pengoptimal
sumber
Saya pikir Anda bisa membuat hard-code matriks secara gratis dan gunakan {}untuk membuat blok daripada menggunakan stdin. Juga, apakah Anda membuang matriks ke array satu dimensi? Saya pikir Anda dapat mengambil matriks yang sudah diformat, lihat contoh OP. (Saya tidak mengenal CJam dengan baik, jadi ambillah ini dengan sebutir garam;))
FryAmTheEggman
Membaca matriks dan mengubahnya menjadi daftar tunggal adalah q~]bagiannya. yang lebih pendek dibandingkan dengan ketika saya membuat kode dan menggunakan blok (saya kira)
Pengoptimal