Oblicz liczbę Delacorte kwadratu

12

Wyzwanie: wdrożyć obliczenia liczby Delacorte w dowolnym języku. Najkrótszy kod wygrywa.

Dla danej macierzy kwadratowej różnych liczb całkowitych 1..n² (możliwa długość boku n co najmniej od 3 do 27), jej liczba Delacorte jest sumą produktów gcd (a, b) × odległość² (a, b) dla każdej odrębnej para liczb całkowitych {a, b}.

Poniższy przykład pokazuje kwadrat 3 × 3 z liczbą Delacorte 160.

3 2 9
4 1 8
5 6 7

W tym kwadracie mamy 36 różnych par do obliczenia, na przykład pary 4 i 6: gcd (4, 6) × odległość ² (4, 6) = 4

Kolejny przykładowy kwadrat do testowania - ma on liczbę 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

Numery Delacorte zostały zaczerpnięte z tego konkursu programistycznego - zobacz tam więcej szczegółów ... Konkurs zakończył się w styczniu 2015 roku. To była świetna zabawa!

Zasady:

Niezbędne podziały linii liczą się jako 1 znak. Możesz opublikować swoje rozwiązanie w golfa z podziałem linii, ale są one liczone tylko w razie potrzeby w tym języku.

Możesz wybrać sposób obsługi danych wejściowych i wyjściowych i nie musisz liczyć niezbędnej struktury swojego języka, na przykład nagłówków standardowych lub głównych funkcji. Liczy się tylko rzeczywisty kod (w tym definicje skrótów / aliasów), jak w tym przykładzie 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();
        }
    }
}

Możesz również wprowadzić kwadrat jako tablicę dwuwymiarową lub z wiersza polecenia lub jako ciąg znaków lub inny standardowy typ kolekcji. Dwuwymiarowa tablica to jedyny sposób, aby samodzielnie nie obliczać długości boku kwadratu.
Podfunkcja do faktycznej pracy nie jest wymagana, możesz także umieścić kod bezpośrednio w Main ().

Jeszcze więcej przygotowań jest dozwolone za darmo, jak tutaj:

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

Jeśli nie masz pewności, czy twoje długie przygotowania są zgodne z duchem tych zasad, czy można je nazwać oszustwem, po prostu zapytaj :)

maf-soft
źródło
Wygląda na to, że w przypadku Pythona wszystkie zawarte są za darmo? Może to powodować dziwne optymalizacje ...
Falko,
@ Falko, pytanie brzmi: co obejmuje standard? Spróbuj zrozumieć ducha zasad i dostosować je do swojego języka. Więc nie: patrz mój usingprzykład - jeśli jest używany do dołączenia biblioteki, ponieważ w przeciwnym razie nie można wywołać jakiejś funkcji, jest darmowy. Jeśli użyjesz go do zdefiniowania jakiegoś krótkiego aliasu, liczy się cała instrukcja.
maf-soft
@Optimizer: Znaczenie funkcji odległości jest nieco ukryte w łączu : Jest to kwadrat odległości euklidesowej między dwoma polami.
Falko,
@Optimizer, zamiast dokładnie go zdefiniować, podałem przykład, więc możesz być pewien, co to znaczy. Myślałem, że to wystarczy i dodałem zabawy ...
maf-soft
I muszę powiedzieć, że chociaż jest to uzasadnione pytanie, wygląda na to, że opublikowałeś go tutaj, aby w końcu móc wziąć udział w tym konkursie;)
Optymalizator

Odpowiedzi:

6

APL (38)

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

Jest to funkcja, która przyjmuje prawidłowy argument macierzy, na przykład:

      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

Wyjaśnienie:

  • ⊂¨⍳⍴Z←⍵: zapisz macierz w Z. Zrób listę każdej możliwej pary współrzędnych w Z.
  • ∘.{... }⍨: dla każdej pary współrzędnych w połączeniu z każdą parą współrzędnych:
    • +/⊃×⍨⍺-⍵: oblicz distance^2: odejmij pierwszą parę współrzędnych od drugiej, pomnóż je przez siebie i zsumuj wynik
    • ∨/Z[⍺⍵]: pobierz numer Zdla obu par współrzędnych i znajdź GCD
    • ×: pomnóż je przez siebie
  • +/∊: zsumuj elementy tego wyniku
  • .5×: pomnóż przez 0,5 (ponieważ każdą niezerową parę policzyliśmy dwa razy wcześniej)
