题
编写代码,以确定如果一个数字是可分割的,由3.输入到的函数是一个 单 比特,0或1,输出应在1如果数迄今为止收到的二元表示的数除以3,否则为零。
实例:
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
这是根据采访的问题。我问一个关于绘制的逻辑门,但由于这是计算器,我会接受任何编码语言。加分的硬件执行(电气电子工程师学会等)。
A部分(简单): 首先输入MSB。
B部分(有点困难): 首先输入低位.
C部分(困难): 哪一个是较快和较小,(a)或(b)?(未从理论上讲,在大-O意义的,但实际上更快的/小。) 现在慢/更大的之一,并把它作为快速少作为更快的/小的一个。
解决方案
嘿
有关国家表LSB:
S I S' O
0 0 0 1
0 1 1 0
1 0 2 0
1 1 0 1
2 0 1 0
2 1 2 0
说明:0是由三个整除。 0 << 1 + 0 = 0
。重复使用如果S = (S << 1 + I) % 3
。O = 1
和S == 0
有关MSB状态表:
S I S' O
0 0 0 1
0 1 2 0
1 0 1 0
1 1 0 1
2 0 2 0
2 1 1 0
说明:0是由三个整除。 0 >> 1 + 0 = 0
。重复使用如果S = (S >> 1 + I) % 3
。O = 1
和S == 0
S'
是与上述不同,但是,输出工作是相同的,因为S'
是0对于相同的情况下(00和11)。由于O为在两种情况下是相同的,O_LSB = O_MSB,所以使MSB短LSB,或反之亦然,只是用最短两者。
其他提示
有用于确定一个数是否是11的倍数,通过交替地加和减其十进制数字的相当知名的特技。如果你在最后的数字是11的倍数,那么你开始走出数也是11的倍数:
47278 4 - 7 + 2 - 7 + 8 = 0, multiple of 11 (47278 = 11 * 4298) 52214 5 - 2 + 2 - 1 + 4 = 8, not multiple of 11 (52214 = 11 * 4746 + 8)
我们可以使用同样的伎俩二进制数。二进制数是3的倍数,当且仅当它的比特的交替总和也为3的倍数:
4 = 100 1 - 0 + 0 = 1, not multiple of 3 6 = 110 1 - 1 + 0 = 0, multiple of 3 78 = 1001110 1 - 0 + 0 - 1 + 1 - 1 + 0 = 0, multiple of 3 109 = 1101101 1 - 1 + 0 - 1 + 1 - 0 + 1 = 1, not multiple of 3
这没有什么区别,你是否开始与MSB或者LSB,所以下面的Python功能同样适用于这两种情况。它需要返回在时间位一个迭代器。图1和2,而不是1和-1之间交替multiplier
避免采取负数的模
def divisibleBy3(iterator):
multiplier = 1
accumulator = 0
for bit in iterator:
accumulator = (accumulator + bit * multiplier) % 3
multiplier = 3 - multiplier
return accumulator == 0
这里...新的东西...如何检查,如果一个二进制数量的任何长度(即使成千上万的数字)是可分割的,由3.
-->((0))<---1--->()<---0--->(1) ASCII representation of graph
从图片。
- 你开始在双圆。
- 当你获得一个或一个零,如果该数字是圈子里面,然后你留在那个圈子。但是,如果该数字是在一条线,然后你旅行跨线。
- 重复步骤二中,直至所有数字是力消耗.
- 如果你终于结束了在双圆随后的二进制数字是可分割的,由3.
你也可以使用这个用于产生数字可分割的,由3.我不会像这将是难以将其转换成电路。
1例如使用图表...
11000000000001011111111111101是可分割的,由3(结束了在双再次圆)
自己试试看。
你也可以做类似的技巧,用于执行国防部10个,因为当的二进制转换的数字为基10号码。(10圈,每增加一倍上空盘旋,并表示值的0至9造成的模)
编辑: 这是对数字运行的左右,它不是硬要修改的有限状态机的接受相反的语言虽然。
注: 在ASCII表示图()表示一个单一的圈子,(())表示双圆。在有限国家机器,这些被称为国家和双圆圈是接受国(中国家,这意味着其最终可分割的,由3)
下面是一个简单的方法通过手去做。 由于1 = 2 2 MOD 3,我们得到1 = 2 2n个 MOD 3对于每个正整数。 此外2 = 2 2n + 1个 MOD 3.因此,人们可确定的整数是被3整除通过在奇数位位置计数为1点的位,乘以2这个号码,添加1-数在偶数位posistions位将它们添加到结果,并检查结果是被3整除。
实施例:57 <子> 10 子> = 111001 <子> 2 子>。 有2位在奇数位置,并且在偶数位置2位。 2 * 2 + 2 = 6由3整除。因此57是被3整除。
下面还对解决问题℃的思想)。如果一个反相的二进制整数的位顺序,那么所有的位保持在偶/奇数位置或所有位改变。因此反相整数n结果的比特的顺序被一个整数,它是被3整除当且仅当n为被3整除因此,对于问题的任何解决方案)的工作原理,而不用于问题B的变化),并且反之亦然。嗯,也许这可以帮助找出哪种方法更快...
您需要使用算术模3.这是方式做所有的计算
MSB:
number=0
while(!eof)
n=input()
number=(number *2 + n) mod 3
if(number == 0)
print divisible
LSB:
number = 0;
multiplier = 1;
while(!eof)
n=input()
number = (number + multiplier * n) mod 3
multiplier = (multiplier * 2) mod 3
if(number == 0)
print divisible
这是一般的想法...
现在,你的一部分是理解的为什么这是正确的。
和是的,做作业自己;)
我们的想法是,该数量可能会任意长,这意味着你不能在这里使用mod 3
,因为你的数字将增长超出你的整数类的能力。
我们的想法是要注意发生了什么号码。如果您要添加位的权利,你实际上做的是左移一位并添加新的位。
左移位相同乘以2,并加入新的比特要么加入0或1。假设我们从0开始,我们可以这样做递归基于所述模3的最后一个数字的。
last | input || next | example
------------------------------------
0 | 0 || 0 | 0 * 2 + 0 = 0
0 | 1 || 1 | 0 * 2 + 1 = 1
1 | 0 || 2 | 1 * 2 + 0 = 2
1 | 1 || 0 | 1 * 2 + 1 = 0 (= 3 mod 3)
2 | 0 || 1 | 2 * 2 + 0 = 1 (= 4 mod 3)
2 | 1 || 2 | 2 * 2 + 1 = 2 (= 5 mod 3)
现在让我们来看看,当你增添几分向左发生了什么。首先,请注意:
2 2n个 MOD 3 = 1
和
2 2n + 1个 MOD 3 = 2
现在我们必须要么添加1或2基于该模如果当前迭代是奇数还是偶数。
last | n is even? | input || next | example
-------------------------------------------
d/c | don't care | 0 || last | last + 0*2^n = last
0 | yes | 1 || 0 | 0 + 1*2^n = 1 (= 2^n mod 3)
0 | no | 1 || 0 | 0 + 1*2^n = 2 (= 2^n mod 3)
1 | yes | 1 || 0 | 1 + 1*2^n = 2
1 | no | 1 || 0 | 1 + 1*2^n = 0 (= 3 mod 3)
1 | yes | 1 || 0 | 2 + 1*2^n = 0
1 | no | 1 || 0 | 2 + 1*2^n = 1
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
不应该最后输入来12
,或我误解的问题?
其实LSB方法实际上使这个容易。在C:
MSB方法:
/*
Returns 1 if divisble by 3, otherwise 0
Note: It is assumed 'input' format is valid
*/
int is_divisible_by_3_msb(char *input) {
unsigned value = 0;
char *p = input;
if (*p == '1') {
value &= 1;
}
p++;
while (*p) {
if (*p != ',') {
value <<= 1;
if (*p == '1') {
ret &= 1;
}
}
p++;
}
return (value % 3 == 0) ? 1 : 0;
}
LSB方法:
/*
Returns 1 if divisble by 3, otherwise 0
Note: It is assumed 'input' format is valid
*/
int is_divisible_by_3_lsb(char *input) {
unsigned value = 0;
unsigned mask = 1;
char *p = input;
while (*p) {
if (*p != ',') {
if (*p == '1') {
value &= mask;
}
mask <<= 1;
}
p++;
}
return (value % 3 == 0) ? 1 : 0;
}
我个人有很难相信这些中的一个将是显著不同的其他
我觉得弥敦道费尔曼是在正确的轨道上部分和B部分(除B需要一个额外的一块状态:你需要跟踪,如果你的数位是奇数还是偶数的)。
我认为对于C部分诀窍是否定在每一步last
值。即0变为0,1前进到2和2变为1。
一个数字是可分割的,由3如果这个数字是可分割的,由3.
所以你可以添加的数字,并得到的总和:
- 如果总和大于或等于10使用同样的方法
- 如果这是3、第6、第9然后它可分割的,
- 如果总是不同于3、6、第9那么它的不可分割的,