Wireworldでデジタル時計を作成する


32

このGame of Lifeの質問に触発されました。

Wireworldは、「ワイヤー」を流れる「電子」をシミュレートします。「ワイヤー」の単純な配置は、一般的な論理ゲートの動作を生成します。

Wireworldセルラーオートマトンでデジタル時計を作成するように挑戦します。時計は通常の方法で00:00から23:59まで、またはAM / PMインジケーターで11:59までカウントアップしてからリセットする必要があります。

エントリは目に見えるように2つの部分に分割する必要があります。パートAには、すべての非表示ロジック、数字のインクリメントとループに関与するすべてのパーツが含まれている必要があります。パートBは、ディスプレイとそれを駆動するロジックになります。これらの2つの部分間の唯一の接続は、BCDの 4桁の時間を表す16本のワイヤである必要があります(AM / PMインジケータ用のオプションワイヤ1本と、信号が連続していない場合の信号クロックライン用のオプションワイヤ1本付き)。(編集:常にゼロのワイヤは省略可能)

クロック動作のタイミングは一貫している必要があります。シミュレーションでは、状態間の1440の遷移ごとに同じ数のティックを使用する必要があります。16本のワイヤ上の電子は、パーツAから同時に放出され、並行してトリップを開始する必要があります。

これは、コードとゴルフのコンペティションです。スコアは、パーツAを囲む軸に沿った境界ボックスの領域です。

同様に、これがテキスト言語である場合、スコアは4つの4ビット出力を生成するクロック管理関数のサイズになります。この出力には、ループと4つのカウンターのロジックが含まれ、その出力をデコードおよび印刷する関数ではありません。

パートBは、好きなだけ大きくも小さくもできます。ワイヤーワールド回路からの出力を単純に「デバッグ」する簡単な方法はないため、提出物の出力がそれを実行している誰かに見えるようにするためにのみ必要です。オンラインで利用可能な複数のBCD-> 7セグメント回路があります。好きなものを自由に使用するか、クロック信号線が必要な場合は独自のものを作成し、AM / PMインジケーターを数字と同様のスケールで表示してください。

編集:パートBはオプションになりました。パートAからのBCD出力がある場合は、お気軽に送信してください。クロックが動作することを確認するのは面倒ですが、一時停止したシミュレーションではビットの列を問題なく読み取ることができます。


これは小さなオンラインシミュレータです。
NonlinearFruit

私はこれに取り組んできましたが、先週見ただけなので、おそらく賞金を逃します。wireworld bcd-> 7-segmentの4線バージョンが見つかりません。人気のある2線式7セグメントデバイス(ゴーリーに付属しているデバイスなど)の前に4-to-2コンバーターを構築する方法があります。そのデバイスの問題の1つは、見栄えは良いものの、更新に時間がかかることです。これは、パートAのサイズが大きくなります。
wyldstallyns

私は作品を証明できるというパートAを作業15万セルを持っているが、現在のルールに準拠したパートB.が欠けている
wyldstallyns

パートBが難しいとは思っていませんでした。パートAの電子はどれくらい離れていますか?
スパー16

1
@wyldstallyns 2016年12月16日03:30:35Zに終了します(正確な時間を取得するには、「明日」にカーソルを合わせることができます)。幸運を祈ります。私は本当にあなたの時計が好きです。それはエレガントでシンプルなアイデアと優れた実行です。私はまた、どれだけのスペースが最終的に占めることに驚いたことを認めなければなりません。そして、私はあなたがあなたの中で思いつくことができる改善を見たいです。幸運を祈ります:)
niemiro

回答:


36

ラッチングクロック

スコア-53,508(L字型デザインのために36,828のみが積極的に使用されています)

クロックランニング

高品質の録音 -https :
//1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ Gollyパターン-https : //1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY- IPiBuBmBw

指導原則-

  • セルオートマトンを使用するのはこれが初めてだったので、大きな既製のコンポーネントをつなぎ合わせるのを避けました。私がとらなかった1つの有効なアプローチは、ゼロから始まり、最後の出力に1を連続的に追加するバイナリ加算器であり、その後にバイナリからBCDコンバータ、ディスプレイデマルチプレクサ、7セグメントデコーダ、7セグメントディスプレイが続きます。
  • クロックをコールドスタートすることが可能です。特定の導体セルに配置された単一の電子ヘッドがクロックを正しく開始するという追加の制限を自分に課しました。シミュレーションを開始する前に、多くの異種フリップフロップと個々のタイミング要素を注意深く手動で同期する必要はありませんでした。

