如何在没有条件的情况下递增然后递减计数器?

时间:2014-10-27 15:16:37

标签: javascript coffeescript logic

我正在寻找一种聪明的方法来递增然后递减计数器变量。我希望计数器变量从低值开始并递增,朝向更高的值。一旦达到较高值,计数器就会递减,直到它回到较低值。一旦达到较低值,计数器再次递增到更高的值......我想你明白了。

我正在开发一个canvas animation,我希望在不使用if或其他条件测试的情况下运用一些聪明之处:

这是处理计数器变量的条件逻辑:

incrementing = true

foo = ->

    length += 1 if incrementing
    length -= 1 if not incrementing

    incrementing = false if length > 100
    incrementing = true  if length < 1

最初,我以为我可以使用模数。但是,模除法仅将计数器重置为较低的值 - 一旦达到最高值,它不会递减计数器。

 0 % 10 =  0
 1 % 10 =  1
 2 % 10 =  2
 3 % 10 =  3
 4 % 10 =  4
 5 % 10 =  5
 6 % 10 =  6
 7 % 10 =  7
 8 % 10 =  8
 9 % 10 =  9
10 % 10 =  0
11 % 10 =  1
12 % 10 =  2
13 % 10 =  3

我确信必须有一种方法可以在不使用条件测试的情况下完成此操作。假设底值为0且顶值为10,则该方法应输出以下内容。

? =  0
? =  1
? =  2
? =  3
? =  4
? =  5
? =  6
? =  7
? =  8
? =  9
? =  8
? =  7
? =  6
? =  5

2 个答案:

答案 0 :(得分:15)

首先让我们看看一些波浪!

Hello wave!

types of waves

您能确定符合您需求的那个吗?

如果你猜到了 Triangle Wave ,那你就对了!

三角波以均匀的斜率振荡,直到达到最小值或最大值,然后斜率反转。

这里有两件事要做:

  • 函数的原点将在wave的中间开始
  • 波从x振荡到-x

我们希望在0开始输出,只包含正值

function triangle(t, a) {
  return Math.abs(((t + a/2) % a) - a/2);
}

让我们尝试一下

for (var i=0; i<20; i++) {
  console.log(i, triangle(i, 10));
}

输出

0 0
1 1
2 2
3 3
4 4
5 5
6 4
7 3
8 2
9 1
10 0
11 1
12 2
13 3
14 4
15 5
16 4
17 3
18 2
19 1

因此,当我们致电triangle(i, 10)时,10是&#34;期间&#34;。这告诉我们在重复之前我们希望在函数中有多少步骤。

句号6会为我们提供6个值,0, 1, 2, 3, 2, 1

句号4会给我们4个值,0, 1, 2, 1

如果您想从0-9出发,则需要一段20

答案 1 :(得分:2)

这是一个:

(x&8)+(x&7)*((~x&8)/4-1)

会给你

0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0,1,...

当然实际上有一个条件,只是隐藏为按位操作。

另一种可能性是三角波计数器:

(x^((x&8)/-8))&7

哪个

0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0,0,...

还有一个隐藏的条件,当它到达中途时翻转它们。