challenge 最大公約数(除算禁止)

あなたが使っている言語で除算と剰余が使えなくなりました。

以下の条件のもと最大公約数を求めるプログラムを書いてください。

条件

  • 除算および剰余の使用禁止
  • 加算や乗算から除算・剰余を単純に定義することも禁止とする
  • ただし, ビットシフトが面倒な場合には引数を2で割った商を返す関数を実装しても構わない
  • 多倍長演算をサポートすること(各言語のライブラリ状況を見たいので)
  • 引数は2つの正整数と仮定して構わない
  • F_1=1, F_2=1のフィボナッチ数列で2000番目と1999番目の最大公約数を求めたときのループ回数を教えてください

Posted feedbacks - Smalltalk

Squeak Smalltalk で。

通常は無限倍精度整数に対応した #gcd: を使います。ちなみに、無限倍精度向けの Integer>>#gcd: および SmallInteger>>#gcd: に細工(グローバル変数 COUNT を用意して各々のループ内に COUNT := COUNT + 1 を挿入)をしてカウントをしてみたところ、fib1999 gcd: fib2000 では 1127 でした。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| gcdNoDiv gcdNoDivCount fibMemo fib fib1999 fib2000 |
gcdNoDiv := [:pair |
    [(pair sort; first) = pair second or: [pair last = 1]]
        whileFalse: [pair at: 2 incrementBy: pair first negated].
    pair last].

gcdNoDivCount := [:pair |
    | count |
    count := 0.
    [(pair sort; first) = pair second or: [pair last = 1]] whileFalse: [
        count := count + 1.
        pair at: 2 incrementBy: pair first negated].
    count].

fibMemo := Dictionary new.
fib := [:nth |
    fibMemo at: nth ifAbsentPut: [
        nth < 3 ifTrue: [1] ifFalse: [
            (fib copy fixTemps value: nth-1) + (fib copy fixTemps value: nth-2)]]].
fib1999 := fib copy fixTemps value: 1999.
fib2000 := fib copy fixTemps value: 2000.

fib1999 gcd: fib2000.   "=> 1 "  " 組み込みの GCD "
gcdNoDiv value: {fib1999. fib2000}.   "=> 1 "
gcdNoDivCount value: {fib1999. fib2000}.   "=> 1998 "

Index

Feed

Other

Link

Pathtraq

loading...