2つのカウンターマシン上のCollat​​zシーケンス


8

このCollat​​zシーケンス正の整数nから開始し、このように定義されています。

  • nが偶数の場合は、2で割ります(n' = n / 2
  • nが奇数の場合は、3を掛けて1を加えます(n' = 3n + 1

nが1に達するまで上記の反復を繰り返します。

最初に選択された正の整数に関係なく、シーケンスが最終的に数値1に到達するかどうかは不明です(これは数値理論では未解決の主要な問題です)。

A 2つの逆マシン(2CM)非負の整数値を保持することができ、次の命令セットを用いてプログラムすることができる2つのレジスタを備えたマシンです。

INCX    increase the value of register X
INCY    increase the value of register Y
JMP n   jump to instruction n
DJZX n  if register X is zero jump to instruction n,
        otherwise decrement its value
DJZY n  if register Y is zero jump to instruction n,
        otherwise decrement its value
HALT    halt (and accept)
PRINTX  print the content of register X

2CMプログラムは、単に一連の命令です。たとえば、次のプログラムは、レジスタXの内容をレジスタYにコピーするだけです。

cp:   DJZX end
      INCY
      JMP cp
end:  HALT

2CMは完全なチューリングであることに注意してください(つまり、適切な入力エンコーディングですべての計算可能な関数を計算できますが、ここでは関係ありません)。また、命令セットはウィキペディアの記事にあるものとは少し異なることに注意してください。

チャレンジ

collat​​zシーケンスを1まで計算して出力し、停止する最も短い2CMプログラムを作成します(レジスタXには最初に開始値が含まれ、nレジスタYには最初に0が含まれます)。2CMプログラムの長さは、使用される命令の数であることに注意してください(テキストの長さではありません)。

たとえば、X = 3から開始した場合は、次を出力する必要があります:3 10 5 16 8 4 2 1およびHALT。

したがって、お気に入りの言語を使用して2CMシミュレータ/インタプリタを構築できますが、回答に入れる最終(最短)コードは2CM言語である必要があります


2CMマシン用にどのようなプログラムを作成しますか?
FUZxxl 2015

プログラムはHALTで終了する必要がありますか、それとも実行を最後から終了させることもできますか?
orlp 2015


1
@ LegionMammal978コードサイズは関係ありません。
FUZxxl 2015

3
@MarzioDeBiasiこれらすべてのコメントを見て、サンドボックスを推奨させてください(少なくとも次の課題では)。明確な課題を書くことは難しく、すべてを整理したと思っていても、他のユーザーに未解決の質問がよくあります。サンドボックスで指摘したり、メインにチャレンジを投稿したり、人々が作業を開始する前に対応したりできます。それ。
マーティンエンダー2015

回答:


11

18の指示

問題のミニマルな性質と言語がそこに(一見)良い答えのための1つの一般的なアプローチしか作らないので、私が現場に遅れて到着したことには少しがっかりしました。私は19命令の回答をすぐに受け取りましたが、それを投稿するのに十分なものだとは感じませんでした。しかし、頭をひっかいた後、ハッキーなz80アセンブリ体験が実現し、コードブロックを本来の目的以外に再利用して命令を保存する方法を見つけました。

# Let N be the previous number in the Collatz sequence.

# Print N, and if N==1, halt.
# X=N, Y=0
Main:           PRINTX          # Print N.
                DJZX Done       # X=N-1 (N shouldn't be zero, so this never jumps)
                DJZX Done       # If N-1==0, halt. Otherwise, X=N-2.

# Find the parity of N and jump to the proper code to generate the next N.
# X=N-2, Y=0
FindParity:     INCY
                DJZX EvenNext   # If N%2==0, go to EvenNext with X=0, Y=N-1.
                INCY
                DJZX OddNext    # If N%2==1, go to OddNext with X=0, Y=N-1.
                JMP FindParity

# Find the next N, given that the previous N is even.
# X=0, Y=N-1
EvenNext:       INCX
                DJZY Main       # Y=Y-1 (Y should be odd, so this never jumps)
                DJZY Main       # If Y==0, go to Main with X=(Y+1)/2=N/2, Y=0.
                JMP EvenNext

# Find the next N, given that the previous N is odd.
# X=0, Y=N-1
OddNext:        INCX
                INCX
                INCX
                DJZY EvenNext   # If Y==0, go to EvenNext with X=(Y+1)*3=N*3, Y=0.
                JMP OddNext     # ^ Abuses EvenNext to do the final INCX so X=N*3+1.

# Halt.
Done:           HALT

1
私の通訳が悪くないことを願っています:Pいい解決策。
orlp 2015

1
@orlp魅力のように働きました。ありがとう。:)
Runer112 2015

1
私はあなたの解決策が本当に好きです!EvenNextの非常に素晴らしい乱用:)
Nejc

