容易相乘的数字


34

您的任务是确定两个数字是否容易相乘。这意味着,从乘法步骤和加法步骤来看,它们的以10为基数的long乘法在位值之间没有任何进位(重新组合)。当每一对数字相乘等于9或更少且每列的总和等于9或更少时,就会发生这种情况。

例如,331并且1021很容易相乘:

   331
x 1021
------
+  331
  662
   0
331
------
337951

如果我们以其他顺序相乘,也是如此(一如既往):

  1021
x  331
------
+ 1021
 3063
3063
------
337951

但是,431并且1021也不容易相乘,在指示的列之间发生进位:

   431
x 1021
------
+  431
  862
   0
431
------
440051
 ^^^

同样,12并且16也不容易相乘,因为即使相乘没有发生进位,在相乘12 * 6得到get 72时也会发生结转。

  12
x 16
----
+ 72
 12
----
 192

输入:两个正整数或其字符串表示形式。您可能会认为它们不会溢出您语言的整数类型,也不会溢出它们的乘积。

输出:如果它们很容易相乘,则为一个一致的值;否则,则为另一个一致的值。

测试用例:前5个很容易相乘,后5个不容易。

331 1021
1021 331
101 99
333 11111
243 201

431 1021
12 16
3 4
3333 1111
310 13

[(331, 1021), (1021, 331), (101, 99), (333, 11111), (243, 201)]
[(431, 1021), (12, 16), (3, 4), (3333, 1111), (310, 13)]

排行榜:


1
每个数字的输入可以是数字列表吗?
dylnan '17

@dylnan否,尽管默认情况下字符串列表中的字符列表有效。
xnor

Answers:


14

果冻,7个字节

Dæc/>9Ẹ

在线尝试!

使用卷积(我对Jelly:D做出了贡献)

怎么运行的

Dæc/>9Ẹ
D        converts to decimal list
 æc      convolution
    >9Ẹ  checks if any number is greater than 9

哇,卷积:DI认为这是我第一次看到在代码高尔夫球中使用卷积:D +1
HyperNeutrino



@LuisMendo不,那是一个不同的卷积。
暴民埃里克(Erik the Outgolfer)

顺便说一句,您可以用<⁵Ạfor输出替换最后3个字节,而不对其进行布尔NOT运算。
暴民埃里克(Erik the Outgolfer)

8

JavaScript(ES6),67个字节

以currying语法将输入作为2个字符串(a)(b)。返回false容易还是true不容易。

a=>b=>[...a].some((x,i,a)=>[...b].some(y=>(a[-++i]=~~a[-i]+x*y)>9))

测试用例


Alt。版本(有缺陷的),64 55 52字节

通过@Shaggy的建议,通过获取字符串节省了3个字节正如@LeakyNun
指出的那样,此方法在某些较大的特定整数上将失败

以currying语法将输入作为2个字符串(a)(b)。返回true容易还是false不容易。

a=>b=>/^.(0.)*$/.test((g=n=>[...n].join`0`)(a)*g(b))

测试用例

怎么样?

这里的想法是通过在每个因子的每个数字之前插入零来显式暴露进位。

例子:

  • 331 x 1021变为30301 x 1000201,从而得到30307090501,而不是337951。通过在结果中添加前导零并将所有数字除以2,可以将其写为03 03 07 09 05 01。所有组均小于10,这意味着标准乘法中不会有任何进位。

  • 431 x 1021变成40301 x 1000201,得到40309100501,可以写成04 03 09 10 05 01。这次,我们有一个10表示标准乘法中的进位。


可以...我们可以对算法进行基本解释吗?
完全人类

@totallyhuman我已经添加了一个解释。(糟糕……并修复了一个错误。)
Arnauld

1
看起来您应该能够通过将输入作为字符串来节省3个字节。
毛茸茸的

3
我花了很长时间才找到一个(理论上的)反例,您的算法将失败:tio.run / ## y0rNyan8 / 9 / l8LJk / f ///…108中间弄乱了您的算法)
Leaky Nun

@LeakyNun很好找到。是的,理论上它会溢出。
Arnauld

6

爱丽丝,30字节

