ถูก, เร็ว, ดี - ปัจจัยทั่วไป (ยอดเยี่ยม) [ปิด]


10

แรงบันดาลใจจากราคาถูกเร็วดีเราจะใช้อัลกอริทึมที่มีสองอย่าง

คณิตศาสตร์

กำหนดจำนวนเต็มสองไม่ใช่ศูนย์aและb , GCF dเป็นจำนวนเต็มที่มากที่สุดที่แบ่งทั้งaและbโดยไม่เหลือ Bézoutสัมประสิทธิ์คู่ของจำนวนเต็ม(x, y)เช่นว่าขวาน + โดย = d ค่าสัมประสิทธิ์Bézoutไม่ซ้ำกัน ตัวอย่างเช่นกำหนด:

a = 15, b = 9

เรามี

d =  3
x =  2
y = -3

15*2 + 9*(-3) = 30 - 27 = 3ตั้งแต่

วิธีการทั่วไปในการคำนวณ GCF และสัมประสิทธิ์Bézoutคู่หนึ่งคือการใช้อัลกอริทึมของ Euclidแต่ก็ไม่ได้เป็นวิธีเดียวเท่านั้น

รหัส

โปรแกรมของคุณควรใช้จำนวนเต็มสองตัวเป็นอินพุต มันควรจะส่งออก / คืนปัจจัยที่ยิ่งใหญ่ที่สุดและค่าสัมประสิทธิ์Bézoutหนึ่งคู่

อินพุตตัวอย่าง:

15 9

เอาท์พุทตัวอย่าง

3 (2, -3)

เอาต์พุตสามารถอยู่ในลำดับและรูปแบบใดก็ได้ แต่ควรมีความชัดเจนซึ่งคือ GCF และสัมประสิทธิ์

คนทรยศ

โปรแกรมของคุณมีศักยภาพที่จะถูกเร็วและดี น่าเสียดายที่มันสามารถมีได้สองรายการพร้อมกัน

  • เมื่อมันไม่ถูกโปรแกรมควรใช้ทรัพยากรระบบมากเกินไป
  • เมื่อมันไม่เร็วโปรแกรมควรใช้เวลานานเกินไป
  • เมื่อไม่ดีผลลัพธ์ของโปรแกรมควรผิด

โปรแกรมควรจะสามารถทำ (ทั้งดีไม่ได้ทำ) ทั้งสาม ซึ่งจะทำเมื่อขึ้นอยู่กับคุณ - มันอาจขึ้นอยู่กับเวลาคอมไพเลอร์ซึ่งอินพุตมีขนาดใหญ่ขึ้น ฯลฯ หมายเหตุเพิ่มเติมบางส่วน:

  • โปรแกรมของคุณไม่ควรใช้อย่างเห็นได้ชัดและควรผ่านการตรวจสอบคร่าวๆ ฉันจะสงสัยนิดหน่อยถ้าคุณใช้อัลกอริธึมสามแยก
  • ในกรณีที่ราคาถูก "ทรัพยากรระบบจำนวนมาก" เป็นสิ่งที่จะทำให้โปรแกรมอื่นช้าลง อาจเป็นหน่วยความจำแบนด์วิดท์ ฯลฯ
  • ในการได้อย่างรวดเร็วกรณี "เวลามากเกินไป" หมายความว่าเมื่อเทียบกับวิธีการที่จะทำงานในราคาถูกและดีกรณี โปรแกรมควรจะยังคงเสร็จสิ้น ยิ่งคุณเข้าใกล้ "น่าผิดหวังอย่างไม่น่าเชื่อ แต่ไม่ทำลายพอที่จะหยุดโปรแกรม" ดีกว่า (สนุกและ) ดีกว่า
  • ในกรณีที่ดีผลลัพธ์ไม่ควรผิดอย่างชัดเจนและควรผ่านการตรวจสอบคร่าวๆ ฉันสงสัยมากถ้ามันให้ GCF ที่ "2 anna ครึ่ง"

นี่คือการประกวดความนิยมผู้ชนะมากที่สุดจึงชนะ!

แก้ไข

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


1
ดีใจที่มีความท้าทายเริ่มต้นเช่นนี้ :)
Ypnypn

โปรแกรมจำเป็นต้องมีสองอย่างพร้อมกันหรือไม่หากเป็นโปรแกรมที่ดีในบางกรณีและราคาถูกและรวดเร็ว (แต่ไม่ดี) ในโปรแกรมอื่น?
Dennis

