用位异或分解没有数字0、3、7的数字


20

挑战

编写一个采用正十进制数的函数或程序,将其称为A,然后输出两个正数BC,这样:

  • A == B bitxor C
  • BC的十进制表示形式不得包含数字0、3或7。

例子

>>> decompose(3)
1, 2
>>> decompose(7)
1, 6
>>> decompose(718)
121, 695
>>> decompose(99997)
2, 99999
>>> decompose(4294967296)
4294968218, 922
>>> decompose(5296080632396965608312971217160142474083606142654386510789497504098664630388377556711796340247136376)
6291484486961499292662848846261496489294168969458648464915998254691295448225881546425551225669515922,
1191982455588299219648819556299554251659915414942295896926425126251962564256469862862114191986258666

由于分解不是唯一的,因此您的函数/程序无需输出与提供的示例完全相同的结果。

非常详细的规则

  1. 提交应采用完整功能或程序的形式。import陈述确实计入最终分数。

  2. 您可以假设输入A始终至少包含数字0、3或7。

  3. 您可能会认为分解始终存在。

  4. 您可以使用BigInt(如果它们是该语言的标准库的一部分),或者可以通过该语言的法律包管理器进行安装。

  5. 该功能应该很快。输入100位数字时,在相当现代的计算机上运行应该不超过20秒,而输入10位数字时,应该不超过2秒。

  6. 功能/程序应支持至少100位数的输入。

    • 如果该功能/程序仅支持不超过N <100位的整数,则最终得分将受到+ 10×(100 / N-1)字节的惩罚。这是为了鼓励高尔夫球手支持更大范围的数字,即使输入可能很冗长。
  7. 上的呈现没有限制,只要它们是显然十进制表示的输入/输出。

    • 如果内置整数类型不足,则该函数可能会输入和输出字符串/ BigInts。
    • 输入可以来自功能参数,命令行参数或STDIN。
    • 该函数可以返回结果,或仅将结果直接打印到STDOUT。
    • 但是,不允许在输入/输出中签名溢出。
    • 不能接受近似答案,输入/输出必须准确。

计分

这是一个。以字节为单位的最短解决方案获胜。

如果程序只能支持少于100个数字的数字,则将受到处罚:

  • 64位整数(19位数字)= +42字节
  • 63位整数(18位数字)= +45字节
  • 53位整数(15位数字)= +56字节
  • 31/32位整数(9位)= +101字节

2
您确定这种分解总是可能的吗?你能给我写个证明吗?
约翰·德沃夏克

然后有人在95电影报价问题中屏蔽了1、5、9
jimmy23013

3
100位数?这意味着Python马上就赢了,因为它是这里唯一支持任意精度整数的常用语言。为什么不是19位数字(适合64位但无符号整数)?(2 ^ 64 = 18 446 744 073 709 551 616 616)
Level River St

5
@steveverrill Mathematica ... GolfScript ... CJam ...
Martin Ender

1
和Java(不得不说)
Ypnypn

Answers:


2

CJam,70个字节

