다항식 보간


12

임의의 정확한 정밀도 유리수를 사용하여 다항식 보간 을 수행하는 프로그램을 작성하십시오 . 입력은 다음과 같습니다 :

f (1) = 2/3
f (2) = 4/5
f (3) = 6/7
...

=부호 앞뒤에 정확히 하나의 공백이 있다고 가정 할 수 있으며 모든 숫자는 분수 또는 정수입니다. 입력의 모든 분수는 이미 되돌릴 수 없다고 가정 할 수도 있습니다.

오류 검사가 필요하지 않으며 입력이 유효하고 f (x)에서 x가 두 배가되지 않는다고 가정 할 수 있습니다.

출력은 LaTeX 호환 형식이어야하며 방출 된 LaTeX 코드는 여기에 제공된 출력과 동일한 그래픽 표현을 가져야합니다.

f (x) = 123x ^ 2 + \ frac {45} {2} x + \ frac {7} {4}

분율은 가능한 한 줄여야합니다 (예 : 같은 \frac{2}{4} 것은 허용되지 않습니다. 숫자가 정수이면 분수를 사용하지 마십시오.

특별 규칙 :

당신의 프로그램은 ...

  • 12 차 다항식 작업
  • 합리적인 입력을 위해 1 분 이내에 완료
  • 전체 계산을 수행하는 기능을 사용하지 마십시오
  • 가능한 가장 작은 다항식을 출력

테스트 케이스 :

주어진 테스트 케이스는 설명을위한 것입니다. 프로그램은 모든 올바른 입력에 대해 올바른 결과를 산출해야합니다.

입력

f (1) = 2/3
f (2) = 4/5
f (3) = 6/7

산출

f (x) =-\ frac {4} {105} x ^ 2
       + \ frac {26} {105} x
       + \ frac {16} {35}

입력

f (-12) = 13/2
f (5/3) = 3/5
f (13) = -6
f (1/5) = -3/4

산출

f (x) =-\ frac {2186133} {239455744} x ^ 3
       + \ frac {2741731} {149659840} x ^ 2
       + \ frac {26720517} {29201920} x
       -\ frac {279464297} {299319680}

입력

f (4/3) = 617/81
f (2) = 20/3
f (-8/3) = 6749/81
f (-5) = 7367/12
f (0) = 23/3

산출

f (x) = \ frac {1} {2} x ^ 4
     -2x ^ 3
     + \ frac {7} {4} x ^ 2
     + \ frac {23} {3}

입력

f (0) = 5
f (1) = 7
f (2) = 9
f (3) = 11
f (4) = 13

산출

f (x) = 2x
     + 5

입력

f (1/2) = -1/2
f (-25) = -1/2
f (-54/12) = -1/2

산출

f (x) =-\ frac {1} {2}

당신이 사용하는 모든 것이 합리적인 숫자라면 왜 실수에 대해 이야기하고 있습니까?
Joey

죄송합니다. 내 영어 실력이 떨어집니다. 예, 합리적인 숫자 만 사용하십시오. 결과는 정확해야합니다.
FUZxxl

첫 번째 테스트 사례에서 점 ( ...)이 실제로 입력의 일부입니까?
Eelvex

@ Elvex : 아뇨. 결정된.
FUZxxl

세 번째 테스트 케이스의 출력이 잘못되었습니다. 정답은 -\frac{37745}{14592}x^4 - \frac{853249}{43776}x^3 + \frac{57809}{7296}x^2 + \frac{225205}{2736}x + \frac{23}{3}입니다. 나는 입력이 다른 것으로 의도되었다고 생각한다 :)
Timwi

답변:


3

J + 쉬

J 스크립트 :