1
ฉันกำลังมองหาสามกรณีที่มีสองในแต่ละ
Hovercouch

ถ้าโปรแกรมไม่ดีเอาต์พุตจะไม่ถูกต้อง? แล้วอะไรคือจุดประสงค์ในการคำนวณอะไรให้ถูกต้อง?
Ricardo A

4
ฉันลงคะแนนเพื่อปิดคำถามนี้เป็นปิดหัวข้อเพราะเป็น [ซ่อนเร้น] ท้าทายซึ่งตั้งอยู่บนหัวข้อปีที่ผ่านมา แต่ตอนนี้ปิดหัวข้อโดยฉันทามติของชุมชน
James

คำตอบ:


2

มันถูกและเร็ว คุณได้รับ gcd ในพริบตา อย่างไรก็ตามคนที่ทำมันไม่มีเงื่อนงำเกี่ยวกับ "Bézierร่วมอะไรบางอย่าง" ดังนั้นเขาจึงแบ่ง a และ b โดย gcd (เพื่อทำให้สิ่งเลวร้ายลง ณ จุดนั้นและ a b อยู่ไกลจากค่าเริ่มต้นเนื่องจากอัลกอริทึมที่เขาเลือกอย่างชาญฉลาด)

int main(int argc, char **argv){
    unsigned int a, b, tmp;
    a = (unsigned int)atoi(argv[1]);
    b = (unsigned int)atoi(argv[2]);
    for (tmp = 0; ((a | b) & 1) == 0; ++tmp){
        a >>= 1;
        b >>= 1;
    }
    while ((a & 1) == 0) 
        a >>= 1;
    do {
        while ((b & 1) == 0)
            b >>= 1;
        if (a > b){
            unsigned int t = b; 
            b = a; 
            a = t;
        }  
        b = b - a;
    } while (b != 0);
    tmp = a << tmp;
    printf("%u, (%u,%u)", tmp, a/tmp, b/tmp);
    return 0;
}

0

ค#

สิ่งนี้จะคำนวณค่าสัมประสิทธิ์Bézout ผมใช้ขั้นตอนวิธี Euclidean ขยาย

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter your first number.");
            int firstNumber = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Enter your second number.");
            int secondNumber = Convert.ToInt32(Console.ReadLine());

            double max = Math.Max(firstNumber, secondNumber);
            double min = Math.Min(firstNumber, secondNumber);
            double s1 = 1;
            double s2 = 0;
            double t1 = 0;
            double t2 = 1;
            double quotient = 0;
            double remainder = 0;
            double[] remainders = new double[0];

            int i = 0;
            do
            {
                quotient = (int)(max / min);
                remainder = max - quotient * min;
                if (remainder > 0)
                {
                    Array.Resize(ref remainders, remainders.Length + 1);
                    remainders[i] = remainder;

                }
                if (i % 2 == 0)
                {
                    s1 = s1 - quotient * s2;
                    t1 = t1 - quotient * t2;
                }
                else
                {
                    s2 = s2 - quotient * s1;
                    t2 = t2 - quotient * t1;
                }

                if (i == 0)
                {
                    max = min;

                }
                else if (i >= 1)
                {
                    max = remainders[i - 1];
                }


                min = remainder;
                i++;
            } while (remainder > 0);

            Console.WriteLine((remainders[remainders.Length - 1]).ToString() + " " + (i % 2 == 0 ? "(" + s1 + "," + t1 + ")" : "(" + s2 + "," + t2 + ")"));
        }

    }
}

ราคาแพงเมื่อไหร่มันช้าและเมื่อไร
undergroundmonorail

@undergroundmonorail ฉันจะใส่ค่าเหล่านั้นเมื่อฉันมีโอกาส
Bura Chuhadar

0

Perl 5

#!/usr/bin/perl
use strict;
use warnings;

$SIG{__WARN__} = sub { exit };

print(<<INTRO);
Greatest Common Factor

    goodbye           -- exit the application
    [number] [number] -- compute gcf of both numbers

INTRO

main();
sub main {
    print "> ";
    chomp(local $_ = <STDIN>);

    print "Have a good one.\n" and exit if /goodbye/;

    my @nums = /(-?\d+)/g;
    print "invalid input\n" and return main() if @nums != 2;

    my ($gcf, @coeff) = gcf(@nums);
    unless (grep abs($_) > 99, $gcf, @coeff) {
        select $\,$\,$\, rand for 1..10;
    }

    local $" = ", "; #"
    print "gcf(@nums) = $gcf\n";
    print "bezout coefficients: @coeff\n";
    main();
}

