ช่วยฉันด้วยแคลคูลัสที่แตกต่างกัน!


52

ฉันรักการเขียนโปรแกรมและรู้ทุกภาษา แต่ฉันดูดคณิตศาสตร์ น่าเสียดายที่โรงเรียนของฉันกำหนดให้นักเรียนคอมพิวเตอร์ต้องใช้แคลคูลัสหนึ่งปี สัปดาห์หน้าจะมีการทดสอบและฉันไม่รู้สูตรอนุพันธ์ใด ๆ !

โปรดช่วยฉันค้นหาสูตร ฉันต้องการสูตรโกง - โปรแกรม (สั้นที่สุดเท่าที่จะเป็นไปได้ดังนั้นครูของฉันจะไม่สังเกตเห็น) ที่ใช้นิพจน์ (เช่น4*x^3-2) เป็นอินพุตและเอาต์พุตอนุพันธ์ (ฉันไม่สนใจว่าอินพุตและเอาต์พุตใช้อาร์กิวเมนต์บรรทัดคำสั่ง STDIN, STDOUT หรืออะไรก็ตามเนื่องจากฉันทำการคำนวณทั้งหมดในหัวของฉันอยู่ดี)

การทดสอบครอบคลุมฟังก์ชันประเภทต่อไปนี้:

  • ค่าคงที่เช่น-3หรือ8.5
  • ฟังก์ชั่นพลังงานเช่นx^0.5หรือx^-7
  • ฟังก์ชันเลขชี้กำลังเช่น0.5^xหรือ7^x(ฐานเป็นบวกเสมอ)
  • ค่าคงที่คูณด้วยฟังก์ชันเช่น3*x^5หรือ-0.1*0.3^x
  • ผลรวมและความแตกต่างของฟังก์ชั่นหลายอย่างเช่น -5*x^2+10-3^x

ครูของฉันจะจัดรูปแบบคำถามของเขาในลักษณะเดียวกันเสมอตามที่แสดงไว้ด้านบน เขายังไม่ใช้เศษส่วนตัวเลขเช่น pi หรือeหรือตัวเลขใหญ่จริง ๆ (มากกว่า 1,000) เขาไม่เคยใช้วงเล็บและแสดงการคูณโดยใช้เครื่องหมายดอกจัน ( *) เสมอ ตัวแปรเฉพาะที่ใช้อยู่เสมอx

ในทางกลับกันครูของฉันค่อนข้างสุภาพเกี่ยวกับคำตอบ พวกเขาไม่จำเป็นต้องทำให้ง่ายขึ้นหรือจัดรูปแบบตามที่แสดงข้างต้นตราบใดที่ชัดเจนว่าคำตอบนั้นคืออะไร

ในขณะที่ฉันสามารถใช้ภาษาใด ๆ โปรดจำไว้ว่าฉันไม่สามารถหาอนุพันธ์ได้ด้วยตัวเอง ดังนั้นหากโปรแกรมใช้ฟังก์ชันในตัวเพื่อจัดการกับสมการหรือคำนวณอนุพันธ์ฉันจะไม่สามารถใช้มันได้

ในระหว่างการทดสอบฉันจะไม่สามารถเข้าถึงอินเทอร์เน็ตหรือไฟล์อื่น ๆ นอกเหนือจากโปรแกรมบนแผ่นงานโกง

หมายเหตุ: สถานการณ์นี้เป็นเรื่องสมมติทั้งหมด ในชีวิตจริงการโกงและช่วยเหลือผู้อื่นการโกงเป็นสิ่งที่ผิดและไม่ควรทำ


3
เราคาดหวังได้xไหมว่ามันเป็นตัวแปรที่ทำให้เกิดความแตกต่างอยู่เสมอ
Kyle Kanos

2
คำตอบต้องง่ายขึ้นหรือไม่ เราจำเป็นต้องเพิ่มคำเหมือนหรือไม่?
Rainbolt

1
ฉันเดาว่าถึงเวลาแล้วสำหรับโครงการแคลคูลัสของฉันที่scrblnrd3.github.io/Javascript-CASเพื่อส่องแสงถ้าฉันสามารถเล่นกอล์ฟได้จริง ๆ
scrblnrd3

