我可以将数字总和除以两倍吗?


40

给定一个整数作为输入,如果数字被其数字总和的两倍整除,则您的任务是输出一个真值,否则将输出一个假值(OEIS A134516)。换一种说法:

(sum_of_digits)*2 | number
  • 您可以为真/假情况指定任何有限的值集,而不是为真/假情况的真/假值,并用它们补充其他值。举一个简单的例子,您可以使用0真数字,而所有其他数字用于假数字(如果愿意,反之亦然)。

  • 标准输入和输出规则适用。默认漏洞也适用。

  • 您可以将输入作为整数或该整数的字符串表示形式。

  • 这是,因此以字节为单位的最短代码获胜!

  • 我是PPCG的新手,因此,如果可能的话,我希望您发表解释。


测试用例

输入-输出-(原因)

80-真实-(16除以80)
100-真实-(2除以100)
60-真实-(12除以60)
18-Truthy-(18除以18)
12-真实-(6除数12)

4-虚假-(8不除以4)
8-虚假-(16不除8)
16-虚假-(14不除以16)
21-虚假-(6不除21)
78-虚假-(30不除以78)
110-虚假-(4不did 110)
111-虚假-(6不除111)
390-虚假-(24不除以390)

好挑战,欢迎来到PPCG!
Skidsdev

@Mayube谢谢,这是我的第二个挑战,但是第一个挑战已经关闭:P

我们可以将数字作为整数列表吗?
亨利

4
@Henry不,那太琐碎了

1
实际上,这两个句子是:“可以代替真实情况下的真实值/虚假值,而可以为真实情况指定任何有限的值集,并为虚假情况指定它们的补语。对于一个简单的示例,您可以使用“ 0”代表真实情况,所有其他数字代表“ false”情况(反之亦然,反之亦然)”似乎彼此矛盾(特别是“有限”和“反之亦然”)。
格雷格·马丁

Answers:


7

Neim,3 个字节

𝐬ᚫ𝕞

说明:

𝐬      Implicitly convert to int array and sum the digits
 ᚫ     Double
  𝕞   Is it a divisor of the input?

在线尝试!

详细版本


嗯...您应该检查输入是否为数字总和的两倍的倍数,而不是相反。
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer是什么意思?我确实检查输入是否是数字总和的两倍的倍数。也许我没有正确解释。
Okx

4
Neim需要变得更加高尔夫-提交时间过长时,我的浏览器将开始滞后。
硕果累累

1
@ Challenger5我真诚地对缺乏打高尔夫球的态度表示歉意。我下次再试。再次抱歉。
Okx

@Okx我真诚地道歉,因为我懒于找到Neim的答案,而这个答案更好地证明了我在说什么。
硕果累累

16

JavaScript(ES6),31 29 27字节

将输入作为字符串。对于真实,返回零,对于虚假,返回非零。

n=>n%eval([...n+n].join`+`)

已评论

n => n % eval([...n + n].join`+`)
n =>                                   // take input string n  -> e.g. "80"
                  n + n                // double the input     -> "8080"
              [...     ]               // split                -> ["8", "0", "8", "0"]
                        .join`+`       // join with '+'        -> "8+0+8+0"
         eval(                  )      // evaluate as JS       -> 16
     n %                               // compute n % result   -> 80 % 16 -> 0

测试用例


我以前从未见过[... x]拆分方法,为此有专门的名称吗?
雅各布·珀西

@JacobPersi这是点差运算符
Arnauld

7

C#,46个字节

using System.Linq;n=>n%(n+"").Sum(c=>c-48)*2<1

完整/格式化版本:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<int, bool> f = n => n % (n + "").Sum(c => c - 48) * 2 < 1;

        Console.WriteLine(f(80));
        Console.WriteLine(f(100));
        Console.WriteLine(f(60));

        Console.WriteLine();

        Console.WriteLine(f(16));
        Console.WriteLine(f(78));
        Console.WriteLine(f(390));

        Console.ReadLine();
    }
}

4

视网膜38 27字节

-11个字节,并通过@MartinEnder修复了代码错误

$
$_¶$_
.+$|.
$*
^(.+)¶\1+$

在线尝试!

如果可整除则打印1,否则打印0

说明(希望我说对了)

$
$_¶$_

追加整个输入,加上换行符,再加上输入

.+$|.
$*

