Дешево, швидко, добре - загальний фактор (найбільший) [закрито]


10

Натхнені дешевими, швидкими, хорошими , ми збираємось реалізувати алгоритм, який має їх рівно два.

Математика

З огляду на два ненулі цілі числа a і b , GCF d є найбільшим цілим числом, яке ділить і a, і b без залишку. Коефіцієнти Безу - пари цілих чисел (x, y), такі, що ax + по = 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-х півріччя".

Це змагання за популярність, тому більшість результатів виграє!

EDIT

Для уточнення я шукаю програми, які можуть бути "швидкими і дешевими" і "дешевими і хорошими" і "швидкими і хорошими" в різних випадках, а не тих, які просто роблять одну з них.


1
Приємно мати оригінальний подібний виклик. :)
Ypnypn

Чи має програма бути рівно двома одночасно або це добре, якщо вона лише в деяких випадках хороша, а в інших дешева і швидка (але не хороша)?
Денніс

1
Я шукаю три випадки, рівно по два в кожному.
Говеркуч

Якщо програма непогана, її вихід повинен бути невірним? Тоді який сенс обчислити що-небудь правильно?
Рікардо

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 () повертають правильні результати, код просто зависає на кілька секунд (виберіть () у 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]];
}

Коли це дешево і швидко, але не добре?
Говеркуч

Ця відповідь дешева, хороша, але не швидка.
Калій Іон

завдання полягає в тому, щоб написати програму, яка в різних обставинах не є "дешевою", "не швидкою" та "непоганою".
Говеркуч

Відповідь фіксовано ...
Калій Іон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.