1
เราควรสมมติว่าไม่มีการล้อเลียน?
ไม่ใช่ว่า Charles

2
ผมเคยตอบส่วนใหญ่ของคำถามเหล่านี้ในการแก้ไขของฉัน ไม่มีสัญกรณ์ทางวิทยาศาสตร์หรือกฎผลิตภัณฑ์
Ypnypn

คำตอบ:


8

Wolfram 136 134 109 [ขอบคุณ Calle สำหรับความคิดเห็นของเขาด้านล่าง]

การสนับสนุนที่ จำกัด สำหรับกฎของผลิตภัณฑ์และห่วงโซ่

n=n_?NumberQ;d[v_Plus]:=d/@v;d[v_]:=v/.{x_^n:>x^(n-1)d[x]n,n^x_:>Log[n]d[x]n^x,x_*y__:>d[x]y+d[y]x,n:>0,x:>1}

ตัวอย่าง:

d[3^(x^2)*(x^3+2*x)^2]
>> 2*3^x^2*(2+3*x^2)*(2*x+x^3) + 2*3^x^2*x*(2*x+x^3)^2*Log[3]

โปรดทราบว่านี่ไม่ได้ใช้ "ฟังก์ชันในตัวเพื่อจัดการกับสมการหรือคำนวณอนุพันธ์": มีเพียงการจับคู่รูปแบบเท่านั้นที่เกี่ยวข้อง *

[* อืม ... ในทางเทคนิคแล้วล่ามก็แยกวิเคราะห์และสร้าง AST จากอินพุตเช่นกัน]


Ungolfed:

d[expr_Plus] := d /@ expr;
d[expr_] := expr /. {
   Power[x_, n_?NumberQ] :> n Power[x, n - 1] d[x],
   Power[n_?NumberQ, x_] :> Log[n] Power[n, x] d[x],
   Times[x_, y__] :> d[x] y + d[y] x,
   n_?NumberQ :> 0,
   x :> 1
}

นี้เป็นรุ่นอื่น คุณไม่ต้องเขียนPower, Timesฯลฯ IDK เท่าใดที่จะปรับปรุงรุ่นแข็งแรงเล่นกอล์ฟของคุณว่า แต่คุณมีอย่างน้อยหนึ่งTimesในนั้นเพื่อให้คุณสามารถ def บันทึกตัวละครบางตัว นอกจากนี้ทราบว่าในรุ่น ungolfed d[expr_]:= v/...ของคุณมันบอกว่า

1
@Calle "IDK ว่าจะปรับปรุงเวอร์ชัน golfed ของคุณ" - 25 ไบต์! ไชโย!
สราญ

26

Perl - 121 122

(+2 สำหรับ-p)

s/(?<![-\d.*^])-?[\d.]+(?![*^\d.])/0/g;s/(?<!\^)x(?!\^)/1/g;s/x\^(-?[\d.]+)/"$1*x^".($1-1)/ge;s/([\d.]+)\^x/ln($1)*$&/g

ทดสอบ:

$ perl -p diff.pl << EOF
> -3
> 8.5
> x^0.5
> x^-7
> 0.5^x
> 7^x
> 3*x^5
> -0.1*0.3^x
> -5*x^2+10-3^x
> EOF
0
0
0.5*x^-0.5
-7*x^-8
ln(0.5)*0.5^x
ln(7)*7^x
3*5*x^4
-0.1*ln(0.3)*0.3^x
-5*2*x^1+0-ln(3)*3^x

ยังเป็นอีกเหตุผลหนึ่งที่ฉันจะเรียน regex ...
Kyle Kanos

3
@KyleKanos อย่า Regex ไม่ดี regex ยอดเยี่ยมมาก
mniip

Meh เอาชนะฉันไปที่มัน ไม่เลว! (PS: regex สวยงาม)
Martin Ender

8
ฉันไม่รู้ว่าเกิดอะไรขึ้นที่นี่ +1
qwr

4
คำอธิบาย: ค่าคงที่ -> 0, x -> 1, x ^ n -> n * x ^ (n-1), a ^ x -> ln (a) * a ^ x
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

7

Haskell 38 Chars

