Operador decimal "XOR"


15

Muchos lenguajes de programación proporcionan operadores para manipular los dígitos binarios (base-2) de los enteros. Aquí hay una forma de generalizar estos operadores a otras bases:

Vamos x y y ser números de un solo dígito en la base B . Definir el operador unario ~y operadores binarios &, |y ^tal que:

  • ~ x = (B - 1) - x
  • x & y = min (x, y)
  • x | y = max (x, y)
  • x ^ y = (x & ~ y) | (y & ~ x)

Tenga en cuenta que si B = 2, obtenemos los operadores NOT, AND, OR y XOR a nivel de bits.

Para B = 10, obtenemos la tabla "XOR decimal":

^ │ 0 1 2 3 4 5 6 7 8 9
──┼────────────────────
0 │ 0 1 2 3 4 5 6 7 8 9
1 │ 1 1 2 3 4 5 6 7 8 8
2 │ 2 2 2 3 4 5 6 7 7 7
3 │ 3 3 3 3 4 5 6 6 6 6
4 │ 4 4 4 4 4 5 5 5 5 5
5 │ 5 5 5 5 5 4 4 4 4 4
6 │ 6 6 6 6 5 4 3 3 3 3
7 │ 7 7 7 6 5 4 3 2 2 2
8 │ 8 8 7 6 5 4 3 2 1 1
9 │ 9 8 7 6 5 4 3 2 1 0

Para números de varios dígitos, aplique el operador de un solo dígito dígito por dígito. Por ejemplo, 12345 ^ 24680 = 24655, porque:

  • 1 ^ 2 = 2
  • 2 ^ 4 = 4
  • 3 ^ 6 = 6
  • 4 ^ 8 = 5
  • 5 ^ 0 = 5

Si los operandos son de diferentes longitudes, rellene el más corto con ceros a la izquierda.

El reto

Escriba, en el menor número de bytes posible, un programa o función que tome como entrada dos enteros (que se puede suponer que están entre 0 y 999999999, inclusive) y genera el "XOR decimal" de los dos números como se definió anteriormente.

Casos de prueba

  • 12345, 24680 → 24655
  • 12345, 6789 → 16654
  • 2019, 5779 → 5770
  • 0, 999999999 → 999999999
  • 0, 0 → 0

¿Podemos tomar la entrada o salida como cadenas o matrices de caracteres?
Encarnación de la ignorancia

66
¿Qué tal una matriz de dígitos? ¿Es eso aceptable?
Encarnación de la ignorancia

1
¿Es 09un resultado aceptable para una entrada de 90, 99?
Neil

1
Ojalá hubiera una generalización que se mantuvieraA^B^B=A
trichoplax

2
@trichoplax, no puedes tener ambas a^b=b^ay a^b^b=apara bases con un divisor primo impar
mik el

Respuestas:


3

Jalea , 14 bytes

DUz0«9_ṚƊṀƊ€UḌ

Pruébalo en línea!

Cuadrícula de todos los pares de un solo dígito

Un enlace monádico que toma una lista de dos enteros como argumento y devuelve un entero.

Explicación

D               | Decimal digits
 U              | Reverse order of each set of digits
  z0            | Transpose with 0 as filler
          Ɗ€    | For each pair of digits, do the following as a monad:
    «   Ɗ       | - Minimum of the two digits and the following as a monad (vectorises):
     9_         |   - 9 minus the digits
       Ṛ        |   - Reverse the order
         Ṁ      | - Maximum
            U   | Reverse the order of the answer to restore the orignal order of digits
             Ḍ  | Convert back from decimal digits to integer

Si una matriz de dígitos es aceptable entrada / salida:

Jalea , 12 bytes

Uz0«9_ṚƊṀƊ€U

Pruébalo en línea!


2

Pyth , 31 bytes

LhS,hb-9ebjkmeS,ydy_d_.t_MjRTQ0

Pruébalo en línea!

LhS,hb-9eb             # Helper function, computes the (x & ~y) part
L                      # y = lambda b:
  S                    #               sorted(                )  
   ,                   #                       [    ,        ]
    hb                 #                        b[0]
      -9eb             #                              9-b[-1]
 h                     #                                       [0] # sorted(...)[0] = minimum

jkmeS,ydy_d_.t_MjRTQ0  # Main program (example input Q: [123, 45])
                jRTQ   # convert each input to a list of digits -> [[1,2,3],[4,5]]
              _M       # reverse each -> [[3,2,1],[5,4]]
            .t      0  # transpose, padding right with 0 -> [[3,5],[2,4],[1,0]]
           _           # reverse -> [[1,0],[2,4],[3,5]]
  m                    # map that over lambda d:
    S,                 #   sorted([    ,           ])
      yd               #           y(d)
        y_d            #                 y(d[::-1])         # reversed
   e                   #                             [-1]   # sorted(...)[-1] = maximum
