仅使用乘法和整数,我如何划分'一个号码?

时间:2014-06-25 22:09:08

标签: javascript html css algorithm math

问题:

用于在rapidweaver中构建堆栈的API不允许除法或浮动,但我基本上想要将数字除以另一个数字。

API的相关规则:

API放在html,css和javascript文件中,并在生成项目文件之前编译为实际的html,css和javascript。

  1. 在此API中,每个数学运算都包含在:

    %( math )%

  2. 所以要达到(1 + 3)* 6,它就是:

    %( %( 1 + 3 )% * 6 )%

    使用%( 1 + 3 * 6 )%会破坏它,每个%()%中只允许一个操作。

  3. 此外,我可以使用代表用户输入的变量

    %id=variableName%

  4. 所以,如果我想将用户输入乘以2,我可以这样做:

    %( %id=variableName% * 2 )%

  5. 我想做什么:

    %( %id=CB_seconds% / 2 )%%( %id=CB_seconds% * 0.5 )%

    但是^ ^因某些愚蠢的原因而不允许......

    我想取用户输入%id=CB_seconds%,并将其除以一半。用户将%id=CB_seconds%定义为0到10,000之间的整数。我需要原始值和不同区域的分值。一种可能的解决方案是让用户指定0到5,000之间的值,并将此值乘以2。但是,这不会起作用,因为用户正在定义动画的长度,并且要求他们指定他们真正想要的长度的一半是令人困惑的。

    我的问题

    是否有某种方法可以使用ONLY整数和乘法/加法/减法来获得一半的数字,并且不知道之前的数字是什么?


    这里是Stacks API的文档 - https://yourhead.tenderapp.com/kb/stacks-api/templates

4 个答案:

答案 0 :(得分:4)

如果您只能访问+*,则无法访问。

这是数学:

如果你有一个只用加法和乘法编写的函数,例如:

a/b=f(a,b)

您可以将f展开为多项式函数。

如果你将n增长到无穷大

您将拥有f(n,n)=n/n=1

但是多项式总是倾向于+无限,无限或0,所以这样的函数不可能存在。

答案 1 :(得分:2)

您可以将乘法定义为一系列加法,您可以将除法作为一系列减法进行划分。为此,您需要循环和比较功能。要将b除以b,假设两者都是整数且a > b,则您的伪代码将为:

division = 1
c = a - b
while (c > b)
  c = c - b
  division = division + 1
end while

此时您有a / b = division,余数为c

例如,a = 10b = 3

division = 1
c = 10 - 3 = 7

c (=7) > 3 --> Continue
  c = 7 - 3 = 4
  division = 2

c (= 4) > 3 --> Continue
  c = 4 - 3 = 1
  division =  3

c (= 1) < 3 --> Stop

此时division = 3c = 1,即10 / 3 = 3 (+ 1)

我看到Stacks API允许进行比较。如果它还包含循环,那么您可以实现上述。

说完以上所有内容之后,他们没有分工真的很蠢。

答案 2 :(得分:1)

我知道这是真正糟糕的编码,但你可以将每个数字从1加倍到5000,看看它是否是用作输入的数字(同时检查它是否为数字+ 1以查看圆形分数)。由于它只有5000次操作,因此不应该对性能产生太大影响。

答案 3 :(得分:0)

新答案

由于我们没有真正的循环,我们必须实现二进制搜索。我们想做的是:

CB_copy = CB_seconds;
CB_half = 0;
for ( exp = 13 ; exp > 0 ; exp- - ) {
    if ( CB_copy > 1 << exp ) {
        CB_half += 1 << (exp-1);
        CB_copy -= 1 << exp;
    }
}

但我们没有条件可言。我们可以使用我们的比较重写它:

CB_copy = CB_seconds;
CB_half = 0;
for ( exp = 13 ; exp > 0 ; exp- - ) {
    CB_half += ( 1 << (exp-1) ) * ( CB_copy > 1 << exp );
    CB_copy -= ( 1 << exp ) * ( CB_copy > 1 << exp )
}

如上所述,我们没有循环。因此,我们必须展开所有内容,并获得28行代码:

CB_copy = CB_seconds;
CB_half = 0;
CB_half += ( 1 << 12 ) * ( CB_copy > 1 << 13 );
CB_copy -= ( 1 << 13 ) * ( CB_copy > 1 << 13 );
CB_half += ( 1 << 11 ) * ( CB_copy > 1 << 12 );
CB_copy -= ( 1 << 12 ) * ( CB_copy > 1 << 12 );
. . .
CB_half += ( 1 << 1 ) * ( CB_copy > 1 << 2 );
CB_copy -= ( 1 << 2 ) * ( CB_copy > 1 << 2 );
CB_half += ( 1 << 0 ) * ( CB_copy > 1 << 1 );
CB_copy -= ( 1 << 1 ) * ( CB_copy > 1 << 1 );

我们也没有位移。但我们可以从定制的plist中获取值。因此,将1 << k替换为twoExp{k},将k的十四个值替换为,并在plist中包含这些常量:

CB_half += ( twoExp12 ) * ( CB_copy > twoExp13 );
CB_copy -= ( twoExp13 ) * ( CB_copy > twoExp13 );
etc

最后,将其翻译成正确的语法:

%CB_copy = %id=CB_seconds% %
%CB_half = 0%
%CB_half = %( CB_half + %( twoExp12 * %( CB_copy > twoExp13 )% )% )% %
%CB_copy = %( CB_copy - %( twoExp13 * %( CB_copy > twoExp13 )% )% )% %
. . .
%CB_half = %( CB_half + %( twoExp0 * %( CB_copy > twoExp1 )% )% )% %
%CB_copy = %( CB_copy - %( twoExp1 * %( CB_copy > twoExp1 )% )% )% %

28行代码除以2.祝你好运。


旧答案

我们可以实现GrimRepear1908循环高达5000的想法,并检查加倍是否为我们提供正确的值。在真实语言中,我们要做的事情如下:

for repeatIndex in (0..5001):
  CB_half += repeatIndex*( repeatIndex*2==CB_seconds || repeatIndex*2==CB_seconds+1 )

使用API​​,似乎只有在每行保持一个操作时代码才是可读的,所以这变成:

for repeatIndex in (0..5001):
  doubled = repeatIndex*2
  doubledLessOne = doubled-1
  CB_evenTarget = doubled==CB_seconds
  CB_oddTarget = doubledLessOne==CB_second
  isTarget = CB_evenTarget || CB_oddTarget // is 0 or 1
  multed = repeatIndex * isTarget
  CB_half = multed + CB_half

在语言的语法中(假设我已正确完成变量赋值),最终得到:

%[repeat 5001]%
%doubled = %( %id=repeatIndex% *2 )% %
%doubledLessOne = %( %id=doubled% -1 )%
%CB_evenTarget = %( %id=doubled% == %id=CB_seconds% )%
%CB_oddTarget = %( %id=doubledLessOne% == %id=CB_second% )%
%isTarget = %( %id=CB_evenTarget% || %id=CB_oddTarget% )%
%multed = %( %id=repeatIndex% * %id=isTarget% )%
%CB_half = %( %id=multed% + %id=CB_half% )%
%[endrepeat]%

Nuclearman提出了一种二元搜索技术。这可能会使代码更短,但是由于一个简单的循环结束的痛苦,我不打算尝试。