在Wireworld中建立数字时钟


32

受到“人生游戏”问题的启发。

Wireworld模拟流经“电线”的“电子”,其简单排列会产生典型的逻辑门行为。

我挑战您在Wireworld蜂窝自动机中构建数字时钟。您的时钟必须以通常的方式从00:00向上计数,或者使用AM / PM指示器从11:59向上计数,然后重设。

您的输入应明显分为两部分。A部分应包含所有非显示逻辑,所有涉及数字递增和循环的部分。B部分将是显示器及其驱动逻辑。这两个部分之间的唯一连接应该是代表BCD中时间的四位数字的16根电线(如果信号不连续,则AM / PM指示器的一根可选电线,信号时钟线的一根可选电线)。(编辑:总为零的导线可以省略)

时钟行为的时序应保持一致。对于状态之间的1440个过渡中的每个过渡,模拟应采用相同的滴答数。16条导线上的任何电子都应同时从A部分发出,并开始平行跳闸。

这是一场代码高尔夫比赛。您的分数是围绕零件A的轴对齐边界框的面积。

类似地,如果这是文本语言,则您的得分将是产生四个4位输出的时钟管理功能的大小,该输出包含一个循环和4个计数器的逻辑,而不是解码和打印该输出的功能。

B部分的大小可以根据需要选择。这样做只是为了使提交的输出可以被运行它的人看到,因为没有简单的方法可以简单地“调试” wireworld电路的输出。在线有多个BCD-> 7段电路。随意使用任意一个,如果需要时钟信号线,则可以自己制作,并以类似于数字的比例显示AM / PM指示器。

编辑:B部分现在是可选的。如果您只有A部分的BCD输出,请随时提交。确认时钟正常工作将更加繁琐,但是我可以在暂停的模拟中读取一行位。


是一个小型的在线模拟器。
NonlinearFruit

我一直在努力,但上周才看到它,所以我可能会错过赏金。我找不到wireworld bcd-> 7段的4线版本;在流行的2线制7段设备(例如随同golly附带的设备)之前构建4对2转换器可能是可行的方法。该设备的一个问题是,尽管它看上去很漂亮,但是更新速度很慢,这会膨胀A部分的大小,因为它可以更快地输出数字,而数字显示的速度却必须人为地降低。
wyldstallyns

我有一个15万单元工作的A部分,我可以证明它可以工作,但目前缺少符合规则的B部分
。– wyldstallyns

我没想到B部分会很困难。您的电子在A部分中相距多远?
Sparr

1
@wyldstallyns它于16/12/2016 03:30:35Z关闭(您可以将鼠标悬停在“明天”上以获取准确的时间)。祝您好运。我真的很喜欢你的时钟。这是一个优雅而简单的想法,并且执行出色。我必须承认,我对最终占用了多少空间感到惊讶。而且,我很想看到您可以提出的任何改进。所以,祝你好运:)
niemiro

Answers:


36

锁存时钟

得分-53,508(由于采用L型设计,因此仅有效使用了36,828)

时钟运行

高质量录制 -https :
//1drv.ms/u/s!ArQEzxH5nQLKhvt_HHfcqQKo2FODLQ Golly模式-https : //1drv.ms/u/s!ArQEzxH5nQLKhvwAmwCY- IPiBuBmBw

指导原则 -

  • 由于这是我第一次使用蜂窝自动机,因此避免了将大型预制部件串在一起。我没有采用的一种有效方法是二进制加法器从零开始,并连续将一个加法器添加到最后一个输出,然后是二进制到BCD转换器,显示解复用器,7段解码器和7段显示。
  • 应该可以冷启动时钟。我对自己施加了额外的限制,即放置在特定导体单元上的单个电子头应正确启动时钟。在开始模拟之前,我不想要求许多完全不同的触发器和各个定时元件进行仔细的手动同步。

第一部分:分钟计数器

数学

从0到9的二进制计数(对于最低有效分钟数)如下:

0 - 0000
1 - 0001
2 - 0010
3 - 0011
4 - 0100
5 - 0101
6 - 0110
7 - 0111
8 - 1000
10 - 1001