パートI:ミニッツカウンター

数学

0から9までのバイナリ(最下位の分桁)のカウントは次のようになります-

0 - 0000
1 - 発明の属する技術分野
2 - 0010
3 - 0011
4 - 0100
5 - 0101
6 - 0110
7 - 0111
8 - 1000
9 - 1001

列として読むと、最下位(2 ^ 0ユニットのビットストリーム)は01010101、2 ^ 1ユニットのストリームは0011001100、2 ^ 2ユニットのストリームは0000111100、2 ^ 3ユニットのストリームは0000000011になります。

最初のものは簡単-永遠に01をフリップフリップするだけです。3番目は4つの1、6つの0、6つのゼロで位相シフトされたストリームです。4番目は、8つの0と2つの1のストリームです。

2つ目は、やや非対称なので、少し難しくなります。しかし、私はそれに気付きます(ここで。は連結演算子です):

0011001100 0011001100 = 0011001100 NOT(1100110011)= 00110011001100110011 XOR 00000000001111111111 = 5(0011)XOR 00000000001111111111

(ちなみに、後で言及したように、私のクロックの大部分は60ビートのティッカーで実行されます。00000000001111111111の2倍の長さのウェーブは、120ビートのティッカーの必要性が生じます)。

設計

出力は、上から下に向かって、分単位(2 ^ 0、2 ^ 1、2 ^ 2、2 ^ 3)、次に数十分(2 ^ 0、2 ^ 2、2 ^ 1)に流れます。下の2本のワイヤが交差していることに注意してください。

注釈付きの分カウンター

  1. 120ビートのメインクロック。
  2. コールドスタートのための電子の配置場所。電子テールがない場合、2つの方向に分割されますが、すぐ上のダイオードがこれらの1つをキャッチし、120ビートループを回って周回する素晴らしい循環電子を与えます。
  3. 12ビートのセカンダリクロック。
  4. 導体+ダイオードのコイルは、セカンダリ12ビートクロックを開始します。この小さな断片がどれほど厄介に同期するのか、言葉では説明できません。120ビートクロックと60ビートクロックを同期してから、12ビートと周波数半分の24ビート擬似クロックを同期し、24ビートクロックを120ビートクロックに戻す必要があります。そうしないと、XORゲートが機能しません。 。
  5. 位相シフト。
  6. フリップ・フロップ。入力の1つの電子が最初にセットラインにヒットし、非常に特定の時間後にリセットラインにヒットして、正確に1つのパルスを入力し、1つのパルスを出力します。
  7. ここにハンプを追加します-リセットラインで、フリップフロップのセットとリセットの間の遅延を増やします。追加のハンプごとにパルスが追加されます。以下のフリップフロップには9つの余分なこぶがあるため、セットとリセットの間で10パルスです。
  8. トリッキーな2 ^ 1分の分の行のXORゲート。
  9. AND-NOTゲートと非常に特殊な部分長とは、通過する各電子パルスが二重に戻り、背後の電子を消滅させることを意味します。周波数の半分。12ビートのセカンダリソースから24ビートのクロックを作成します。
  10. 実際にはほとんどの作業を行う60ビートのセカンダリクロック。遅いクロックから速いクロックを開始する方が簡単なので、ほとんど使用されていなくても、最も遅いクロック(120ビート)がマスターになります。60ビートクロックがこのことの中心です。
  11. 60ビートクロックがカチカチ音をたてるときにのみ電子を運ぶフィードバックワイヤ。AND-NOTゲートと組み合わせて使用​​し、120ビートマスターから繰り返し再起動されるクロックを停止します。そうでなければ多くの恐ろしいことが起こり、Ctrl-Zは救い主です。
  12. 60ビートクロックが開始されるダイオード。
  13. このデバイス全体は、フリップフロップ、ANDゲート、およびAND-NOTゲートを組み合わせたものです。ラッチを提供します。1パルスで開始し、1パルスで停止します。
  14. 10パルス中1パルスでラッチを10パルスオン、10パルスオフに調整するワイヤのループ。これがないと、12パルスがオンになり、8パルスがオフになります。これらの10オン10オフラッチは、6ミクロン(1パルス)フリップフロップが分単位の基本コンポーネントを形成したのと同様に、10分ブロックの基本コンポーネントを形成します。
  15. コールドスタートの初期パルスは、開始するクロックと位相が2ビートずれているなど、あらゆる種類の問題を引き起こしました。これはラッチを台無しにします。このANDゲートは、同期パルス(特に開始パルス)をキャッチして破棄します。
  16. これは、振り返って少し後悔しているデザインの一部です。それは電子を取り、それを5つに分割し、背後の5つの電子を消滅させ、111111から100000を取ります。
  17. これは電子を受け取り、前面に縫い付けます。正確には2段階先です。100000で101000になります。パート16と組み合わせると、111111-> 100000-> 101000になります。少ないスペースで同じ効果を達成できたでしょう。
  18. 次に、上記のパターンを下部ラッチに押し込み、20オン、40オフを実現します。これは分割され、半分は20単位で位相シフトされ、これらは数十分の2つの上位ビットストリームを形成します。