ri:Q{;Qmr_Q^`1$`+730`&}g_Q^p

在线尝试。

随机选择整数,直到找到匹配项。这几乎不符合64位整数的20秒限制(使用Java解释器),因此我在实际字节数上增加了42。

运行示例

$ cjam t <<< 7777777777; echo
2695665494
6161166119

10

常见Lisp中,240个 224 183 173 169字节

Common Lisp对于打高尔夫球有点冗长。但是,这可以在一秒钟内分解100位数字,并在不到10秒的时间内分解200位整数,因此无需罚款。该算法是确定性的。

(defun s(z)(and #1=(some(lambda(q)(position q(format()"~a"z)))"037")(+ z(floor z(expt 10 #1#)))))
(defun d(x)(do((y x(or(s y)(s #3=(logxor x y))(return`(,y,#3#)))))(())))

函数之间的换行符仅用于印刷目的。使用100位参考输入进行测试运行:

(time (d 5296080632396965608312971217160142474083606142654386510789497504098664630388377556711796340247136376))
took 677,000 microseconds (0.677000 seconds) to run.
      20,989 microseconds (0.020989 seconds, 3.10%) of which was spent in GC.
During that period, and with 8 available CPU cores,
     671,875 microseconds (0.671875 seconds) were spent in user mode
           0 microseconds (0.000000 seconds) were spent in system mode
 54,221,104 bytes of memory allocated.
(1864921261592819619661568919418981552559955289196969112566252282429216186594265918444566258544614425
 5891958562486995519825158818455999516899524658151445485616155916296966645869599949958954491929662561)

作为奖励,我提供了一个自上而下逐步构建解决方案的代码版本。它可以在不到十秒钟的时间内管理1000位数字,但是由于附加的代码而无法参加高尔夫比赛。

(defun decompose (x)
  (flet ((s (z)
           (mapcan #'(lambda (c) (and #1=(position c #2=(format () "~a" z))
                                 (list (- (length #2#) #1# 1))))
                   '(#\0 #\3 #\7))))
    (do ((y x (let ((p (nconc (s y) (s #3=(logxor x y)))))
                (or p (return`(,y,#3#)))
                (+ y (expt 10 (apply #'max p))))))
        (nil))))

* (time (decompose (parse-integer (make-string 1000 :initial-element #\7))))
took 9,226,000 microseconds (9.226000 seconds) to run.
        90,966 microseconds (0.090966 seconds, 0.99%) of which was spent in GC.
During that period, and with 8 available CPU cores,
     9,234,375 microseconds (9.234375 seconds) were spent in user mode
             0 microseconds (0.000000 seconds) were spent in system mode
 487,434,560 bytes of memory allocated.
(8889898889152488921298888992819221914229899249999918899888899888888889999989141219898898888988988898888888888899142442899924898918898898988988895189988898888924192198992454114198911989191888889898888918888988988998888891421118891899122898888998989898888898988898888999988918888898889189918889888888899888989219188898998888988892119889198888988888894888912188898989952999888888888898899998988898889228918998949999998898898991141888898999988912121292118899889998989899999892889941898888911888898889118998898888911889889888891452888998889288921141888888942189888899988891918889118888888888989892198899199914111188988889421111188889118888918989988912989999998989891119888898888888892621229888988888999619888952462219889189899998899888889989898891118989218888888898962988891188899888888888999888888888888888888888891269188921288888888998898899214191188888888898992188998898889919888889989889899988892115549998888898889218899988998911898989199918898918988898888891889888989119899888889888998918889112189998
 4184469818464841952189561886965821566229261221619858498284264289194458622668559698924621446851546256444641488616184155821914881485164244662156846141894655485889656891849662551896595944656451462198891289692696856414192264846811616261884188919426294584158925218559295881946496911489245664261126565546419851585441144861859822815144162828551969425529258169849412525611662488849586554989254181228254465226521648916188265491499166186964881248156451994924294646681548996645996894665198811511522424996844864211629888924642289925565591484541149414914699289441561496451494562955652129199261462268846144518142486845251946444998812988291119592418684842524648484689261441456645518518812265495165189812912919529151991611962525419626921619824496626511954895189658691229655648659252448158451924925658586522262194585891859285841914968868466462442488528641466655911199816288496111884591648442984864269495264612518852292965985888414945855422266658614684922884216851481646226111486498155591649619266595911992489425412191)
* (apply #'logxor *)
7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777

2

Python 2,103 + 42 = 145字节

Python本身支持bigints,但是对于100位数字,此程序远远超过20秒。但是,它会在2秒钟左右分解64位整数。

from random import *
def d(a):
 b=c=0
 while set(`b`+`c`)&set('037'):
    b=randint(1,a);c=a^b
 return b,c

1
使用随机性的聪明主意。如果要定义函数,则不需要while循环就可以继续尝试随机值-您可以再次调用该函数。无需控制结构,然后可以将函数折叠为a lambda和三元:from random import* d=lambda a,b=0:set(`b`+`a^b`)&set(\'037\')and d(a,randint(1,a))or(b,a^b)。尽管不使用函数可能会更好。
xnor 2014年

我考虑过递归,但是它会导致大量(甚至只有11位)的堆栈溢出。
雷米2014年

1

Python 3(132字节)

(这只是为了激发更好的解决方案。这是我解决ASCII影片中原始问题时的解决方案。)

def d(a):
 l=len(str(a));s=int('1'*l);u=10**(l-1)
 while u:
  while set(str(s)+str((a^s)//u))&set('037'):s+=u
  u//=10
 print(s,a^s)

尽管十进制系统中按位异或的行为非常复杂,但是有一个主要观察结果:修改低位数字不会影响高位数字。因此,我们可以自上而下地工作:尝试使高位数字没有0、3、7,然后再处理下一位,直到计算出整个数字为止。这使我们可以线性运行,然后处理一千位数可以在1秒内完成。(Common Lisp解决方案也使用了我相信的相同技术。)


但是固定低位数字可能会影响高位数字。例如,997^8 == 1005。我认为这里有一个想法的核心,但这并不明显。
基思·兰德尔

@KeithRandall:是的,就像999…999 + 1,但是,如果选择{1,2,4,5,6,8,9},那么其中一些将不会影响高位数。(例如997^2 == 999)。内while循环会尽力寻找保持高位数字有效的选择。
kennytm 2014年

是的,但是显然(至少对我而言)肯定会有一个数字可以工作。
基思·兰德尔
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.