sub gcf {
    my ($x, $y) = @_;

    my @r = ($x, $y);
    my @s = (1, 0);
    my @t = (0, 1);

    my $i = 1;
    while ($r[$i] != 0) {
        my $q = int($r[$i-1] / $r[$i]);
        for (\@r, \@s, \@t) {
            $_->[$i+1] = $_->[$i-1] - $q * $_->[$i];
        }
        $i++;
    }

    return map int(1.01 * $_->[$i-1]), \@r, \@s, \@t;
}

__END__

ไม่ถูก: main () ถูกเรียกซ้ำ (เติมกองซ้อน) จนกว่าจะมีการเตือน "การเรียกซ้ำลึก" โดย perl ซึ่งจะออกจากแอปพลิเคชันเนื่องจากตัวจัดการ __WARN__

ไม่เร็ว: เมื่ออัลกอริทึม gcf () ส่งคืนผลลัพธ์ที่ถูกต้องรหัสก็จะหยุดทำงานเป็นเวลาสองสามวินาที (select () ใน main ())

ไม่ดี: ผลลัพธ์ทั้งหมดที่อยู่เหนือ 99 (หรือต่ำกว่า -99) ไม่ถูกต้อง

ทั้งหมดไม่สร้างสรรค์เช่นนั้น รอคอยที่จะได้คำตอบที่หรูหรามากขึ้น


0

หลาม

#!/usr/bin/python
def gcd(x, y):
    l = 0
    if x < y:
        l = x
    else:
        l = y
    for g in reversed(range(l + 1)):
        if x%g == 0 and y%g == 0 and g > 1:
            return g
        else:
            if g == 1:
                return 1

def bezout(x,y,g):
    c1 = 0
    c2 = 0
    k = 0
    if x < y:
        k = y
    else:
        k = x
    for _k in range(k):
        tc = (gcd(x,y) - x*_k)%y
        if tc == 0:
            c1 = _k
            c2 = (gcd(x,y) - y*_k)/x
            return (c1, c2)

gc = gcd(15,9)
be, bf = bezout(9,15,gc)
print("%d (%d, %d)" % (gc, be, bf))

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

ปริศนาดี


0

จาวาสคริ

ไม่ถูก

ใช้ทรัพยากรระบบจำนวนมาก

function gcf(a, b) {
    var result = 1;
    for (var i = 1; i < 100000000 * a && i < 100000000/* Do it a few extra times, just to make sure */ * b; i++) {
        if (a % i == 0 && b % i == 0) {
            result = i;
        }
    }
    return [result, a / result, b / result];
}

ไม่เร็ว

ใช้การติดต่อกลับเช่นเดียวกับที่ล้มเหลวเป็นพิเศษ

function gcf(a, b) {
    setTimeout(function() {
        var result = 1;
        for (var i = 1; i < 2 * a && i < 2 * b; i++) {
            if (a % i == 0 && b % i == 0) {
                result = i;
            }
        }
        alert(result.toString() + " (" + (a / result).toString() + ", " + (b/result).toString() + ")");
    }, 10000);
}

ไม่ดี

ขีด จำกัด ที่เข้มงวดgcf(10, 10)เพียงเพื่อความปลอดภัยของพื้นที่ดิสก์

function gcf(a, b) {
    var gcfTable = [[1,1,1,1,1,1,1,1,1,1],[1,2,1,2,1,2,1,2,1,2],[1,1,3,1,1,3,1,1,3,1],[1,2,1,4,1,2,1,4,1,2],[1,1,1,1,5,1,1,1,1,5],[1,2,3,2,1,6,1,2,3,2],[1,1,1,1,1,1,7,1,1,1],[1,2,1,4,1,2,1,8,1,2],[1,1,3,1,1,3,1,1,9,1],[1,2,1,2,5,2,1,2,1,10]];
    return [gcfTable[a - 1][b - 1], a / gcfTable[a - 1][b - 1], b / gcfTable[a - 1][b - 1]];
}

เมื่อไหร่ราคาถูกและเร็ว แต่ไม่ดี?
Hovercouch

คำตอบนี้ถูกดี แต่ไม่เร็ว
โพแทสเซียมไอออน

ความท้าทายคือการเขียนโปรแกรมที่แต่ละ "ไม่ถูก", "ไม่เร็ว" และ "ไม่ดี" ในสถานการณ์ต่าง ๆ
Hovercouch

แก้ไขคำตอบแล้ว ...
โพแทสเซียมไอออน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.