将每个匹配项转换为一进制(作为原始输入的第二行或第一行中的每个数字)

^(.+)¶\1+$

检查第一行(两位数总和)是否为第二行的除数


4

MATL,7个字节

tV!UsE\

0如果可分则输出,否则输出正整数。具体来说,它输出将数字除以其数字总和的两倍的余数。

在线尝试!

说明

t   % Implicit input. Duplicate
V!U % Convert to string, transpose, convert to number: gives column vector of digits
s   % Sum
E   % Times 2
\   % Modulus. Implicit display

4

05AB1E5 4字节

-1字节归功于Okx

SO·Ö

在线尝试!

您也可以删除最后一个Ö,以确保真实性为0,而为虚假性获得其他属性,结果仅3个字节,但对我而言似乎不合适。

说明

SO·Ö
SO    # Separate the digits and sum them
  ·   # Multiply the result by two
   Ö  # Is the input divisible by the result?

您可以通过更换其高尔夫到4个字节%_Ö
Okx

4

x86-64机器码,24字节

6A 0A 5E 31 C9 89 F8 99 F7 F6 01 D1 85 C0 75 F7 8D 04 09 99 F7 F7 92 C3

上面的代码在64位x86机器代码中定义了一个函数,该函数确定输入值是否可被其位数之和加倍。该函数符合System V AMD64调用约定,因此几乎可以从任何语言进行调用,就像它是C函数一样。

根据EDI调用约定,它通过寄存器将单个参数作为输入,它是要测试的整数。(假定它是一个整数,与质询规则一致,并且对于CDQ我们用来正确工作的指令是必需的。)

EAX按照调用约定,它再次将结果返回到寄存器中。其结果将是0,如果输入值通过它的数字的总和整除,否则非零。(基本上是反布尔值,与质询规则中给出的示例完全一样。)

它的C原型将是:

int DivisibleByDoubleSumOfDigits(int value);

以下是无用的汇编语言说明,并在其中简要说明了每条指令的用途:

; EDI == input value
DivisibleByDoubleSumOfDigits:
   push 10
   pop  rsi             ; ESI <= 10
   xor  ecx, ecx        ; ECX <= 0
   mov  eax, edi        ; EAX <= EDI (make copy of input)

SumDigits:
   cdq                  ; EDX <= 0
   div  esi             ; EDX:EAX / 10
   add  ecx, edx        ; ECX += remainder (EDX)
   test eax, eax
   jnz  SumDigits       ; loop while EAX != 0

   lea  eax, [rcx+rcx]  ; EAX <= (ECX * 2)
   cdq                  ; EDX <= 0
   div  edi             ; EDX:EAX / input
   xchg edx, eax        ; put remainder (EDX) in EAX
   ret                  ; return, with result in EAX

在第一步中,我们对寄存器进行了一些初步的初始化:

  • PUSH+ POP指令用作初始化ESI为10 的缓慢但简短的方法。这是必需的,因为DIVx86上的指令需要寄存器操作数。(没有任何形式可以除以10的立即值。)
  • XOR用作清除ECX寄存器的快速方法。该寄存器将在即将到来的循环中充当“累加器”。
  • 最后,制作输入值(来自EDI)的副本,并将其存储在中EAX,当我们进行循环时,它将被破坏。

然后,我们开始循环并求和输入值中的数字。这基于x86 DIV指令,该指令除EDX:EAX以其操作数,然后返回中的商EAX和中的余数EDX。我们在这里要做的是将输入值除以10,以便余数是最后一位(我们将其添加到累加器寄存器中ECX),而商就是余数。

  • CDQ指令是将其设置EDX为0的一种简短方法。它实际上将值符号扩展EAXEDX:EAX,这是DIV用作被除数的方法。我们实际上不需要在这里进行符号扩展,因为输入值是无符号的,但是CDQ是1字节,与使用XORclear 相对EDX,这是2字节。
  • 然后我们DIVIDE EDX:EAXESI(10)。
  • 余数(EDX)添加到累加器(ECX)中。
  • 测试EAX寄存器(商)以查看它是否等于0。如果是,那么我们已经遍历所有数字,并且失败了。如果不是,我们还有更多的数字可以累加,所以我们回到循环的顶部。