marinus
źródło
Będzie to 72 bajty, jeśli policzymy używając bajtów UTF-8.
kennytm
2
@KennyTM: zestaw znaków APL mieści się w bajcie. Istnieją kodowania, które wykorzystują to. APL wyprzedza Unicode o dekady. Wydaje się, że na tej stronie akceptowane jest liczenie znaków APL jako bajtów, o ile nie są używane znaki Unicode. (tzn. używając znaków kodowych Unicode do kodowania ciągów znaków itp.)
marinus
@marinus, to brzmi rozsądnie. Co sądzisz o znakach Unicode w Mathematica?
maf-soft
@ maf-soft: cóż, jeśli istnieje kodowanie, w którym wszystkie użyte znaki mieszczą się w bajcie (więc obejmuje to zarówno znaki „specjalne”, jak i „normalne”, więc nie może być więcej niż 256 unikalnych znaków znaków), można go liczyć jako jeden bajt na znak. Jeśli nie, to nie może. Jeśli jednak Mathematica używa mniej niż 128 unikatowych znaków Unicode, można je w prosty sposób zmapować do górnej połowy bajtu, z ASCII w dolnej połowie. [1/2].
marinus
@ maf-soft: byłoby to jednak nowatorskie kodowanie (~ „język”), więc musisz udostępnić program tłumaczący i możesz go używać tylko w przypadku pytań nowszych niż program tłumaczący, zgodnie z regułą oznacza to, że możesz odpowiadać na pytania tylko w językach poprzedzających pytanie (aby zapobiec zdefiniowaniu języka za pomocą 1-bajtowego polecenia, aby dokładnie rozwiązać pytanie). [2/2]
marinus
5

Matematyka (83 82 79 69 67 66)

Przygotowanie

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

Kod

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

Jeśli policzymy używając znaków Unicode: 62 :

Tr[ArrayRules@a~Tuples~2/.{t_u_,v_w_}u~GCD~w#.#&[t-v]]〚1〛/2
kennytm
źródło
Możesz użyć wersji UTF '-> `: 
swish
@swish ->zajmuje 2 znaki i zajmuje 1 znak, jednak ->zajmuje 2 bajty i zajmuje 3 bajty w UTF-8. Może więc być dłuższy w zależności od wskaźników.
kennytm
Cóż, spójrz na rozwiązanie APL, więc myślę, że metryka jest w postaci na tym;)
swish
@swish To jest coś, co OP powinien wyjaśnić, ponieważ bajty UTF-8 są domyślnymi, jeśli nie podano :)
kennytm
@KennyTM - Nie jestem pewien, co jest najlepsze. Chciałbym śledzić, co jest wspólne na tej stronie. Obecnie nie mam czasu się dowiedzieć. Czy ktoś może pomóc z niektórymi linkami? Możesz także skorzystać z czatu wymienionego w komentarzach OP.
maf-soft
5

Python - 128 112 90 89 88

Przygotowanie:

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

Obliczanie liczby Delacorte (linia, która się liczy):

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

Wynik:

print D

Wynik:

5957
Falko
źródło
2
Możesz zwinąć obie forpętle w jeden generator i sumraz. Możesz także zapisać P(R,R)w zmiennej *x,=product(R,R), używając kopii oznaczonej gwiazdką. Co więcej, możesz sprawić, że będzie to czterokrotny produkt product(R,R,R,R)i po prostu zrób for j,n,i,m in product(*[R]*4).
xnor
@xnor: Świetnie! *[R]*4tego szukałem sam, ale nie mogłem dostać się do pracy.
Falko
1
widząc, że twoje przygotowanie nie wlicza się do liczby bajtów, czy nie możesz zrobić czegoś takiego jak from fractions import gcd as gzapisanie bajtów w ważnej sekcji?
FlipTack,
3

Pyth 43

Ta odpowiedź prawie na pewno mogłaby być dalej golfa; Szczególnie nie lubię obliczania odległości.

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

Aby to ustawić, zapisz liniową tablicę w zmiennej J. Możesz to zrobić, pisząc:

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

Wypróbuj online .

Wysyła liczbę zmiennoprzecinkową. Myślę, że to uzasadnione, proszę powiedzieć, czy złamałem regułę :)

Wyjaśnienie:

                                             : 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
źródło
Wow, w końcu pokonałem Pytha dzięki APL.
marinus
@marinus Haha, wciąż próbuję, ale myślę, że przynajmniej mnie pobiłeś :)
FryAmTheEggman
Wow, to jest szalone. Czytam teraz doc.txt, ale bardzo trudno mi to przeczytać!
rubik
@rubik Przynajmniej nie jest to APL: D Dokument nie jest w 100% dokładny, ponieważ cały ten język jest obsługiwany przez jednego faceta: isaacg . Jeśli masz pytania, nie krępuj się zapytać mnie / niego na czacie :)
FryAmTheEggman
2

CJam, 55

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

Przyjmuje macierz jako STDIN w następującym formacie:

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

Wypróbuj online tutaj

Optymalizator
źródło
Myślę, że możesz za darmo zaprogramować matrycę i użyć jej {}do utworzenia bloku zamiast używać standardowego wejścia. Ponadto, czy zrzucasz macierz do jednowymiarowej tablicy? Myślę, że możesz wziąć matrycę już sformatowaną, zobacz przykłady PO. (Nie znam dobrze CJama, więc weź to z
odrobiną
Czytanie macierzy i konwertowanie jej na pojedynczą listę jest q~]częścią. który jest krótszy w porównaniu do tego, kiedy go
Optimizer