Дешево, Быстро, Хорошо - Общий Фактор (Величайший) [закрыто]


10

Вдохновленные Дешево, Быстро, Хорошо , мы собираемся реализовать алгоритм, который имеет ровно два из них.

Математика

Учитывая два ненулевых целых числа a и b , GCF d является наибольшим целым числом, которое делит и a и b без остатка. Коэффициенты Безу - это пары целых чисел (x, y) , для которых ax + by = d . Коэффициенты Безу не являются уникальными. Например, учитывая:

a = 15, b = 9

У нас есть

d =  3
x =  2
y = -3

Так как 15*2 + 9*(-3) = 30 - 27 = 3.

Распространенным способом вычисления GCF и пары коэффициентов Безу является использование алгоритма Евклида , но это ни в коем случае не единственный способ.

Код

Ваша программа должна принимать два целых числа в качестве входных данных. Он должен выводить / возвращать наибольший общий коэффициент и одну пару коэффициентов Безу.

Пример ввода:

15 9

пример вывода

3 (2, -3)

Выходные данные могут быть в любом порядке и формате, но должно быть ясно, что является GCF, а какие - коэффициентами.

Закулисный

Ваша программа может быть дешевой, быстрой и хорошей. К сожалению, это может быть только два из них одновременно.

  • Когда это не дешево , программа должна использовать чрезмерное количество системных ресурсов.
  • Когда это не быстро , программа должна занять слишком много времени.
  • Когда это не хорошо , вывод программы должен быть неправильным.

Программа должна уметь делать (ну, не делать) все три. Что делает, когда зависит от вас - это может быть основано на времени, компиляторе, какой ввод больше и т. Д. Некоторые дополнительные примечания:

  • Ваша программа не должна быть явно закулисной и должна пройти беглый осмотр. Я был бы немного подозрительным, если бы вы реализовали три отдельных алгоритма.
  • В дешевом случае «чрезмерное количество системных ресурсов» - это все, что может замедлить работу других программ. Это может быть память, пропускная способность и т. Д.
  • В быстром случае «чрезмерное время» означает, как оно работает в дешевых и хороших случаях. Программа еще должна закончиться. Чем ближе вы можете к «невероятно разочаровывающему, но недостаточно разочаровывающему, чтобы остановить программу», тем (смешнее и лучше).
  • В хорошем случае вывод не должен быть явно неправильным и должен пройти краткий осмотр. Я был бы очень подозрительно, если бы это дало мне GCF "2 анна половина".

Это конкурс популярности, поэтому большинство побед выигрывает!

РЕДАКТИРОВАТЬ

Чтобы уточнить, я ищу для программ , которые могут быть «быстро и дешево» и «дешево и хорошо» и «быстро и хорошо» в различных случаях, а не те , которые просто делают одну из них.


1
Приятно иметь такой оригинальный вызов. :)
Ypnypn

Должна ли программа быть ровно двумя одновременно или это нормально, если она хороша только в одних случаях и дешева и быстра (но не хороша) в других?
Деннис

1
Я ищу три случая, по два в каждом.
Hovercouch

Если программа плохая, ее вывод должен быть неправильным? Тогда какой смысл вычислять что-нибудь правильно?
Рикардо А

4
Я голосую, чтобы закрыть этот вопрос как не по теме, потому что это [закулисный] вызов, который был по теме год назад, но теперь не по теме по общему мнению сообщества .
Джеймс

Ответы:


2

С

Это дешево и быстро. Вы получаете 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 #

Это вычисляет коэффициенты Безу. Я использовал расширенный евклидов алгоритм .

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 Я поставлю эти значения, когда у меня будет такая возможность.
Бура Чухадар

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

Javascript

Не дешево

Использует много системных ресурсов.

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

Ответ исправлен ...
Ион калия
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.