Descomponga un número con bit-xor sin los dígitos 0, 3, 7

20

Desafío

Escriba una función o programa que tome un número decimal positivo, llámelo A y genere dos números positivos, B y C , de modo que:

  • A == B bitxor C
  • B y C no deben contener ninguno de los dígitos 0, 3 o 7 en su representación decimal.

Ejemplos

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

Como la descomposición no es única, su función / programa no necesita generar exactamente los mismos resultados que estos ejemplos proporcionados.

Reglas muy detalladas

  1. Las presentaciones deben ser en forma de una función o programa completo . importdeclaraciones no cuentan para el marcador final.

  2. Puede suponer que la entrada A siempre contiene al menos un dígito de 0, 3 o 7.

  3. Puede suponer que siempre existe una descomposición.

  4. Puede usar BigInt si forman parte de las bibliotecas estándar del idioma o si se pueden instalar a través del administrador de paquetes de jure del idioma .

  5. La función debe ser rápida. No debería llevar más de 20 segundos ejecutarlo en una computadora razonablemente moderna cuando se ingresa un número de 100 dígitos, y no más de 2 segundos cuando se ingresa un número de 10 dígitos.

  6. La función / programa debe admitir la entrada de al menos 100 dígitos .

    • Si la función / programa solo admite números enteros de hasta N <100 dígitos, habrá una penalización de + 10 × (100 / N - 1) bytes a la puntuación final. Esto es para alentar a los golfistas a admitir una gama más amplia de números, incluso si la importación puede ser detallada.
  7. No hay restricción en la presentación de entradas / salidas siempre que estén claramente en representación decimal.

    • La función puede introducir y generar cadenas / BigInts si los tipos de enteros integrados no son suficientes.
    • La entrada puede provenir del parámetro de función, argumento de línea de comando o STDIN.
    • La función puede devolver el resultado o simplemente imprimir el resultado directamente en STDOUT.
    • Sin embargo, el desbordamiento firmado en las entradas / salidas no está permitido.
    • No se toleran respuestas aproximadas, las entradas / salidas deben ser exactas.

Puntuación

Este es un . La solución más corta en bytes gana.

Hay una penalización si el programa solo puede admitir números de menos de 100 dígitos:

  • Enteros de 64 bits (19 dígitos) = +42 bytes
  • Enteros de 63 bits (18 dígitos) = +45 bytes
  • Enteros de 53 bits (15 dígitos) = +56 bytes
  • Enteros de 31/32 bits (9 dígitos) = +101 bytes
kennytm
fuente
2
¿Estás seguro de que tal descomposición siempre es posible? ¿Puedes dibujarme una prueba?
John Dvorak, el
Alguien bloqueó 1, 5, 9 en la pregunta 95 Movie Quotes entonces.
jimmy23013
3
100 dígitos? eso significa que Python gana de inmediato, ya que es el único lenguaje comúnmente utilizado aquí que admite enteros de precisión arbitrarios. ¿Por qué no 19 dígitos, que cabe en un entero de 64 pero sin signo? (2 ^ 64 = 18 446 744 073 709 551 616)
Level River St
55
@steveverrill Mathematica ... GolfScript ... CJam ...
Martin Ender
1
Y Java (tenía que decir eso)
Ypnypn

Respuestas:

2

CJam, 70 bytes

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

Pruébalo en línea.

Selecciona aleatoriamente enteros hasta que encuentre una coincidencia. Esto apenas cumple con el límite de 20 segundos para enteros de 64 bits (utilizando el intérprete de Java), por lo que he agregado 42 al recuento de bytes real.

Ejecución de ejemplo

$ cjam t <<< 7777777777; echo
2695665494
6161166119
Dennis
fuente
10

Common Lisp, 240 224 183 173 169 bytes

Common Lisp es un poco detallado para jugar al golf. Sin embargo, esto descompone números de 100 dígitos en menos de un segundo, y enteros de 200 dígitos en menos de diez segundos, por lo que no hay necesidad de penalizaciones. El algoritmo es determinista.

(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#)))))(())))

El avance de línea entre las funciones es solo para fines tipográficos. Prueba de funcionamiento con la entrada de referencia de 100 dígitos:

(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)

Como beneficio adicional, incluyo una versión del código que construye de manera incremental la solución de arriba hacia abajo. Puede administrar un número de 1000 dígitos en menos de diez segundos, pero no puede competir en golf debido al código adicional.

(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
jlahd
fuente
2

Python 2, 103 + 42 = 145 bytes

Python admite de forma nativa bigints, pero este programa supera con creces los 20 segundos para un número de 100 dígitos. Sin embargo, descompone enteros de 64 bits en alrededor de 2 segundos.

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
Remy
fuente
1
Idea inteligente usando aleatoriedad. Si está definiendo una función, no necesita un whilebucle para seguir probando valores aleatorios; simplemente puede llamar a la función nuevamente. Sin necesidad de una estructura de control, a continuación, puede colapsar la función a una lambday una ternaria: from random import* d=lambda a,b=0:set(`b`+`a^b`)&set(\'037\')and d(a,randint(1,a))or(b,a^b). Aunque es mejor que no uses una función.
xnor
Consideré la recursividad, pero causa un desbordamiento de la pila para grandes números (incluso solo 11 dígitos).
Remy
1

Python 3 (132 bytes)

(Esto es solo para estimular mejores soluciones. Esta es mi solución al resolver el problema original en la película 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)

Aunque el comportamiento de xor bit a bit en el sistema decimal es bastante complicado, hay una observación importante: modificar los dígitos bajos no afectará a los dígitos altos . Por lo tanto, podemos trabajar de arriba hacia abajo: intente liberar los dígitos superiores de 0, 3, 7 y luego trabaje en el siguiente dígito, hasta que se resuelva el número entero. Esto nos permite ejecutar en tiempo lineal, luego el procesamiento de un número de mil dígitos puede completarse en menos de 1 segundo. (La solución Common Lisp también está utilizando la misma técnica, creo).

kennytm
fuente
Pero arreglar los dígitos bajos puede afectar los dígitos altos. Por ejemplo, 997^8 == 1005. Creo que hay un núcleo de una idea aquí, pero no es obvio.
Keith Randall el
@KeithRandall: Sí, es como 999 ... 999 + 1, pero, dada la elección de {1,2,4,5,6,8,9}, habría algunos de ellos que no afectarán a los dígitos altos. (por ejemplo 997^2 == 999) El whilebucle interno hace el agotamiento para encontrar la opción que mantenga válidos los dígitos altos.
kennytm
correcto, pero entonces no es obvio (para mí, al menos) que definitivamente hay un dígito que funcionará.
Keith Randall el