便宜,快速,良好-共同因素(最大)[关闭]


10

Cheap,Fast,Good的启发,我们将要实现一个算法,其中恰好有两个。

数学

给定两个非零整数ab,GCF d是将ab均除而无余的最大整数。贝索特系数是整数对(x,y),因此ax + by = d。贝索特系数不是唯一的。例如,给定:

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 half”,我会非常怀疑。

这是一次人气竞赛,因此大多数投票都获胜!

编辑

为了明确起见,我正在寻找在不同情况下可以“快速又便宜” “便宜又好” “快速又好”的程序,而不是仅执行其中之一的程序。


1
遇到这样的原始挑战真是太好了。:)
Ypnypn

该程序是否必须一次恰好是两个,还是在某些情况下很好而又便宜又快速(但不好)的话就可以了吗?
丹尼斯

1
我正在寻找三个案例,每个案例中只有两个。
Hovercouch 2014年

如果程序不好,它的输出应该不正确吗?那么正确计算任何东西的意义是什么?
里卡多A

4
我投票结束这个问题是因为脱离话题,因为这是一个[不足的]挑战,一年前就已经成为话题,但是现在已经被社区共识变成了话题。
詹姆斯

Answers:


2

C

它既便宜又快速。一眨眼,您就会得到gcd。但是,做这件事的那个家伙对“贝塞尔共舞”一无所知,因此他只是将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

C#

这将计算Bézout系数。我使用了扩展欧几里得算法

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,如果有机会,我会把这些值放进去。
Bura Chuhadar 2014年

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()算法返回正确的结果时,代码仅会挂起几秒钟(main()中的select())。

不好:所有高于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

Java脚本

不便宜

占用大量系统资源。

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 2014年

这个答案很便宜,很好,但是不快。
钾离子

面临的挑战是编写一个在不同情况下分别“不便宜”,“不快速”和“不好”的程序。
Hovercouch

已解决问题的答案
钾离子
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.