最后,在循环完成之后,我们实现number % ((sum_of_digits)*2)

  • LEA指令用作乘以ECX2(或等效地ECX加到自身)并将结果存储在不同寄存器(在本例中为)的一种简短方法EAX

    (我们也可以做add ecx, ecx+ xchg ecx, eax;它们都是3个字节,但是LEA指令更快,更典型。)

  • 然后,我们CDQ再次做准备分裂。因为EAX将为正(即无符号),所以具有EDX像以前一样清零的效果。
  • 接下来是除法,这次是除以EDX:EAX输入值(仍保留在其中的未破坏副本EDI)。这等效于取模,其余部分为EDX。(商也被放入EAX,但是我们不需要它。)
  • 最后,我们XCHG(交换)的内容EAXEDX。通常,您可以在MOV此处执行一个操作,但是XCHG只有1个字节(尽管速度较慢)。因为EDX包含除法运算后的余数,所以如果该值可以被整除或否则为非零,则它将为0。因此,当我们RETurn时,EAX如果输入值可被其数字的总和的两倍整除,则(结果)为0,否则为非零。

希望这足以解释。
这不是最短的条目,但是,嘿,它似乎击败了几乎所有非高尔夫语言!:-)


3

Japt7个 4字节

将输入作为字符串。输出0用于true或数大于0false,其中,从其他解决方案,似乎是有效的。如果没有,请告诉我,我会回滚。

%²¬x

测试一下


说明

字符串的隐式输入U
"390"

²

重复U两次。
"390390"

¬

拆分为单个字符数组。
["3","9","0","3","9","0"]

x

通过求和来减少,过程中将每个字符自动转换为整数。
24

%

得到除以U结果的余数,U在此过程中也将自动转换为整数。隐式输出结果整数。
6 (=false)


2
您的解释通常会占用很多垂直空间,我认为这是不需要的。无论哪种方式,这都是您的答案。
Okx

@Okx; 我不知道几天前我只切换到这种格式时会有多“正常”。
毛茸茸的

4
我喜欢解释格式。很容易遵循,尤其是对于这个问题,因为它是线性减少并且像数学问题一样向下移动页面。只是我的两分钱。
亨利

3
这种解释格式比通常的格式好很多,尤其是对于那些不熟悉这些语言的人。我希望其他使用这些高尔夫语言的高尔夫球手也能这样做。
Peter1807 '17

3

C89,55 53个字节