ฟังก์ชั่นdใช้ฟังก์ชั่นและส่งกลับฟังก์ชั่น มันถูกป้อนเข้าในรูปแบบของซีรีย์พาวเวอร์และเอาท์พุทแบบเดียวกัน (ซึ่งเป็นประเภทของอะไรก็ตาม)

d=zipWith(*)[1..].tail

ตัวอย่างเช่นถ้าเราป้อนข้อมูลที่เราได้รับx->x^2x->2*x

λ <Prelude>: d [0,0,1]
[0,2]

และสำหรับฟังก์ชันเลขชี้กำลัง

λ <Prelude>: take 10 exp --exp redefined above to be in power series notation
[1.0,1.0,0.5,0.16666666666666666,4.1666666666666664e-2,8.333333333333333e-3,1.388888888888889e-3,1.984126984126984e-4,2.48015873015873e-5,2.7557319223985893e-6]
λ <Prelude>: let d=zipWith(*)[1..].tail in take 10 $ d exp
[1.0,1.0,0.5,0.16666666666666666,4.1666666666666664e-2,8.333333333333333e-3,1.388888888888889e-3,1.984126984126984e-4,2.48015873015873e-5,2.7557319223985893e-6]

5
แต่ OP ไม่ทราบคณิตศาสตร์ใด ๆ ! เราสามารถคาดหวังให้เขาแสดงการป้อนข้อมูลเลขชี้กำลังของเขาเป็นชุดพลังงานได้หรือไม่
สราญ

เห็นได้ชัดว่าเขารู้สัญกรณ์ เขาแค่ไม่รู้วิธีการทำอนุพันธ์
PyRulez

5
จับได้2^xไหม
Kyle Kanos

5
คาถานี้คืออะไร?
Christofer Ohlsson

7
ฉันไม่เห็นว่า "รับนิพจน์ (เช่น4*x^3-2) เป็นข้อมูลป้อนเข้า" ตามที่ OP ต้องการ
Gabe

5

อารัมภบท 176

d(N,0):-number(N).
d(x,1).
d(-L,-E):-d(L,E).
d(L+R,E+F):-d(L,E),d(R,F).
d(L-R,E-F):-d(L,E),d(R,F).
d(L*R,E*R+L*F):-d(L,E),d(R,F).
d(L^R,E*R*L^(R-1)+ln(L)*F*L^R):-d(L,E),d(R,F).

ผู้ประกอบการที่รองรับ: ไบนารี+ไบนารี-ไบนารี*ไบนารี^, -เอก โปรดทราบว่า+ไม่รองรับunary

วิ่งตัวอย่าง:

49 ?- d(-3,O).
O = 0.

50 ?- d(8.5,O).
O = 0.

51 ?- d(x^0.5,O).
O = 1*0.5*x^ (0.5-1)+ln(x)*0*x^0.5.

52 ?- d(x^-7,O).
ERROR: Syntax error: Operator expected
ERROR: d(x
ERROR: ** here **
ERROR: ^-7,O) . 
52 ?- d(x^ -7,O).
O = 1* -7*x^ (-7-1)+ln(x)*0*x^ -7.

53 ?- d(x,O).
O = 1.

54 ?- d(0.5^x,O).
O = 0*x*0.5^ (x-1)+ln(0.5)*1*0.5^x.

55 ?- d(7^x,O).
O = 0*x*7^ (x-1)+ln(7)*1*7^x.

56 ?- d(3*x^5,O).
O = 0*x^5+3* (1*5*x^ (5-1)+ln(x)*0*x^5).

57 ?- d(-0.1*0.3^x,O).
O = 0*0.3^x+ -0.1* (0*x*0.3^ (x-1)+ln(0.3)*1*0.3^x).

58 ?- d(-5*x^2+10-3^x,O).
O = 0*x^2+ -5* (1*2*x^ (2-1)+ln(x)*0*x^2)+0- (0*x*3^ (x-1)+ln(3)*1*3^x).

อารัมภบทสับสนเมื่อมันวิ่งเข้าไปใน^-ลำดับ ต้องแทรกช่องว่างระหว่าง^และ-เพื่อให้การแยกวิเคราะห์นิพจน์ถูกต้อง

หวังว่าคุณครูของคุณจะไม่รังเกียจสิ่งที่สมการ