/Q.\d3-&+k!*?-n/ o @
\ic/*2&w~

在线尝试!

输出既1容易又0困难。

当且仅当乘积的数字总和等于数字总和的乘积时,数字才容易相乘。

/i    Input both numbers as a single string
.     Duplicate this string
/*    Coerce into two integers and multiply
2&w   Push return address twice (do the following three times)
~\Q     Swap the top two stack entries, then reverse the stack
        This produces a 3-cycle, and the first iteration coerces
        the original input string into two integers
c       Convert into individual characters
\d3-&+  Add all numbers on the stack except the bottom two (i.e., add all digits)
k     Return to pushed address (end loop)
      At this point, all three numbers are replaced by their digit sums
!*?   Multiply the digit sums of the original two numbers
-     Subtract the digit sum of the product
n     Logical negate: convert to 1 or 0
/o@   Output as character and terminate

4

MATL,10字节

,j!U]Y+9>a

输出0容易,1很难。

在线尝试!验证所有测试用例

说明

,       % Do twice
  j     %   Input as a string
  !     %   Transpose into a column vector of characters
  U     %   Convert each character to number. Gives a numeric column vector
]       % End
Y+      % Convolution, full size
9>      % Greatear than 1? Element-wise
a       % Any: true if there is some true entry. Implicitly display

4

[R 135个 110 109 86字节

function(m,n)any(convolve(m%/%10^(nchar(m):1-1)%%10,n%/%10^(1:nchar(n)-1)%%10,,"o")>9)

在线尝试!

将输入作为字符串。

很难看,但是可以使用。

现在,它使用卷积方法,如Leaky Nun的答案所示,因此将输入作为整数,并返回TRUE难以相乘的数字和FALSE易于相乘的数字。

过去,在移植卷积方法时总是遇到一些麻烦,但是今天我终于阅读了文档

需要注意的是两个序列的卷积的通常的定义xy由下式给出convolve(x, rev(y), type = "o")

真是愚蠢。因此,将的数字提取取反n,它分解为Leaky Nun的答案的端口。




3

Wolfram语言(Mathematica)75 66 65 56字节

f:=#~FromDigits~x&
g:=Max@CoefficientList[f@#2f@#,x]<=9&

在线尝试!

接收2个字符串输入

说明:

f:=#~FromDigits~x&                      (* Turns the number to a polynomial
                                           with the digits as coefficients      *)
g:=Max@CoefficientList[f@#2f@#,x]<=9&   (* Polynomial multiplication, and check
                                           whether all coefficients are smaller
                                           than 10                              *)

-9更改为使用字符串作为输入

-1用于使用infix运算符

-9感谢@MartinEnder提供的Max功能



3

朱莉娅0.6,30字节

~x=any(conv(digits.(x)...).>9)

在线尝试!

输入是数字的元组,输出是true很难相乘的数字,也false就是简单的数字。

. 是逐元素函数应用程序。

...将(整数列表的)元组扩展为conv函数的两个独立输入。



3

SNOBOL4(CSNOBOL4) 268个 264 247 246 243 131字节

	DEFINE('D(A)')
	M =INPUT
	N =INPUT
	OUTPUT =EQ(D(M) * D(N),D(M * N)) 1	:(END)
D	A LEN(1) . X REM . A	:F(RETURN)
	D =D + X	:(D)
END

在线尝试!

Nitrodon移植方法。我认为这是我第一次在SNOBOL中D为数字和定义函数。

	DEFINE('D(A)')					;* function definition
	M =INPUT					;* read input
	N =INPUT					;* read input
	OUTPUT =EQ(D(M) * D(N),D(M * N)) 1	:(END)	;* if D(M)*D(N)==D(M*N),
							;* print 1 else print nothing. Goto End
D	A LEN(1) . X REM . A	:F(RETURN)		;* function body
	D =D + X	:(D)				;* add X to D
END

旧版本,243个字节:

	M =INPUT
	N =INPUT
	P =SIZE(M)
	Q =SIZE(N)
	G =ARRAY(P + Q)
Z	OUTPUT =LE(P)	:S(E)
	M LEN(P) LEN(1) . A
	J =Q
Y	GT(J)	:F(D)
	N LEN(J) LEN(1) . B
	W =I + J
	X =G<W> + A * B
	G<W> =LE(A * B,9) LE(X,9) X	:F(E)
	J =J - 1	:(Y)
D	P =P - 1	:(Z)
E
END

在线尝试!

STDIN上的输入由换行符分隔,输出到STDOUT:单个换行符易于乘法,没有输出则不便于乘法。

这不会赢得任何奖项,但却提出了另一种方法(嗯,这确实是幼稚的方法)。我认为我无法用cubix编写此代码,但是SNOBOL足够强大,无法按原样使用。

由于它将输入作为字符串,因此该方法适用于每个少于512位数字的输入。我不确定100%ARRAYSNOBOL可以有多大。

此版本的SNOBOL中将INPUT缓冲为最大宽度为1024个字符。所有其他字符都将丢失。看来,ARRAY可能很大。远远超过2048个必需的单元格

	M =INPUT				;*read input
	N =INPUT				;*read input
	P =SIZE(M)				;*P = number of M's digits, also iteration counter for outer loop
	Q =SIZE(N)				;*Q = number of N's digits
	G =ARRAY(P + Q)				;*G is an empty array of length P + Q
Z	GE(P)	:F(T)				;*if P<0, goto T (outer loop condition)
	M LEN(P) LEN(1) . A			;*A = P'th character of M
	J =Q					;*J is the iteration counter for inner loop
Y	GT(J)	:F(D)				;*if J<=0, goto D (inner loop condition)
	N LEN(J) LEN(1) . B			;*B = J'th character of N
	W =I + J				;*W=I+J, column number in multiplication
	X =G<W> + A * B				;*X=G[W]+A*B, temp variable for golfing
	G<W> =LE(A * B,9) LE(X,9) X	:F(END)	;*if A*B<=9 and X<=9, G[W]=X otherwise terminate with no output
	J =J - 1	:(Y)			;*decrement J, goto Y
D	P =P - 1	:(Z)			;*decrement P, goto Z
T	OUTPUT =				;*set output to ''; OUTPUT automatically prints a newline.
END

2

木炭,38字节

≔E⁺θη⁰ζFLθFLη§≔ζ⁺ικ⁺§ζ⁺ικ×I§θιI§ηκ‹⌈ζχ

在线尝试!链接是详细版本的代码。-当数字容易相乘时输出a 。说明:

≔E⁺θη⁰ζ

初始化z为足够大的零(输入长度​​的和)数组。

FLθFLη

循环输入q和的索引h

§≔ζ⁺ικ⁺§ζ⁺ικ×I§θιI§ηκ

执行长乘法的一个步骤。

‹⌈ζχ

检查携带。



2

Haskell,82 81字节

q=map$read.pure
f a=any(>9).concat.scanr((.(0:)).zipWith(+).(<$>q a).(*))(0<$a).q

数字a作为字符串。False如果数字容易相乘,True则返回;否则返回。

在线尝试!

我认为这与@Laikoni的答案足够不同。怎么运行的:

q                    -- helper function to turn a string into a list of digits

f a =                -- main function, first number is parameter 'a' 
      scanr    .q    -- fold the following function from the right (and collect
                     -- the intermediate results in a list) into the list of
                     -- digits of the second number
            0<$a     --   starting with as many 0s as there are digits in 'a'
                     -- the function is, translated to non-point free:
  \n c->zipWith(+)((*n)<$>q a)$0:c 
                     -- 'n': next digit of 'b'; 'c': value so far
        (*n)<$>a     --    multiplay each digit in 'a' with 'n'
        0:c          --    prepend a 0 to 'c'
        zipWith(+)   --    add both lists element wise
                     --    (this shifts out the last digit of 'c' in every step)
   concat            -- flatten the collected lists into a single list
 any(>9)             -- check if any number is >9

不错的解决方案!我一直在寻找摆脱进口的方法,但最终结果却更长。
Laikoni '17

2

哈斯克尔45) 44字节

编辑:

  • -1个字节更改==<

在查看其他答案之前,我已经想到了这一点,然后发现爱丽丝使用了相同的基本思想。无论如何都发布,因为它比其他Haskell答案要短。

?接受两个整数并返回Bool。用作331?1021False表示乘法很容易。

a?b=s(a*b)<s a*s b
s=sum.map(read.pure).show

在线尝试!

  • s是计算整数位数之和的函数。(read.pure将一位数字字符转换为整数。)
  • 如果一对数字容易相乘,则乘积的数字和等于数字和的乘积。
  • 相反,在长乘法期间的任何进位都会使乘积的数字总和偏离理想值。


1

Haskell 123字节

import Data.List
r=read.pure
a%b|l<-transpose[reverse$map((*r d).r)b++(0<$e)|d:e<-scanr(:)""a]=all(<10)$concat l++map sum l

在线尝试!用法示例:"331" % "1021"yields True


1

Perl 5,100 + 2(-F)= 102字节

push@a,[reverse@F]}{map{for$j(@{$a[0]}){$b[$i++].='+'.$_*$j}$i=++$c}@{$a[1]};map$\||=9>eval,@b;say$\

在线尝试!

输出false表示容易,true表示不容易。


1

果冻,8字节

;PDḄµṪ⁼P

在线尝试!

我的Javascript 答案的端口。不短于现有的果冻答案,因为果冻具有强大的内置卷积功能。

将输入作为两个数字的列表。返回1容易,0不容易。


说明:


;PDḄµṪ⁼P     Main link. Let input = [101, 99]
;P           Concatenate with product. Get [101, 99, 9999]
  D          Convert to decimal. Get [[1,0,1], [9,9], [9,9,9,9]]
   Ḅ         Convert from binary. Get [1 * 2^2 + 0 * 2^1 + 1 * 2^0, 
             9 * 2^1 + 9 * 2^0, 9 * 2^3 + 9 * 2^2 + 9 * 2^1 + 9 * 2^0]
             = [5, 27, 135]
    µ        With that value,
     Ṫ       Take the tail from that value. Get 135, have [5, 27] remain.
      ⁼      Check equality with...
       P       The product of the remaining numbers (5 and 17).

1

C(gcc),104字节

基本上,将“手动”乘以r []并在任何列大于9的情况下设置返回值,因为这将意味着发生进位。

令人惊讶的是,这比我第一次尝试使用字符串作为参数的尝试要短。

f(a,b){int*q,r[10]={0},*p=r,R=0,B;for(;a;a/=10)for(q=p++,B=b;B;B/=10)R|=(*q+++=a%10*(B%10))>9;return R;}

在线尝试!

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.