(感谢Steadybox!

s,t;f(x){for(t=x,s=0;t;t/=10)s+=t%10;return x%(s*2);}

它只接受一个输入,x这就是要测试的值。如果x可以被其位数的总和平均除以两倍,则返回0,否则返回非零。

在线尝试!

取消高尔夫:

/* int */ s, t;
/*int */ f(/* int */ x)
{
    for (t = x, s = 0; t /* != 0 */; t /= 10)
        s += (t % 10);
    return x % (s * 2);
}

如您所见,这利用了C89的隐式整数规则。全局变量st被隐式声明为ints。(由于它们是全局变量,它们也被隐式初始化为0,但是如果我们希望函数可以多次调用,则不能利用它。)

同样,函数f接受一个参数,x,该参数隐含为int,并返回int

函数内部的代码非常简单,尽管for如果您不熟悉语法,则循环看起来会很奇怪。基本上,forC中的循环头包含三个部分:

for (initialization; loop condition; increment)

在“初始化”部分,我们已经初始化了全局变量。在进入循环之前,它将运行一次。

在“循环条件”部分,我们指定了循环应在什么条件下继续。这应该是显而易见的。

在“增量”部分,我们基本上放置了任意代码,因为它将在每个循环的末尾运行。

循环的更大目的是迭代输入值中的每个数字,并将它们添加到中s。最后,在循环完成之后,s将其加倍并取模,x以查看其是否可整除。(可以在我的另一个答案中找到关于此逻辑的更好,更详细的解释,该答案基于此。)

可读版本:

int f(int x)
{
    int temp = x;
    int sum  = 0;
    while (temp > 0)
    {
        sum  += temp % 10;
        temp /= 10;
    }
    return x % (sum * 2);
}

如果使用t而不是t>0作为循环条件,则可以保存两个字节。
Steadybox

啊,当然!很好,@ Steadybox。不知道我怎么会错过这一点,因为针对0进行测试正是我的asm实现所做的事情,而该答案很大程度上取决于该实现。
科迪·格雷




2

Mathematica,26个字节

(2Tr@IntegerDigits@#)∣#&

不知道为什么优先级比乘法高...


2

PHP,41字节

如果可整除,则输出零;否则,输出正整数。

<?=$argn%(2*array_sum(str_split($argn)));

在线尝试!


您将分配放在标题块中。您不妨使用$a=10,但您忘了将其计入您的字节数

@aross为什么我应该将输入计入我的字节数。$argn是可用的-F(在这种情况下)或-R选项
约克Hülsermann

嗯,有趣。我不知道-F。但这并没有反映在您的TIO中(它是否支持STDIN的回显?)。
Aross'7

@aross就像您的方法只使用文件而不是代码,使用-F选项而不是-R php.net/manual/en/features.commandline.options.php一样工作。行让我知道
约尔格Hülsermann

2

Excel,63个字节

=MOD(A1,2*SUMPRODUCT(--MID(A1,ROW(OFFSET(A$1,,,LEN(A1))),1)))=0

累加数字是很长的位。



2

外壳9 8字节

感谢Leo节省了1个字节。

Ṡ¦ȯ*2ṁis

在线尝试!

说明

Ṡ¦ȯ         Test whether f(x) divides x, where f is the function obtained by
            composing the next 4 functions.
       s    Convert x to a string.
     ṁi     Convert each character to an integer and sum the result.
   *2       Double the result.

您可以使用ṁ来通过单个命令映射和求和,从而节省一个字节
Leo


2

Python 3,35个字节

lambda a:a%(sum(map(int,str(a)))*2)

您好,欢迎来到该网站。您可以在此处删除一些空格。特别是围绕=和之后)int(c)。另外,由于sum可以将生成器作为参数,因此可以删除其中的[..]内部。如果您还有其他问题,请随时与我联系。
小麦巫师

int(c)for c in a也可以是map(int,a),以节省一些字节。
小麦巫师

这是行不通的,或者说是倒退。可以轻松地用4个额外的字节修复:lambda a:not a%(sum(map(int,str(a)))*2)
osuka_

@osuka_参见问题描述中的项目符号要点
wrymug

2

TI-BASIC,27 26 21 字节

-5感谢@Oki

:fPart(Ans/sum(2int(10fPart(Ans10^(~randIntNoRep(1,1+int(log(Ans

由于TI-BASIC中没有简洁的方法来求和整数,因此这变得棘手。返回0True,和不同数量False

说明:

:fPart(Ans/sum(2int(10fPart(Ans10^(-randIntNoRep(1,1+int(log(Ans
                               10^(-randIntNoRep(1,1+int(log(Ans #Create a list of negative powers of ten, based off the length of the input, i.e. {1,0.1,0.01}
                            Ans                                  #Scalar multiply the input into the list
                    10fPart(                                     #Remove everything left of the decimal point and multiply by 10
               2int(                                             #Remove everything right of the decimal point and multiply by 2
           sum(                                                  #Sum the resulting list
       Ans/                                                      #Divide the input by the sum
:fPart(                                                          #Remove everything left of the decimal, implicit print

2
10^-randIntNoRep(1,1+int(log(Ans做与seq(10^(~A-1),A,0,log(Ans减少顺序无关紧要的字节数减少相同(假设版本为2.55MP)
Oki,

1

Braingolf13 12字节

VR.Mvd&+2*c%

在线尝试!

输出0为真,其他任何数字为假。

说明

VR.Mvd&+2*c%  Implicit input from command-line args
VR            Create stack2, return to stack1
  .M          Duplicate input to stack2
    vd        Switch to stack2, split into digits
      &+      Sum up all digits
        2*    Double
          c   Collapse stack2 back into stack1
           %  Modulus
              Implicit output of last item on stack

1

Japt,7个字节

vUì x*2

返回1true0用于false

在线尝试!

说明

vUì x*2
v        // Return 1 if the input is divisible by:
 Uì      //   Input split into a base-10 array
    x    //   Sum the array
     *2  //   While mapped by *2

我也为此提出了一些其他的7字节解决方案(尽管我不认为这是其中之一)-但我相信还有一个更短的解决方案。
粗野的


1

Java,66个字节

-1字节感谢Olivier

a->{int i=0;for(int b:(""+a).getBytes())i+=b-48;return a%(i*2)<1;}

取消高尔夫&解释:

a -> {
    int i = 0;

    for(int b : (""+a).getBytes()) { // Loop through each byte of the input converted to a string
        i += b-48; // Subtract 48 from the byte and add it to i
    }

    return a % (i*2) < 1 // Check if a % (i*2) is equal to one
    // I use <1 here for golfing, as the result of a modulus operation should never be less than 0
}

使用int而不是byte保存...一个字节。
奥利维尔·格雷戈尔

@OlivierGrégoire谢谢。没注意到。
Okx

@Okx还需要更改高尔夫球代码。
亨利

您的(行进的)代码给出的110和111值不正确。由于模数和乘法具有相同的顺序,因此可能会将a%i*2其解析为(a%i)*2
奥利维尔·格雷戈雷

@OlivierGrégoire啊,真糟糕。
Okx

1

J,15个字节

0表示真实,非零表示虚假。

|~[:+/2#"."0@":

说明

        "."0@":  convert to list of digits
  [:+/2#         sum 2 copies of the list ([: forces monadic phrase)
|~               residue of sum divided by argument?

避免paren或倍数@或倍数的非常聪明的方法[:
约拿(Jonah)

1
我辩论过将其发布为我自己的答案,但这并没有太大的不同。|~2*1#.,.&.":13个字节
cole

我在J Qt IDE上收到一个“域错误”。(|〜[:+ / 2#“。” 0 @“:112)然后对于科尔的代码,我得到(|〜2 * 1#....”:112)= 0。:/可能我这边出了问题。
DrQuarius



1

Haskell35 34字节

f x=mod x$2*sum[read[c]|c<-show x]

在线尝试!

如果是,则返回“ 0”,否则返回其余部分。

Haskell,nimi的无意义版本,34字节

mod<*>(2*).sum.map(read.pure).show

在线尝试!


相同的字节数,如果你去pointfree:mod<*>(2*).sum.map(read.pure).show
NIMI

看起来不错,我在提交中添加了它。
bartavelle

1

PHP,44字节

for(;~$d=$argn[$i++];)$t+=2*$d;echo$argn%$t;

像这样运行:

echo 80 | php -nR 'for(;~$d=$argn[$i++];)$t+=2*$d;echo$argn%$t;'

说明

迭代数字以计算总数,然后像大多数答案一样输出模。


1

Java(OpenJDK 8)55 53字节

a->{int i=0,x=a;for(;x>0;x/=10)i+=x%10*2;return a%i;}

在线尝试!

返回值0表示真实,其他表示虚假。

由于我在Okx答案中的评论没有引起任何连锁反应,因此我删除了该评论并将其发布为该答案,而且打得更多。

感谢@KrzysztofCichocki和@Laikoni进一步打高尔夫球,他们正确地向我展示了我不需要回答真实/虚假的值,但只要我描述结果,任何值都可以。


您可以在结尾处删除<1部分,因此结果将为0(对于true)和> 0(对于false),这是可以实现的,这将导致额外的-2字节,因此您回答的长度可能是53字节。
Krzysztof Cichocki

@KrzysztofCichoki不,我不能:这是Java。唯一的真实值是true
OlivierGrégoire'7

@OlivierGrégoire如果没有其他说明,则为true,此挑战专门指出Instead of truthy / falsy values for the true and false cases, you may instead specify any finite set of values for the true/false case, and their complement the other values.
Laikoni '17

@KrzysztofCichocki和Laikoni对不起,我读错了那部分,我只是解决了!谢谢你们两个:)另外,很抱歉拒绝在这种情况下实际上适当的编辑
奥利维尔·格雷戈雷

1

迷你高射炮,296个 292字节

({}((()[()]))){(({}[((((()()()){}){}){}){}])({}(((({})){}){}{}){})[({})])(({}({})))({}(({}[{}]))[{}])({}[({})](({}{})(({}({})))({}(({}[{}]))[{}])({}[({})]))[{}])(({}({})))({}(({}[{}]))[{}])({}[({})])}{}({}(((({}){})))[{}]){({}((({}[()]))([{(({})[{}])()}{}]()){{}{}(({}))(()[()])}{})[{}][()])}

在线尝试!

TIO链接有我更多的评论,因此在某种程度上更易于阅读。

真/假:如果第二个数字等于第三个数字,则真(可整除),否则为假。因此,真值集和虚假集都是无限的,但我想应该允许这样做。如果不是+10字节。

注意:输入中不允许前导/尾随换行符/空格。

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.