读取为最低有效位(2 ^ 0个单位的位流)的列为01010101,2 ^ 1个单位的流为0011001100,2 ^ 2个单位的流为0000111100,2 ^ 3个单位的流为0000000011。

第一个很简单-永远翻转01。第三个是四个1,六个0,相移六个零的流。第四个是八个0和两个1的流。

第二个要难一点,因为它有一个令人讨厌的不对称性。但是,我注意到(其中。是concat运算符):

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

(顺便提一下,如稍后所提到的,我的大部分时钟都在60拍的行情上运行。00000000001111111111双倍长波是出现120拍的行情的地方)。

设计

输出流从上到下依次为分钟单位(2 ^ 0,2 ^ 1,2 ^ 2,2 ^ 3),然后是十分钟(2 ^ 0,2 ^ 2,2 ^ 1)。请注意,底部的两条线交叉。

分钟计数器注释

  1. 120拍主时钟。
  2. 在何处放置电子以进行冷启动。它没有任何电子尾巴,它在两个方向上分裂,但紧邻上方的二极管抓住了其中一个,从而产生了一个很好的循环电子,并绕过了120拍的环路。
  3. 12拍次时钟。
  4. 导体+二极管线圈启动次级12拍时钟。言语无法形容这个小片段的同步程度。您必须先同步120和60拍的时钟,然后同步12拍和频率减半的24拍的伪时钟,然后将24拍的时钟重新绑回120拍的时钟,否则XOR门将不起作用。
  5. 相移。
  6. 拖鞋。输入上的单个电子首先击中设定线,然后在非常特定的时间后击中复位线,从而精确给出一个脉冲输入,一个脉冲输出。
  7. 在这里加峰-在复位线上,增加了触发器在设置和复位之间的延迟。每个额外的驼峰都会产生一个额外的脉冲。下面的触发器有九个额外的驼峰,因此在置位和复位之间有十个脉冲。
  8. 我棘手的分钟线2 ^ 1单位的XOR门。
  9. AND-NOT门和非常特定的部件长度意味着经过的每个电子脉冲都会自身加倍并消灭后面的电子。频率减半。从12拍次音源创建24拍时钟。
  10. 60拍次时钟,实际上完成了大部分工作。从较慢的时钟开始快速时钟比较容易,因此最慢的时钟(120拍)是主要时钟,即使它几乎没有使用过。60拍时钟是这件事的核心。
  11. 仅当60拍时钟滴答滴答时才传送电子的反馈线。它与AND-NOT门结合使用,以阻止时钟从120拍主设备重复启动。否则,会发生许多可怕的事情,并且Ctrl-Z是救星。
  12. 起始60拍时钟的二极管。
  13. 整个设备是触发器,“与”门和“与非”门的组合。它提供了一个闩锁。一个脉冲启动它,一个脉冲停止它。
  14. 导线循环可将锁存器校准为10个脉冲打开,10个脉冲关闭以输入十分之一的脉冲。没有它,我们将打开12个脉冲,关闭8个脉冲。这十个十个关闭的锁存器形成了十个分钟块的基本组件,就像6微米(1脉冲)触发器构成了分钟单元的基本组件一样。
  15. 冷启动初始脉冲引起各种问题,包括与它启动的时钟异相两个拍。这弄乱了闩锁。该与门捕获并处理不同步的脉冲-特别是起始脉冲。
  16. 回顾一下,这是设计的一部分。它需要一个电子,将其分裂为五个,然后消灭后面的五个电子,从而使111111达到100000。
  17. 这需要一个电子并将其缝在正面。确切地说,有两个阶段。它需要100000并得到101000。结合第16部分,我们得到111111-> 100000->101000。回想一下,我希望我能完成111111-> 101010-> 101000;它会在更少的空间中达到相同的效果。
  18. 然后将上述模式推入底部闩锁,以实现20接通,40断开。将其拆分,将一半移相20个单位,然后将它们形成数十分钟的两个高阶位流。

第二部分:小时计数器

说明

小时计数器的输入是一个电子脉冲,每小时一次。第一步是每十二小时一次将其减小为单个电子脉冲。这是使用几个“闩锁”原语实现的。