jk                     # ''.join( ^^^ )


1

Adelante (gforth) , 111 bytes

: m 10 /mod rot ;
: t 9 swap - min ;
: f 2dup + 0> if m m recurse 10 * -rot 2dup swap t -rot t max + 1 then * ;

Pruébalo en línea!

Explicación del código

: m          \ start a new word definition
  10 /mod    \ get quotient and remainder of dividing by 10
  rot        \ move item in 3rd stack position to top of stack
;            \ end word definition

\ word implementing "not" followed by "and"
: t          \ start a new word definition
  9 swap -   \ subtract top stack element from 9
  min        \ get the minimum of the top two stack elements
;            \ end word definition

: f          \ start a new word definition
  2dup +     \ duplicate top two stack elements and add them together
  0> if      \ if greater than 0
    m m      \ divide both by 10, move remainders behind quotients
    recurse  \ call self recursively
    10 *     \ multiply result by 10 (decimal left shift of 1)
    -rot     \ get remainders from original division
    2dup     \ duplicate both remainders 
    swap t   \ swap order and call t (b & !a)
    -rot t   \ move result back and call t on other pair (a & !b)
    max + 1  \ get the max of the two results and add to total. put 1 on top of stack
  then       \ end if block
  *          \ multiply top two stack results (cheaper way of getting rid of extra 0)
;            \ end word definition

1

C # (compilador interactivo de Visual C #) , 75 bytes

a=>b=>a.Select((x,y)=>Math.Max(9-x<(y=y<b.Count?b[y]:0)?9-x:y,9-y<x?9-y:x))

Guardado 6 bytes gracias a @someone

Pruébalo en línea!


76 bytes . Creo que esta pregunta podría ser una oportunidad única para usar Zip.
mi pronombre es monicareinstate el

1
@ alguien Gracias! En cuanto a Zip, no puede usarlo ya que trunca automáticamente la colección más larga a la longitud de la más corta
Encarnación de la ignorancia

0

PHP , 111 109 bytes

for(;''<($a=$argv[1][-++$i]).$b=$argv[2][-$i];)$s=min($a<5?9-$a:$a,max($a<5?$a:9-$a,$a<5?$b:9-$b)).$s;echo$s;

Pruébalo en línea!

Pruebas: ¡ Pruébelo en línea!

Si llamamos a los dígitos, queremos XOR $ay $bdescubrí que:

  • Cuando $aes menos de 5,XOR = min(9-$a, max($a, $b))
  • Cuando $aes igual o mayor que 5,XOR = min($a, max(9-$a, 9-$b))

Así que implementé esta lógica más un truco para manejar números con diferentes longitudes. Tomo cada formulario dígitos al final de los dos números de entrada (con índices negativos como input[-1], input[-2], ...) y calcular el XOR y poner el resultado en el orden inverso en una cadena que se imprimirá al final. Como tomo dígitos del final de los números, los resultados de XOR deben agruparse en orden inverso. Cuando una de las entradas es más larga que la otra, el índice negativo en una entrada más corta da como resultado una cadena vacía que es igual a 0.


0

Retina , 85 59 bytes

^'0P`.+
N$`.
$.%`
¶

/../_(`^
$"
T`d`Rd`.¶.
%N`.
^N`..
L`^.

Pruébalo en línea! Toma la entrada como líneas separadas, pero el enlace es para probar una suite que reformatea la entrada separada por comas. Explicación:

^'0P`.+

Almohadilla izquierda con ceros ambas líneas a la misma longitud.

N$`.
$.%`
¶

Ordene cada dígito por su índice de columna, luego elimine la nueva línea. Esto tiene el efecto de emparejar los dígitos juntos de la misma manera que lo haría una transposición.

/../_(`

Aplique por separado a cada par de dígitos, uniendo los resultados.

^
$"

Duplicar el par.

T`d`Rd`.¶.

Invierta el segundo dígito del primer par y el primer dígito del segundo, por lo que ahora tenemos x ~yen una línea y ~x yen la otra.

%N`.

Ordene los dígitos de cada línea en orden, de modo que el primer dígito sea ahora x & ~yo ~x & ysegún corresponda.

^N`..

Invertir ordenar las líneas.

L`^.

Y extraiga el primer dígito, que es el resultado deseado.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.