パートII:時間カウンター

説明

時間カウンターへの入力は、1時間に1回、単一の電子パルスです。最初のステップは、12時間ごとに1回、これを単一の電子パルスに減らすことです。これは、いくつかの「ラッチ&キャッチ」プリミティブを使用して実現されます。

「ラッチ」は、6ミクロンのオン/オフラッチを与えるために、AND-NOTおよびANDゲートに接続された6ミクロンのフリップフロップです。「キャッチ」は、入力として連続した電子の流れを取り、最初の通過を許可し、キャッチがリセットされる時点で流れが終了するまで、背後にある他のすべての電子を消滅させます。

ラッチを配置し、続いてキャッチを連続して配置すると、1つの電子が入力され、ラッチがオンになり、1つの電子がもう一方の端から出力されます(残りはキャッチに捕捉されます)。次に、2番目のエレクトロン->ラッチをオフにし、サイレントリセットをキャッチします。正味効果:それらの電子間の遅延の長さ関係なく、最初の電子が通過し、2番目の電子が消滅するなど。

ここで、2つの「ラッチ&キャッチ」を連続してチェーンすると、4つの電子のうち1つだけが通過します。

次に、3回目の「ラッチアンドキャッチ」を行いますが、今回は、4回目のラッチとキャッチをすべて、フリップフロップSETラインのAND-NOTゲートとフリップフロップSETの間に埋め込みます。これがどのように機能するかを考えさせていただきますが、今回はそれらの電子間の遅延の長さ関係なく、3つの電子のうち1つだけが通過します。

最後に、4つの電子のうちの1つと3つの電子のうちの1つをANDゲートで結合すると、12の電子のうち1つだけが通過します。このセクション全体は、下の時間カウンタの左上へのパスの乱雑な波線です。

次に、12時間ごとに電子を取り、1時間ごとに1つに戻しますが、それぞれを異なる導線に出力します。これは、13の出口点を持つ長いコイル状の導体を使用して実現されます。

これらの電子を取ります-1時間に1本の異なる導体を下って、フリップフロップSETラインにヒットします。次に、同じフリップフロップのRESETラインに次の1時間のコンダクタがヒットし、各ワイヤに1時間あたり60パルスを送ります。

最後に-これらのパルスを取得し、7バイト半のROM(読み取り専用メモリ)に渡して、正しいBCDビットストリームを出力します。WireWorld ROMの詳細については、こちらをご覧ください。ご覧ください http

設計

注釈付きの時間カウンター

  1. 1時間あたり1つの電子。
  2. 最初のラッチ。
  3. 最初のキャッチ。
  4. 外側の「ラッチ&キャッチ」SET行に埋め込まれた「ラッチ&キャッチ」。
  5. ANDゲート。
  6. AM / PMラッチ(12時間ごとにオン/オフになります)。
  7. ワイヤの各ループは6x60 = 360ユニットの長さです。
  8. フリップ/フロップは側面をオンにして、より小さなプロファイルを作成しました。
  9. 7バイト半のROM。

ノート

  1. 1分間に1電子、6ミクロンの設計により、リアルタイムクロックに対して1分間に6世代(10秒ごとに1世代)でシミュレーションを実行します。
  2. AM / PMラインは、AMの場合は高(1)、PMの場合は低(0)です。これは少し変わった方法で選択するように見えるかもしれませんが、正当化があります。クロックのコールドスタート中、AM / PMラインは最初は自然に低い(0)です。AM / PMラインがハイ(1)になるとすぐに、カウントが午前12:00に開始されたことを示します。このポイントより前のすべての出力は無視する必要があり、このポイントより後のすべての出力は意味があると見なされます。

便利なリンク