“锁存器”是连接到AND-NOT和AND门的6微米触发器,用于提供6微米开/关锁存器。“捕获”将连续的电子流作为输入,允许先通过,然后消除后面的所有其他电子,直到该流结束时捕获复位。

依次放置一个闩锁和一个闩锁,会导致一个电子进入->开启闩锁,一个电子从另一端流出(其余电子被闩锁捕获)。然后第二电子进入->关闭闩锁,静默复位。净效应:第一个电子通过,第二个电子被歼灭,依此类推,与这些电子之间的延迟时间无关

现在,串联两个“闩锁”,您只有四分之一的电子通过。

接下来,进行第三次“闩锁和捕捉”,但是这次将整个第四闩锁并嵌入在AND-NOT门与触发器SET之间的触发器SET线上。我让您考虑一下它是如何工作的,但是这次,只有三分之一的电子通过,而不管这些电子之间的延迟多长时间

最后,取四分之一的电子,然后将三分之一的电子与“与”门结合,只有十二分之一的电子通过。这整个部分是下面小时计数器左上角的凌乱路径。

接下来,每十二个小时取一次电子,然后每小时分裂成一个电子,但将其输出到不同的导线上。这可以通过使用带有13个出口点的长线圈导体来实现。

拿这些电子-一小时沿着不同的导体走下来,然后击中触发器SET线。然后,同一个小时触发器上的RESET线将被下一小时的导体击中,从而每小时每根导线向下产生60个脉冲。

最后-接收这些脉冲并将其传递到ROM(只读存储器)的七个半字节中,以输出正确的BCD比特流。有关WireWorld ROM的更详细说明,请参见此处:http ://www.quinapalus.com/wires6.html

设计

带有小时计数器的注解

  1. 每小时输入一个电子。
  2. 第一个闩锁。
  3. 第一招。
  4. 嵌入在外部“闩锁” SET线上的“闩锁”。
  5. 与门。
  6. AM / PM闩锁(每十二小时打开/关闭一次)。
  7. 每个导线环的长度为6x60 = 360单位。
  8. 翻转/翻转其侧面以创建较小的轮廓。
  9. ROM七个半字节。

笔记

  1. 由于其每分钟1个电子,6微米的设计,因此可以以每分钟6代(每10秒产生1代)的速度运行仿真,以实现实时时钟。
  2. AM / PM线对于AM为高(1),对于PM为低(0)。这似乎是一种不寻常的选择方法,但是有道理。在时钟的冷启动期间,AM / PM线最初自然是低电平(0)。一旦AM / PM线被拉高(1),这表明计数从12:00 AM开始。应忽略此点之前的所有输出,认为此点之后的所有输出都是有意义的。

有用的链接


更改了要求,因此可以忽略始终为零的输出。数十小时内永远不会使用4s和8s位,数十分钟内也不会使用8s位。
Sparr

固体!真正的工程。其他逻辑门是否有用?我要蛮力一些。
wyldstallyns

1
这很漂亮
Sparr

1
真是遗憾了,现在我不得不尝试优化我的。我有重复的图案,我可能会缩短以腾出空间来折叠他人
。– wyldstallyns

3
我不知道您在meta上有多活跃,所以这是为了告诉您我已提名该答案为2016年最佳PPCG
彼得·泰勒

5

延迟线存储器-51 x 2880 = 146880

图片

缩小:

图片

输出出现在每个循环的顶部。

我用这个lua将所有状态直接放在导线上,让golly电子在位之间前进,因此我们不必用光标跟随导线。

我使用这种幼稚的方法来设置标准和崩溃课程,wireworld,golly和lua。

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输入。


更改了要求,因此可以忽略始终为零的输出。数十小时内永远不会使用4s和8s位,数十分钟内也不会使用8s位。
Sparr

2
这是一个有趣而令人敬畏的实现!
Sparr

1
好吧,我在第11小时被另一个功能性时钟打败了。我将用不同的技巧来攻击最长和最短的循环。
wyldstallyns

我不会把它拖下去。通过切换到3微米脉冲,我可以节省1/4的尺寸,但是它仍然不能卷得足够紧,无法击败niemiro。
wyldstallyns
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.