Haskell, 183

3

199 caracteres en octava:

m=@(x)mod(x,1928049029);[d,l]=scanf('%d');c=d(1);e=repmat(int64(d(2:2:l)),1,c);[_,b]=gcd(e-e',1928049029*ones(c));b=eye(c)+m(e.*b);x=b(1,:);for i=2:c;x=m(x.*b(i,:));end;disp(m(sum(m(x'.*d(3:2:l)))))
Jeremiah Willcock
fuente

Respuestas:

3

Golfscript, 114 112 111 110 109 65 (86) caracteres

Si no le interesa obtener resultados esta semana, 65 caracteres son suficientes:

~](;2/0\:X{~\.X{0=}%^\{\.@- 1928049029:P.,\@{@*\%(!}++?**}+/+P%}/

Pero si buscas eficiencia, es un poco más largo con 86 caracteres:

~](;2/0\:X{~\.X{0=}%^\{\[.0](@-[1928049029:P%P]{.~/{\.(;@@~@*-+\}+2*.1=}do;0=*}+/+P%}/

Esto se analiza con mucho más detalle de lo que quiero repetir aquí en mi blog .


Principalmente no es mi trabajo, pero el hecho de que Nabb se mueva fuertemente da 47 caracteres:

n%(!\:A{~A{~;.3$- 1928049029:N((?1or**}/\/+N%}/

Nota: Solo he razonado sobre este código: intentar ejecutarlo no tendría sentido dada la cantidad de tiempo y la cantidad de memoria que usaría.

Peter Taylor
fuente
3

Golfscript - 52 46 (67)

Un enfoque de fuerza bruta para inversas modulares en 46 caracteres. Calcula repetidamente a ^ (N-2) con enteros de precisión arbitraria.

n%(!\:A{~A{~;.3$-.!+1928049029:N((?**}/\/+N%}/

La implementación del algoritmo euclidiano extendido solo nos cuesta 15 caracteres adicionales.

n%(!\:A{~A{~;.3$-:|!1\1928049029:N{@2$|3$/*-\|\:|%.}do;;**}/\/+N%}/

Este código está completamente detallado en mi publicación de blog , incluidas algunas alternativas para calcular el inverso multiplicativo modular.

Nabb
fuente
1
Bien, pero creo que todavía hay al menos dos caracteres para guardar. Reemplace {*N%2<}con {*N%1=}como en el blog y puede deshacerse del (;después N,. Pero luego, para la entrada de rendimiento es irrelevante, puede usar el pequeño teorema de Fermat sin preocuparse por el lado modular de la exponenciación, solo déjelo para el orden final, de modo que recip se convierta N((?.
Peter Taylor
1
@Peter: {*N%1=}+perderá el caso con el denominador cero, que tomaría al menos 3 caracteres para manejar. Sin embargo, es bueno hacer simplemente x ^ (N-2), de hecho podemos obtener 46 caracteres con esto.
Nabb
2

Lua 444 Chars

Funciona para el ejemplo en la página wiki

3
2 1942
4 3402
5 4414

Pero de alguna manera no funciona para los ejemplos aquí en esta página. Si alguien puede encontrar el error?

Versión sin golf:

-- Reconstruct shamir secret
-- convention, poly = {[0]=a0,a1,...,an}
i=io.read
f=math.fmod
w=1928049029
k=i():match"%d+"
x={} -- Will contain X values
y={} -- Will contain Y values
p={} -- will contain lagrange polynomials

-- Read data
for j=0,k-1 do
    x[j],y[j]=i():match("(%d+) (%d+)")
    print(j,x[j],y[j])
end
-- Multiplication and scaling function
function mul(p,q,s)
    -- multiply polies
    r={} -- poly to be returned
    for k=0,#p do 
        for l=0,#q do
            r[l+k]=r[l+k] or 0 -- if the coeff for degree l+k of x doesn't exist, put 0
            p[k]=p[k] or 0 -- if p hasn't got a coeff for x^k
            q[l]=q[l] or 0 -- idem for q
            r[l+k]=(r[l+k]+s*p[k]*q[l]%w -- calculate increment for coeff for x^(l+k) 
        end
    end
    -- Debugging
    io.write"Multiplied "
    printPoly(p)
    io.write"With       "
    printPoly(q)
    io.write("And scaling factor ",tostring(s),"\n")
    io.write"Yielding   "
    printPoly(r)
    return r
end

function printPoly(p) -- "Pretty" printing of the polynomial
    for k=#p,1,-1 do
        io.write(tostring(p[k] or 0),"x^",tostring(k),"+")
    end
    io.write(p[0])
    io.write"\n"
end
function egcd(a,b)
    if a == 0 then
        return b, 0, 1
    else
        local g, y, x = egcd(b % a, a)
        return g, x - math.floor(b / a) * y, y
    end
end

function inv(a,m)
    a=a>=0 and a or a+m
    local g,x,y = egcd(a,m)
    if g== 1 then
        return x%m
    else
        print(a,"has no inverse mod",m)
    end
end


-- generate lagrange polynomials
for j=0,#x do
    print("j=",j,"*********")
    for m=0,k-1 do
        if m~=j then -- if m==j, continue
            p[j]=p[j]or{[0]=1} -- if this poly doesn't exist, take 1
            p[j]=mul( p[j], {[0]=-x[m],1},inv(x[j]-x[m],w))-- multiply with (x-x_m)/(x_j-x_m)
            io.write"---------------------------------\n"
        end
    end
end
r=0 -- Result for x^0
for k=0,#p do
    print("l_"..k)
    printPoly(p[k]) -- print l_k
    r=r+f(y[k]*p[k][0],w) -- add coeff for x^0 to result
end
print("Secret was",f(r,w)) -- display result

Golfizado (sin campo finito), 444 caracteres:

i=io.read f=math.fmod w=1928049029 k=i():match"%d+"x={}y={}p={}for j=0,k-1 do x[j],y[j]=i():match("(%d+) (%d+)")end
function mul(p,q,s)r={}for k=0,#p do for l=0,#q do r[l+k]=r[l+k]or 0 p[k]=p[k]or 0 q[l]=q[l]or 0 r[l+k]=f(r[l+k]+s*p[k]*q[l],w)end end return r end
for j=0,#x do for m=0,k-1 do if m~=j then p[j]=p[j]or{[0]=1}p[j]=mul(p[j],{[0]=-x[m],1},1/(x[j]-x[m]))end end end r=0 for k=0,#p do r=r+f(y[k]*p[k][0],w)end
print(f(r,w))
jpjacobs
fuente
El ejemplo de Wikipedia no usa un campo finito, lo cual es realmente una pena, eso habría sido mucho más instructivo. Es muy probable que sea la fuente de su error.
aaaaaaaaaaaa
2

Java, 435 407 caracteres

import java.util.*;public class G{public static void main(String[]args){Scanner s=new Scanner(System.in);int i,k,n=s.nextInt();long N=1928049029L,x[]=new long[n],y[]=new long[n],z=0,l,c;for(i=n;i-->0;){x[i]=s.nextInt();y[i]=s.nextInt();}for(i=n;i-->0;){l=y[i];for(long j:x)if(x[i]!=j){c=1;for(long a=N+j-x[i],b=N,d=0,t;b>0;){t=d;d=c-a/b*d;c=t;t=b;b=a%b;a=t;}l=l*j%N*(c+N)%N;}z+=l;}System.out.println(z%N);}}

Sin golf:

import java.util.*;
public class G {
    public static void main(String[] args) {
        Scanner s=new Scanner(System.in);
        int i,k,n=s.nextInt();
        long N=1928049029L,x[]=new long[n],y[]=new long[n],z=0,l,c;
        for (i=n; i-->0;) {
            x[i]=s.nextInt();
            y[i]=s.nextInt();
        }
        for (i=n; i-->0;) {
            l=y[i];
            for (long j:x)
                if (x[i]!=j) {
                    // Extended Euclid algorithm - iterative version -
                    // to find the reciprocal of j-x[i] (mod N)
                    c=1;
                    for (long a=N+j-x[i], b=N, d=0, t; b>0;) {
                        t=d; d=c-a/b*d; c=t;
                        t=b; b=a%b; a=t;
                    }
                    l = l*j%N;
                    l = l*(c+N)%N;
                }
                z+=l;
        }
        System.out.println(z%N);
    }
}
Peter Taylor
fuente
2

Haskell, 183

p=1928049029
a#0=(1,0)
a#b=let(s,t)=b#mod a b in(t,s-div a b*t)
s d=sum[y*product[z*fst((z-x)#p)|[z,_]<-d,z/=x]|[x,y]<-d]
main=interact$show.(`mod`p).s.map(map read.words).tail.lines
hammar
fuente