Ucuz, Hızlı, İyi - Ortak Faktör (En Büyük) [kapalı]


10

Ucuz, Hızlı, İyi'den esinlenerek , tam olarak iki tane içeren bir algoritma uygulayacağız.

Matematik

İki sıfırdan farklı tamsayılar verilen bir ve b GCF d büyük tamsayı olduğu bölme hem bir ve b kalanı olmadan. Katsayıları Bezout tamsayı çiftleridir (x, y) bu şekilde ax + tarafından d = . Bézout katsayıları benzersiz değildir. Örneğin, verilenler:

a = 15, b = 9

Sahibiz

d =  3
x =  2
y = -3

Beri 15*2 + 9*(-3) = 30 - 27 = 3.

GCF ve bir çift Bézout katsayısını hesaplamanın yaygın bir yolu Öklid Algoritmasını kullanmaktır , ancak bu tek yol değildir.

Kod

Programınız girdi olarak iki tamsayı almalıdır. En büyük ortak faktörü ve bir çift Bézout katsayısını çıkarmalı / döndürmelidir.

Örnek girdi:

15 9

örnek çıktı

3 (2, -3)

Çıktı herhangi bir sırada ve biçimde olabilir, ancak hangisinin GCF ve hangilerinin katsayılar olduğu açık olmalıdır.

Underhanded

Programınızın ucuz, hızlı ve iyi olma potansiyeli vardır. Ne yazık ki, aynı anda sadece iki tane olabilir.

  • Ucuz olmadığında , program aşırı miktarda sistem kaynağı kullanmalıdır.
  • Hızlı olmadığında , program aşırı zaman almalıdır.
  • İyi olmadığında , program çıktısı yanlış olmalıdır.

Program her üçünü de yapabilmelidir (iyi değil). Hangi zaman size kalmış- zamana, derleyiciye, hangi girdinin daha büyük olduğuna vb. Bağlı olabilir. Bazı ek notlar:

  • Programınız açıkça göz ardı edilmemeli ve bir imtiyaz denetiminden geçmelidir. Üç ayrı algoritma uygularsanız biraz şüpheli olurum.
  • Gelen ucuz durumda, "sistem kaynaklarının aşırı miktar" diğer programları yavaşlatabilir olur herşeydir. Bellek, bant genişliği vb. Olabilir.
  • In hızlı durumda, "aşırı süresi", çalışır nasıl göreli anlamına ucuza ve iyi durumlarda. Program hala bitmelidir. "İnanılmaz derecede sinir bozucu ama programı durdurmak için yeterince sinir bozucu değil" daha yakın (daha komik ve) daha iyi.
  • Gelen iyi durumda, çıkış açıkça yanlış olmamalı ve üstünkörü muayene geçmelidir. Bana "2 anna yarısı" GCF verirse çok şüpheli olurdum .

Bu bir popülerlik yarışmasıdır, bu yüzden çoğu upvotes kazanır!

DÜZENLE

Açıklığa kavuşturmak için, "hızlı ve ucuz" ve "ucuz ve iyi" ve "hızlı ve iyi" olabilecek programları arıyorum , bunlardan birini yapanlar değil.


1
Bunun gibi orijinal bir meydan okumaya sahip olmak güzel. :)
Ypnypn

Program aynı anda tam olarak iki mi olmalı yoksa sadece bazı durumlarda iyi, diğerlerinde ucuz ve hızlı (ama iyi değil) ise sorun değil mi?
Dennis

1
Her biri tam olarak iki tane olmak üzere üç dava arıyorum.
Hovercouch

Program iyi değilse çıktısı yanlış mı olmalı? O zaman bir şeyi doğru hesaplamanın anlamı nedir?
Ricardo A

4
Bu soruyu konu dışı olarak kapatmak için oy kullanıyorum çünkü bu, bir yıl önce konuya bağlı olan, ancak şimdi topluluk mutabakatı ile konu dışı olan [yetersiz] bir meydan okuma .
James

Yanıtlar:


2

C

Ucuz ve hızlı. Bir göz açıp kapayıncaya kadar gcd alırsınız. Ancak bunu yapan adam bu "Bézier ortak-şey" hakkında hiçbir ipucu yoktu, bu yüzden sadece a ve b'yi gcd'ye böldü. (işleri daha da kötüleştirmek için, o noktada a ve b akıllıca seçtiği algoritma nedeniyle başlangıç ​​değerlerinden oldukça uzaktır)

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 #

Bu, Bézout katsayılarını hesaplar. Kullandığım Genişletilmiş Öklid algoritması .

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

    }
}

Bu ne zaman pahalı, ne zaman yavaş ve ne zaman kötü?
undergroundmonorail

@ undergroundmonorail Ben şansım olduğunda bu değerleri koyacağım.
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__

Ucuz değil: __ (WARN__ işleyicisi nedeniyle uygulamadan çıkılacak) perl tarafından "derin özyineleme" uyarısı tetikleninceye kadar main () özyinelemeli olarak (yığının doldurulması) çağrılır.

Hızlı değil: gcf () algoritmaları doğru sonuçları döndürdüğünde, kod birkaç saniye bekler (main () içinde () öğesini seçin).

İyi değil: 99'un üzerindeki (-99'un altındaki) tüm sonuçlar yanlış.

Sonuçta çok yaratıcı değil; daha zarif cevaplar bekliyorum.


0

piton

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

Bu ucuz ve hızlıdır ancak aralığın en büyük girdiyle sınırlandırılmış olması kötüdür, bu nedenle bir çift katsayı bulamayabilir.

İyi bulmaca.


0

JavaScript

Ucuz değil

Çok fazla sistem kaynağı kullanır.

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

Hızlı değil

Ekstra arıza güvenliği gibi bir geri arama kullanın.

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

İyi değil

gcf(10, 10)Sadece güvenli disk alanı için katı sınır .

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

Ne zaman ucuz ve hızlı ama iyi değil?
Hovercouch

Bu cevap ucuz, iyi ama hızlı değil.
Potasyum İyon

zorluk, farklı koşullarda "ucuz değil", "hızlı değil" ve "iyi değil" olan bir program yazmaktır.
Hovercouch

Yanıt düzeltildi ...
Potasyum İyon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.