เวลาบ้า:

59 ?- d(x^x,O).
O = 1*x*x^ (x-1)+ln(x)*1*x^x.

60 ?- d((x^2-x+1)*4^ -x,O).
O = (1*2*x^ (2-1)+ln(x)*0*x^2-1+0)*4^ -x+ (x^2-x+1)* (0* -x*4^ (-x-1)+ln(4)* - 1*4^ -x).

4

C, 260

เฮ้ฉันคิดว่าฉันรู้จักอาจารย์ของคุณแล้ว! ไม่ใช่คนที่มีความสามารถเหนือธรรมชาติในการตรวจสอบนักเรียนที่ดำเนินการฟังก์ชั่นการจับคู่รูปแบบห้องสมุดในหัวของพวกเขา?

ดังนั้นการใช้ไม่sscanfเป็นปัญหา ... แต่ไม่ต้องกังวล:

#define P s--||printf(
q=94,s,c,t,a;main(){char i[999],*p=i,*e=p;gets(i);for(;c=*p++,t=q^94|c^45?c%26==16?c%16/3:c/46:1,s=(a="30PCqspP#!C@ #cS` #!cpp#q"[s*5+t])/16-3,a&1&&(p[-1]=0),t||(P"*0"),P"/x"),P"/x*%s",e),P"*ln(%s)",e),s=0),a&2&&(e=p),c;putchar(q=c));}

ตัวอย่างการรัน (อินพุตเปิดstdin; เอาต์พุตไปที่stdout):

4 * x ^ 3-2

4*x^3/x*3-2*0

รูปแบบนี้ดีกว่าเพียง12*x^2เพราะครูของคุณสามารถมั่นใจได้ว่าคุณคำนวณคำตอบด้วยตัวเองและไม่โกงโดยการคัดลอกจากคนอื่น!

x + 2 ^ x

x/x+2^x*ln(2)

ผลลัพธ์มีปัญหาโดเมนเล็กน้อยที่x=0แต่มันถูกต้องเกือบทุกที่ !

สำหรับการอ้างอิงต่อไปนี้เป็นเวอร์ชั่นที่ไม่สามารถอ่านได้ มันใช้เครื่องรัฐที่มี 5 รัฐและ 5 ประเภทของตัวอักษรอินพุต

void deriv(char* input)
{
    char* p = input; // current position
    char* exp = p; // base or exponent
    char q = '^'; // previous character

    // State machine has 5 states; here are examples of input:
    // state 0: 123
    // state 1: 123*
    // state 2: 123*x
    // state 3: 123*x^456
    // state 4: 123^x
    int state = 0;

    // Control bits for state machine:
    // bit 0: special action: stop recording base or exponent
    // bit 1: special action: start recording base or exponent
    // bits 4-7: if first column, specify how to calculate the derivative:
    //              3 - multiply the constant term by 0
    //              4 - divide x by x
    //              5 - divide x^n by x and multiply by n
    //              6 - multiply n^x by ln(n)
    // bits 4-7: if not first column, specify the next state
    //              (plus 3, to make the character printable)
    const char* control =
        "\x33\x30\x50\x43\x71"
        "\x73\x70\x50\x23\x21"
        "\x43\x40\x20\x23\x63"
        "\x53\x60\x20\x23\x21"
        "\x63\x70\x70\x23\x71";

    for (;;) {
        int c = *p++;

        // Convert a char to a category:
        // category 0: // - +
        // category 3: // *
        // category 2: // x
        // category 4: // ^
        // category 1: // numbers: 0...9 and decimal point
        int category;
        int action;    

        if (q == '^' && c == '-')
            category = 1; // unary minus is a part of a number
        else
            category = c%26==16?c%16/3:c/46; // just does it

        // Load new state and action to do
        action = control[state * 5 + category];

        if (action & 1)
            p[-1] = 0;
        state = (action >> 4) - 3;
        if (category == 0)
        {
            if (state == 0)
                printf("*0");
            if (state == 1)
                printf("/x");
            if (state == 2)
                printf("/x*%s", exp);
            if (state == 3)
                printf("*ln(%s)", exp);
            state = 0;
        }
        if (action & 2)
            exp = p;

        if (c == 0 || c == '\n') // either of these can mark end of input
            break;

        putchar(c);
        q = c;
    }
}