常にゼロの出力を省略できるように要件を変更しました。数十時間の4秒と8秒のビットは使用されず、数十分の8秒のビットも使用されません。
スパー16

固体!真のエンジニアリング。他の論理ゲートのいずれかが有用でしたか?私はいくつかをブルートフォースしようとしています。
wyldstallyns 16

1
これは美しいです
スパー

1
だああ良い悲しみだけで十分に近い今、私は試してみて、最適化の鉱山を強要しています。私はパターンを繰り返してきた私は他人を折るための余地を作るために短縮することができます。
wyldstallyns

3
あなたがメタでどれだけ活発に活動しているのかわかりませんので、これは私がこの答えをBest of PPCG 2016にノミネートしたことを知らせるためです。
ピーターテイラー

5

遅延ラインメモリ-51 x 2880 = 146880

画像

ズームアウト:

画像

出力は各ループの上部から出ます。

このluaを使用して、すべての状態を直接ワイヤに配置して、 gollyビット間で電子を前進さ、ワイヤでカーソルをたどる必要がないようにします。

この素朴な方法を使用して、バーを設定し、ワイヤーワールド、ゴーリー、およびルアをクラッシュさせました。

local g = golly()

local minutes_in_day = 1440 -- 60x24
local interval = 4 -- how often to send electrons

local function bcd4(num)
    num=math.floor(num)
    local t={}
    for b=4,1,-1 do
        t[b]=math.floor(math.fmod(num,2))
        num=(num-t[b])/2
    end
    return table.concat(t)
end

local function makewire(x,y1,y2)
    for y1=1,y2 do g.setcell(x,y1,3) end
end

local function makeloop(x,y,size)
    local len = size/2 - 1
    makewire(x,y+1,len); makewire(x+2,y+1,len) -- main wires
    g.setcell(x+1,y,3); g.setcell(x+1,y+len,3) -- endcape
end

local function paint(x,y,pattern)
    for v in string.gmatch(pattern,".") do
        if v=="1" then g.setcell(x, y, 1); g.setcell(x, y-1, 2) end
        x = x + 4
    end
    g.show(pattern);g.update() -- slows things down but more interesting to watch
    for i=1,interval do g.step() end
end

for x=0,63,4 do makeloop(x,0,minutes_in_day * interval) end

for hour = 0,23 do
      for minute = 0,59 do
         paint( 0, 2, bcd4(hour/10) .. bcd4(hour%10) .. bcd4(minute/10) .. bcd4(minute%10) )
      end
end

テストのために、これらの上部ワイヤを追加し、それらのヒントを見ました。

イグル

これは、4組の4ワイヤーBCDを眼球に収集するスクリプトです。

-- watches 16 wires spaced 4 apart starting at (0,-4)
local ticks = 1440 -- set to match the length of your 24 hour loop
local g = golly()
local output = ""
local nums = {  ["0000"] = "0", ["0001"] = "1", ["0010"] = "2", ["0011"] = "3", ["0100"] = "4",
                ["0101"] = "5", ["0110"] = "6", ["0111"] = "7", ["1000"] = "8", ["1001"] = "9",
                ["1010"] = "A", ["1011"] = "B", ["1100"] = "C", ["1101"] = "D", ["1110"] = "E",
                ["1111"] = "F" } -- full set in case we have errors (i did)

for i=0,ticks,1 do
   local text = ""
   for i=0,48,16 do -- set your X here, change the 0 and 48
       local word = ""
       for j=0,15,4 do
            local bit = g.getcell(i+j,-4) -- set your Y here, change -4
            if bit == 0 or bit == 3 then word = word .. "0" else word = word .. "1" end
       end
       text = text .. nums[word]
   end
   g.show(text); output = output..' '..text
   g.update(); g.step();g.step();g.step();g.step()
end
g.note(output)

最終的な回答では、常にゼロの行を整理し、残りを正しいBCD入力にルーティングする必要があります。


常にゼロの出力を省略できるように要件を変更しました。数十時間の4と8のビットは使用されず、数十分の8のビットも使用されません。
スパー16

2
これは陽気で素晴らしい実装です!
スパー16

1
わかりました。11時間目に別の機能的な時計でwithられました。さまざまなトリックで最長と最短のループを攻撃します。
wyldstallyns

私はそれをやってのけるつもりはありません。3ミクロンパルスに切り替えることでサイズの1/4を節約できますが、それでもniemiroに勝るほどタイトにコイル状にはなりません。
wyldstallyns
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.