4

スコア:21

これが私の試みです:

main:印刷Xしてジャンプしますfinish(ifの場合X==1)。

divisibilityX%2==0またはの場合、区別しX%2==1ます。またにコピーXYて作りX==0ます。isDivisible(if X%2==0)またはisNotDivisible(if X%2==1)のいずれかにジャンプします。

isDivisible:ときに使用されるループY%2==0Y2 ずつ減少するごとに1ずつ増加Xします。の場合Y==0、にジャンプしmainます。

isNotDivisible:ときに使用されY%2==1ます。X1 ずつ増加します。

notDivLoop:ときに使用されるループY%2==1。1減少するごとに3 Y増加Xします。の場合Y==0、にジャンプしmainます。

finish:停止

main:           PRINTX              # print X
                DJZX main           # here X is always >0 and jump never fires (it is just for decreasing)
                DJZX finish         # if initially X==1 this jumps to finish
                INCX                # establish the previous state of X
                INCX
                                    # continue with X>1

divisibility:   DJZX isDivisible    # if X%2==0, then this will fire (when jumping Y=X)
                INCY
                DJZX isNotDivisible # if X%2==1, this fires (when jumping Y=X)
                INCY
                JMP divisibility    # jump to the beginning of loop

isDivisible:    DJZY main           # this jumps to the main loop with X=X/2
                DJZY main           # this jump will never fire, because X%2==0
                INCX                # for every partition 2 of Y, increase X (making X=Y/2)
                JMP isDivisible     # jump to beginning of loop

isNotDivisible: INCX                # X=0, increase for 1
notDivLoop:     DJZY main           # in each iteration, increase X for 3 (when Y==0, X=3Y+1)
                INCX
                INCX
                INCX
                JMP notDivLoop      # jump to beginning of loop

finish:         HALT                # finally halt

(@orlpによって提供されるインタープリターを使用して)3が提供されると、生成される結果は次のようになります。

3
10 
5 
16 
8
4
2
1

4

19指示

私はそういうのが好きだから自分で通訳を書きました。ここに私自身の通訳のための私の解決策があります:

MP
 XE
 XE
HY
 XV
 XO
 JH
WX
VYM
 JW
LYM
 X
 X
OX
 X
 X
 X
 JL
EH

そして、これは他のインタプリタと互換性のある構文でどのように見えるかです:

# x = n, y = 0
main:    printx
         djzx   end
         djzx   end

# x = n - 2, y = 0 on fallthrough
half:    incy
         djzx   even
         djzx   odd
         jmp    half

evloop:  incx
# x = 0, y = n / 2  on jump to even
even:    djzy   main
         jmp    evloop

oddloop: djzy   main
         incx
         incx
# x = 0, y = (n + 1) / 2 on jump to even
odd:     incx
         incx
         incx
         incx
         jmp    oddloop

end:     halt

同じ解決策が見つかったようですが、以前は:(
orlp

@orlp起こります。
FUZxxl 2015

3

19指示

found:    PRINTX       # print input/found number
          DJZX done    # check if n == 1
          DJZX done    # after this point x == n - 2
parity:   INCY         # after this loop y == n // 2
          DJZX even
          DJZX odd
          JMP parity
odd-loop: DJZY found
          INCX
          INCX
odd:      INCX         # we enter mid-way to compute x = 6y + 4 = 3n + 1
          INCX
          INCX
          INCX
          JMP odd-loop
even:     DJZY found   # simply set x = y
          INCX
          JMP even
done:     HALT

私の通訳を使用しそれを実行できます。



@FUZxxlそれは私があなたに1時間前に言ったことです:P
orlp

はい、そうでした。他の人が平等を理解できるように私はこれを書きました。
FUZxxl 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.