PS ระวังgetsฟังก์ชั่นนั้น: มันมีช่องโหว่ด้านความปลอดภัยที่ทำให้ครูของคุณสามารถรูทคิทในใจของคุณได้ด้วยการให้อินพุตนานเกินไป ...


3

ลัวะ296 268 263

function d(a)l=""i=a:find"x" if i then if a:sub(i-1,i-1)=="^"then l="log("..a:sub(1,i-2)..")*"..a elseif a:sub(i+1,i+1)=="^"then l=a:sub(i+2).."*"..a:sub(1,i)p=a:sub(i+2)-1 if p~=1 then l= l..a:sub(i+1,i+1)..p end else l=a:sub(1,i-2)end else l="0"end return l end

ไม่ค่อยเล่นกอล์ฟมากนักและไม่สามารถจัดการหลาย ๆ คำศัพท์ได้ (คุณสามารถเรียกใช้ได้สองสามครั้งใช่มั้ย) แต่สามารถจัดการn^xได้x^nและnเป็นอินพุต


Ungolfed ...

function d(a)
   l=""
   i=a:find"x"
   if i then
      if a:sub(i-1,i-1)=="^" then
         l="log("..a:sub(1,i-2)..")*"..a
      elseif a:sub(i+1,i+1)=="^" then
         l=a:sub(i+2).."*"..a:sub(1,i)
         p=a:sub(i+2)-1 -- this actually does math here
         if p~=1 then
            l= l..a:sub(i+1,i+1)..p
         end
      else
         l=a:sub(1,i-2)
      end
   else
      l="0"
   end
   return l
end

str.func(str,...)== str:func(...)นั่นคือเหตุผลที่ว่าทำไมสตริงจึงมีความสามารถในการ Metatable หลังจากทั้งหมด ...
mniip

@mniip: ยังเรียน Lua อยู่ ขอบคุณสำหรับทิป.
Kyle Kanos

1
เนื่องจาก OP กำลังมองหารหัสเท่านั้น "เขาสามารถคำนวณได้ในหัวของเขา" ฉันไม่ต้องกังวลกับการกำหนดฟังก์ชั่นและการประกาศlท้องถิ่น เพียงแค่คาดหวังว่าการป้อนข้อมูลจะถูกเก็บไว้ในและกล่าวว่าการส่งออกจะถูกเก็บไว้ในa l
Martin Ender

คุณสามารถละเว้นวงเล็บในได้a:find("x")และโปรดทราบว่า1thenจะใช้ได้เฉพาะใน Lua 5.2
mniip

@mniip: โอ้โหนั่นเจ๋งดีที่()เป็นทางเลือก 1thenได้รับการแก้ไขเช่นเดียวกับผมไม่ได้มี 5.2 (ไม่ได้ทำการปรับปรุง CPU ใด ๆ จนกว่าหลังจากวิทยานิพนธ์จะทำ B / C ฉันไม่ต้องการอะไรเลอะ)
Kyle Kanos

3

ECMAScript 6, 127 bytes

นี่คือความพยายาม regex ของฉัน (ใช้ regex เดียวและตรรกะบางอย่างในการโทรกลับแทน):

i.replace(/(^|[*+-])(\d+|(?:([\d.]+)\^)?(x)(?:\^(-?[\d.]+))?)(?![.*^])/g,(m,s,a,b,x,e)=>s+(b?'ln'+b+'*'+a:e?e--+'*x^'+e:x?1:0))

สิ่งนี้คาดว่าสตริงอินพุตจะถูกเก็บไว้ในiและเพียงแค่ส่งคืนผลลัพธ์ ลองใช้ในคอนโซลที่สอดคล้องกับ ECMAScript 6 (เช่น Firefox)


2

sed, 110

การใช้ตัวอักษร "พวกเขาไม่จำเป็นต้องทำให้ง่ายขึ้นหรือจัดรูปแบบตามที่แสดงข้างต้นตราบใดที่มันชัดเจนว่าคำตอบคืออะไร":

