Giá rẻ, nhanh, tốt - Yếu tố chung (lớn nhất) [đã đóng]


10

Lấy cảm hứng từ giá rẻ, nhanh, tốt , chúng tôi sẽ thực hiện một thuật toán có chính xác hai thuật toán.

Toán

Cho hai số nguyên khác ab , GCF d là số nguyên lớn nhất chia cả ab mà không có phần dư. Các hệ số Bézout là các cặp số nguyên (x, y) sao cho ax + by = d . Hệ số Bézout không phải là duy nhất. Ví dụ: đã cho:

a = 15, b = 9

Chúng ta có

d =  3
x =  2
y = -3

Kể từ đó 15*2 + 9*(-3) = 30 - 27 = 3.

Một cách phổ biến để tính toán GCF và một cặp hệ số Bézout là sử dụng Thuật toán của Euclid , nhưng đó không phải là cách duy nhất.

Mật mã

Chương trình của bạn nên lấy hai số nguyên làm đầu vào. Nó sẽ xuất / trả về hệ số chung lớn nhất và một cặp hệ số Bézout.

Ví dụ đầu vào:

15 9

đầu ra ví dụ

3 (2, -3)

Đầu ra có thể theo bất kỳ thứ tự và định dạng nào, nhưng cần phải rõ ràng đó là GCF và hệ số nào.

Đồ lót

Chương trình của bạn có tiềm năng là rẻ, nhanh và tốt. Thật không may, nó chỉ có thể là hai trong số đó cùng một lúc.

  • Khi nó không rẻ , chương trình nên sử dụng quá nhiều tài nguyên hệ thống.
  • Khi nó không nhanh , chương trình sẽ mất quá nhiều thời gian.
  • Khi nó không tốt , đầu ra chương trình sẽ sai.

Chương trình sẽ có thể làm (tốt, không làm) cả ba. Đó là khi nào tùy thuộc vào bạn - nó có thể dựa trên thời gian, trình biên dịch, đầu vào nào lớn hơn, v.v. Một số lưu ý bổ sung:

  • Chương trình của bạn không nên rõ ràng và nên vượt qua một cuộc kiểm tra. Tôi sẽ hơi nghi ngờ nếu bạn thực hiện ba thuật toán riêng biệt.
  • Trong trường hợp giá rẻ , "lượng tài nguyên hệ thống quá mức" là bất cứ điều gì có thể làm chậm các chương trình khác. Nó có thể là bộ nhớ, băng thông, vv
  • Trong trường hợp nhanh , "thời gian quá mức" có nghĩa là liên quan đến cách nó chạy trong các trường hợp rẻtốt . Chương trình vẫn nên kết thúc. Càng gần bạn càng có thể "cực kỳ bực bội nhưng không đủ bực bội để dừng chương trình" (hài hước hơn và) tốt hơn.
  • Trong trường hợp tốt , đầu ra rõ ràng không nên sai và phải vượt qua kiểm tra chữ thảo. Tôi sẽ rất nghi ngờ nếu nó đưa cho tôi một chứng chỉ "2 anna".

Đây là một cuộc thi phổ biến, vì vậy hầu hết các chiến thắng đều thắng!

BIÊN TẬP

Để làm rõ, tôi đang tìm kiếm các chương trình có thể "nhanh và rẻ" "rẻ và tốt" "nhanh và tốt" trong các trường hợp khác nhau, không phải là những chương trình chỉ làm một trong số chúng.


1
Thật tuyệt khi có một thử thách ban đầu như thế này. :)
Ypnypn

Chương trình có phải chính xác hai cùng một lúc hay không nếu nó chỉ tốt trong một số trường hợp và rẻ và nhanh (nhưng không tốt) ở những người khác?
Dennis

1
Tôi đang tìm kiếm ba trường hợp, với chính xác hai trong mỗi trường hợp.
Hovercouch

Nếu chương trình không tốt thì đầu ra có sai không? Vậy thì điểm nào để tính toán chính xác?
Ricardo A

4
Tôi đang bỏ phiếu để đóng câu hỏi này ngoài chủ đề vì đây là một thử thách [ngầm], thuộc chủ đề một năm trước, nhưng bây giờ không có chủ đề bởi sự đồng thuận của cộng đồng .
James

Câu trả lời:


2

C

Nó rẻ và nhanh. Bạn nhận được gcd trong chớp mắt. Tuy nhiên, anh chàng đã làm điều đó không có manh mối về "Bézier co-Something" nên anh ta chỉ đơn giản chia a và b cho gcd. (để làm cho mọi thứ tồi tệ hơn, tại thời điểm đó a và b khá xa so với giá trị ban đầu của chúng vì thuật toán mà anh ấy đã chọn một cách khôn ngoan)

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

C #

Điều này tính toán các hệ số Bézout. Tôi đã sử dụng thuật toán Euclide mở rộng .

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 + ")"));
        }

    }
}

Khi nào thì đắt, khi nào thì chậm và khi nào thì xấu?
ngầmmonorail

@undergroundmonorail Tôi sẽ đặt những giá trị đó khi có cơ hội.
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__

Không rẻ: main () được gọi là đệ quy (điền vào ngăn xếp) cho đến khi cảnh báo "đệ quy sâu" được kích hoạt bởi perl sẽ thoát khỏi ứng dụng do trình xử lý __WARN__.

Không nhanh: Khi thuật toán gcf () trả về kết quả chính xác, mã chỉ bị treo trong vài giây (select () trong hàm main ()).

Không tốt: Tất cả các kết quả trên 99 (hoặc dưới -99) đều không chính xác.

Tất cả trong tất cả không quá sáng tạo; mong chờ câu trả lời thanh lịch hơn.


0

Con trăn

#!/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))

Điều này rẻ và nhanh nhưng thật tệ khi phạm vi được giới hạn ở đầu vào lớn nhất nên có thể không tìm thấy một cặp hệ số.

Câu đố hay.


0

Javascript

Không rẻ

Sử dụng rất nhiều tài nguyên hệ thống.

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

Không nhanh

Sử dụng một cuộc gọi lại, giống như một thất bại thêm.

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

Không tốt

Giới hạn nghiêm ngặt của gcf(10, 10), chỉ để không gian đĩa an toàn.

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

Khi nào thì rẻ và nhanh nhưng không tốt?
Hovercouch

Câu trả lời này là rẻ, tốt, nhưng không nhanh chóng.
Kali Ion

thách thức là viết một chương trình "không rẻ", "không nhanh" và "không tốt" trong các trường hợp khác nhau.
Hovercouch

Trả lời cố định ...
Kali Ion
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.