i=:0".(1!:1)3
i=:((-:#i),2)$i
c=:|.(%.(x:((i.#i)^~])"0({."1 i)))(+/ .*)(|:{:"1 i)
(":(-.0=c)#(c,.i.-#c))(1!:2)2

sh 스크립트 :

echo -n 'f(x) = '
tr -d 'f()=' | tr /\\n- r' '_  | ./polyint.ijs | sed -e 's/^/+/;s/_/-/;s/\([0-9]*\)r\([0-9]*\)/\\frac{\1}{\2}/;s/ \([0-9]*$\)/x^\1/;s/\^1//;s/x^0//;s/+\(.*-.*\)/\1/'

sh 스크립트를 실행하십시오.

./pol-int.sh
f(1/2) = -1/2
f(-25) = -1/2
f(-54/12) = -1/2

f(x) = -\frac{1}{2}

.

./pol-int.sh
f(4/3) = 617/8
f(2) = 20/3
f(-8/3) = 6749/81
f(-5) = 7367/12
f(0) = 23/3

f(x) = -\frac{37745}{14592}x^4
       -\frac{853249}{43776}x^3
     +  \frac{57809}{7296}x^2
     + \frac{225205}{2736}x
     +  \frac{23}{3}

정확히 동일한 소스 코드 형식을 만들 필요는 없습니다. LaTeX 출력에서. LaTeX를 실행 한 후에도 동일한 그래픽 표현을 얻을 수 있습니다. 약간의 문자를 저장하십시오.
FUZxxl

나는 J를 읽을 ​​수 없지만 짧은 길이에서 J는 매트릭스에 첼론 형태의 내장 함수를 가지고 있다는 것을 의미합니다.
Timwi

@Timwi : 아니요,하지만 내장 된 "역행렬"을 사용합니다. J는 매우 간결합니다. "인버트 매트릭스"를 구현하더라도 길이는 몇 자입니다.
Eelvex

3

펄 (569 자)

use Math'BigInt;sub r{($u,$v)=@_;$v?r($v,$u%$v):$u}sub c{new Math'BigInt$_[0]}$a=@c=<>;for(@c){m!(-?\d+)/?(\d*). = (-?\d+)/?(\d*)!;$j{$_,$i}=$1**c$_,$k{$_,$i|=0}=($2||1)**c$_ for 0..$a;$j{$a,$i}=c$3;$k{$a,$i++}=c$4||1}for$p(0..$a-1){for$y(0..$p-1,$p+1..$a-1){$n=$j{$p,$y}*$k{$p,$p};$o=$k{$p,$y}*$j{$p,$p};$j{$_,$y}=$j{$_,$y}*$k{$_,$p}*$o-$k{$_,$y}*$j{$_,$p}*$n,$k{$_,$y}*=$k{$_,$p}*$o for 0..$a}}print"f(x)=";for(1..$a){$s=r$t=$j{$a,$p=$a-$_}*$k{$p,$p},$w=$k{$a,$p}*$j{$p,$p};$u=abs$t,print$t>0?"$z":'-',($z='+',$w/=$s)-1?"\\frac{$u}{$w}":$u,$p>1?"x^$p":x x$p if$t/=$s}

상해:

use Math'BigInt;

# Subroutine to calculate gcd of two numbers
sub r{($u,$v)=@_;$v?r($v,$u%$v):$u}

# Subroutine to create BigInts
sub c{new Math'BigInt$_[0]}

# Read input
# Throughout, $a is the number of equations.
$a=@c=<>;

# Initialises the $a+1 × $a matrix with all the values.
# $j{$x,$y} contains the numerator, $k{$x,$y} the denominator.
for(@c)
{
    m!(-?\d+)/?(\d*). = (-?\d+)/?(\d*)!;

    # Puzzle for the reader: why is $i|=0 in the second one,
    # not the first one? Answer at the bottom!
    $j{$_,$i}=$1**c$_,$k{$_,$i|=0}=($2||1)**c$_ for 0..$a;
    $j{$a,$i}=c$3;
    $k{$a,$i++}=c$4||1
}

# Generates the matrix echelon form.
# Basically, it works like this:
for$p(0..$a-1)
{
    # For each element along the diagonal {$p,$p}, set all the values above and
    # below it to 0 by adding a multiple of row $p to each of the other rows.
    for$y(0..$p-1,$p+1..$a-1)
    {
        # So we need to multiply the row $p by the value of {$p,$y}/{$p,$p}
        # (stored in $n/$o) and then subtract that from row $y.
        $n=$j{$p,$y}*$k{$p,$p};
        $o=$k{$p,$y}*$j{$p,$p};
            $j{$_,$y}=$j{$_,$y}*$k{$_,$p}*$o-$k{$_,$y}*$j{$_,$p}*$n,
            $k{$_,$y}*=$k{$_,$p}*$o
        for 0..$a
    }
}

# Outputs the result
print"f(x)=";
for(1..$a)
{
    # Note this sets $p = $a-$_. $p is the power of x.
    # We need to divide {$a,$p} by {$p,$p}. Store the result in $t/$w.
    # We also need to put the fraction in lowest terms, so calculate the gcd.
    $s=r$t=$j{$a,$p=$a-$_}*$k{$p,$p},$w=$k{$a,$p}*$j{$p,$p};

    # Output this term only if the numerator ($t) is non-zero.
    # Output a plus sign only if this isn’t the first term.
    # Output a fraction only if the denomator ($w) isn’t 1.
        $u=abs$t,print$t>0?"$z":'-',
        ($z='+',$w/=$s)-1?"\\frac{$u}{$w}":$u,$p>1?"x^$p":x x$p
    if$t/=$s
}

# Answer to the puzzle buried in the code above:
# It’s because the second part is passed as a second argument to c,
# hence it is evaluated before the first part.

코멘트

  • 나는 echelon 형식의 기능을 제공하는 매트릭스 조작 모듈이 있다고 확신합니다. 나는 그것을 직접 사용하지 않는 것이 콘테스트의 요점이라고 생각하기 때문에 그것을 사용하지 않았습니다 (하나도 검색하지 않았습니다). 그런 식으로 더 흥미 롭습니다. 물론 BigInt에 대해서도 마찬가지 일 수 있지만, 아무도이 도전을 시도하지 않을 것입니다 ...

편집

  • (630 → 585) 나는 두 개의 루프 대신 하나의 루프에서에 켈론 형태를 수행 할 수 있음을 깨달았다. 코드에 주석으로 설명을 추가하십시오.

  • (585 → 583) 방금 '대신 사용할 수있는 패키지 구문을 발견했습니다 ::.

  • (583 → 573) 좀 더 마이크로 골프

  • (573 → 569) 입력을 구문 분석하는 짧은 정규식


컴파일 오류가 계속 발생합니다. ideone.com/LoB2T
FUZxxl

@FUZxxl : 지적 해 주셔서 감사합니다. 공간이 부족했습니다. 지금 수정했습니다.
Timwi

3

TI-Basic (83/84) : 109 자

기술적으로 109자인 TI-Basic은 dim (, For (,->, rref (, [A])를 계산하고 "한 문자"로 나열합니다.

입력은 (x, y) 쌍으로 [L1 = (1,2,3,4), L2 = (2,3,5,7)] L1 및 L2로 포맷됩니다.

{1,1}->dim([A]
{dim(L1),dim(L2)+1}->dim([A]
For(A,1,dim(L1)
For(B,dim(L1)-1,0,-1
L1(A)^B->[A](A,dim(L1)-B
End
L2(A->[A](A,dim(L1)+1
End
rref([A]->[A]
{0}->L3
For(A,1,dim(L1)
[A](A,dim(L1)+1->L3(A
End
Disp L3

1
이것은 합리적 또는 LaTeX 양식을 사용하지 않습니다.
lirtosiast

1

라그랑주 메소드, Python, 199 바이트

조금 늦었지만 ...

def lagrange(dp):
l = lambda i: lambda x: (prod([(x - dp[j][0]) / (dp[i][0] - dp[j][0]) for j in range(len(dp)) if i != j]))
return lambda x: sum([l(i)(x) * dp[i][1] for i in range(len(dp))])

1
아마도 연산자 주위의 공백이 모두 필요하지 않습니까?

0
l=lambda D,i:lambda x:prod((x-Dj[0])/(D[i][0]-Dj[0])for j,Dj in enumerate(D)if i!=j)
L=lambda D:lambda x:sum(l(D,i)(x)*Di[1]for i,Di in enumerate(D))

Fred Freys 코드의 단축 버전. D를 l로 전달하는 것을 건너 뛸 수 있습니다. 외부 스코프에서 끌어낼 수 있기 때문입니다. 여기서 내가 똑같이 할 수 있기 때문에 람다 하나를 깎을 수도 있습니다. 나는 언젠가 그것을 테스트 할 것이다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.