s/.*/__&_/;s/x\^(-?[0-9.]+)/\1*x^(\1-1)/g;s/([0-9.]+)\^/ln\1*\1^/g;s/([^(][-+_])[0-9.]+([-+_])/\10\2/g;s/_//g

จำนวนไบต์รวม 1 สำหรับrแฟล็ก

Ungolfed พร้อมความคิดเห็น:

# Add underscores before and after the string, to help with solo-constant recognition
s/.*/__&_/
# Power rule: replace x^c with c*x^(c-1) where c is a number
s/x\^(-?[0-9.]+)/\1*x^(\1-1)/g
# Exponentials: replace c^ with lnc*c^ where c is a number
# (This assumes that there will be an x after the ^)
s/([0-9.]+)\^/ln\1*\1^/g
# Constants: replace ?c? with ?0? where c is a number and ? is +, -, or _
# Except if it's prededed by a parenthesis then don't, because this matches c*x^(c-1)!
s/([^(][-+_])[0-9.]+([-+_])/\10\2/g
# Get rid of the underscores
s/_//g

วิ่งตัวอย่าง:

$ cat derivatives.txt
-3
8.5
x^0.5
x^-7
0.5^x
7^x
3*x^5
-0.1*0.3^x
-5*x^2+10-3^x

$ sed -re 's/.*/__&_/;s/x\^(-?[0-9.]+)/\1*x^(\1-1)/g;s/([0-9.]+)\^/ln\1*\1^/g;s/([^(][-+_])[0-9.]+([-+_])/\10\2/g;s/_//g' derivatives.txt
-0
0
0.5*x^(0.5-1)
-7*x^(-7-1)
ln0.5*0.5^x
ln7*7^x
3*5*x^(5-1)
-0.1*ln0.3*0.3^x
-5*2*x^(2-1)+0-ln3*3^x

ฉันพนันได้เลยว่าจะสามารถเล่นกอล์ฟต่อไปได้ sedมันเป็นความพยายามครั้งแรกของฉันที่ สนุก!


1

ทับทิม, 152

... หรือ 150 ถ้าคุณไม่จำเป็นต้องพิมพ์ ... หรือ 147 ถ้าคุณยังโอเคกับอาร์เรย์ที่คุณต้องเข้าร่วมด้วยตัวเอง

ทำงานด้วย ruby -nal

p gsub(/(?<!\^)([-+])/,'#\1').split(?#).map{|s|s[/x\^/]?$`+$'+"x^(#{$'}-1)":s[/-?(.*)\^(.*)x/]?s+"*ln(#{$1}*#{$2[0]?$2:1})":s[/\*?x/]?($`[0]?$`:1):p}*''

ungolfed:

p gsub(/(?<!\^)([-+])/,'#\1').split(?#). # insert a # between each additive piece, and then split.
map{ |s|                                 
    if s[/x\^/]                          # if it's c*x^a
        $` + $' + "x^(#{$'}-1)"          #      return c*ax^(a-1)
    elsif s[/-?(.*)\^(.*)x/]             # if it's c*b^(a*x)
        ln = $1 + ?* + ($2[0] ? $2 : 1)  #      return c*b^(a*x)*ln(b*a)
        s+"*ln(#{ln})"
    elsif s[/\*?x/]                      # if it's c*x
        ($`[0] ? $` : 1)                 #      return c
    else                                 # else (constant)
        nil                              #      return nil
    end
}*''

ปัญหาหลักของฉันเกี่ยวกับตัวนี้คือจำนวนตัวอักษรที่เหมาะสมในการแยก วิธีเดียวที่ฉันสามารถคิดได้คือsplit(/(?<!\^)([-+])/)สิ่งที่ให้+และ-เป็นผลลัพธ์ของตนเอง คำแนะนำใด ๆ สำหรับการแก้ปัญหาที่ดีกว่า

นอกจากนี้มีวิธีที่สั้นกว่าในการส่งคืนสินค้าsหากไม่ได้ว่างเปล่า แต่กลับมาเป็นอย่างอื่นyไหม ผมเคยใช้s[0]?y:s? ใน JS ฉันเพิ่งทำs||yแต่""เป็นความจริงในทับทิม


จะ lookahead ยืนยันความช่วยเหลือเช่นดังนั้น: split(/(?<!\^)(?=[-+])/)?
DLosc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.