Agregar sin usar un signo + o -

24

Ha habido muchos desafíos de "Hacer __ sin _ _" antes, pero espero que este sea uno de los más desafiantes.

El reto

Debe escribir un programa que tome dos números naturales (números enteros> 0) de STDIN e imprima la suma de los dos números en STDOUT. El desafío es que debe usar la menor cantidad posible de signos +y -señales. No está permitido utilizar ninguna función de suma o negación.

Ejemplos

entrada

123
468

salida

591

entrada

702
720

salida

1422

Desempate: Si dos programas tienen el mismo número de +y -caracteres, el ganador es la persona con menos / * ( ) = . ,y 0-9caracteres.

No permitido: idiomas en los que los operadores estándar de suma / resta e incremento / decremento son símbolos distintos +o -no están permitidos. Esto significa que el espacio en blanco no permite el idioma.

PhiNotPi
fuente
1
Quizás este desafío fue mucho más fácil de lo que pensé que sería, especialmente en otros idiomas, donde hay funciones sum (). Tengo que arreglar esto.
PhiNotPi
50
Recompensa de 100 repeticiones para cualquiera que pueda hacer esto en Brainfuck.
Peter Olson
3
@Peter Olson Bueno, supongo que BF no está completo sin ninguno de los dos +o -...
FUZxxl
3
Solo para aclarar, a este desafío no le importa la longitud del código, ¿verdad? Sólo el número de +, -y personajes de desempate? ... o necesita cambiar las reglas nuevamente :-)
Tommy
@ Tommy No, no lo hace.
PhiNotPi

Respuestas:

29

Perl (sin +/-, sin desempates, 29 caracteres)

s!!xx!;s!x!$"x<>!eg;say y!!!c

Como beneficio adicional, puede hacer que el código sume más de dos números agregando más xs al s!!xx!.

Alternativamente, aquí hay dos soluciones de 21 caracteres con 1 y 3 interruptores de corbata respectivamente

say length$"x<>.$"x<>

say log exp(<>)*exp<>

Nota: Estas soluciones usan la sayfunción, disponible desde Perl 5.10.0 con el -Einterruptor de línea de comando o con use 5.010. Consulte el historial de edición de esta respuesta para ver las versiones que funcionan en perls anteriores.


¿Cómo funciona la solución sin desempates?

  • s!!xx!es un operador de reemplazo de expresiones regulares , que opera de manera predeterminada en la $_variable, que reemplaza la cadena vacía con la cadena xx. (Por /lo general, se usa como delimitador de expresiones regulares en Perl, pero en realidad se puede usar casi cualquier personaje. Elegí !ya que no es un desempate). Esta es solo una forma elegante de "xx"pretender $_- o, ya que $_comienza vacío (indefinido, en realidad), es realmente una forma de escribir $_ = "xx"sin usar el signo igual (y con un carácter menos, también).

  • s!x!$"x<>!eges otro reemplazo expresión regular, esta vez reemplazando cada xen $_con el valor de la expresión $" x <>. (El gmodificador especifica el reemplazo global, eespecifica que el reemplazo debe evaluarse como código Perl en lugar de usarse como una cadena literal). $"Es una variable especial cuyo valor predeterminado es un solo espacio; usarlo en lugar de " "guardar un personaje. (Cualquier otra variable que se sepa que tiene un valor de un carácter, como $&o $/, funcionaría igualmente bien aquí, excepto que usarla $/me costaría un desempate).

    El <> operador de entrada de línea , en contexto escalar, lee una línea de la entrada estándar y la devuelve. El xantes es el operador de repetición de cadena Perl , y es realmente el núcleo de esta solución: devuelve su operando izquierdo (un carácter de espacio único) repetido el número de veces dado por su operando derecho (la línea que acabamos de leer como entrada).

  • y!!!ces solo una forma oscura de (ab) usar el operador de transliteración para contar los caracteres en una cadena ( $_de forma predeterminada, de nuevo). Podría haber escrito say length, pero la versión ofuscada es un carácter más corto. :)

Ilmari Karonen
fuente
3
+1: impresionante y totalmente ilegible ;-) Esta parece ser la respuesta perfecta ya que el conteo de personajes no importa en este desafío.
Tommy
@ Tommy, también hay otras respuestas perfectas. Tal vez deberíamos presionar para que el recuento de personajes sea el último desempate.
Peter Taylor
@ Peter: de alguna manera asumí que ya lo era, por defecto.
Ilmari Karonen
1
si el recuento de caracteres es el último desempate, y existen muchas entradas empatadas para cero en las otras categorías, ¿no se convierte esto code-golfcon algunas restricciones de origen?
Sparr
47

R (24 caracteres)

length(sequence(scan()))

Qué hace esto:

  • scan lee la entrada de STDIN (o un archivo)
  • sequencegenera secuencias enteras a partir de 1 y concatena las secuencias. Por ejemplo, sequence(c(2, 3))resultados en el vector1 2 1 2 3
  • length calcula el número de elementos en el vector concatenado

Ejemplo 1:

> length(sequence(scan()))
1: 123
2: 468
3:
Read 2 items
[1] 591

Ejemplo 2

> length(sequence(scan()))
1: 702
2: 720
3:
Read 2 items
[1] 1422
Andrie
fuente
1
Muy inteligente, buen trabajo.
Matthew leyó el
Esto me
deja sin aliento
+/- y los desempates mencionados anteriormente son interesantes, no personajes.
usuario desconocido
¿Cómo calcula la longitud? sin usar ninguna adición? Si es así, me sorprendería.
Tem Pora
2
@TemPora La pregunta solo restringe el código en la respuesta, no las operaciones realizadas detrás de escena. No vamos a restringir la pregunta para que la arquitectura informática subyacente no pueda incrementar un registro.
mbomb007
15

re

main(){
    int a,b;
    readf("%d %d",&a,&b);
    while(b){a^=b;b=((a^b)&b)<<1;}
    write(a);
}

poco jugando para ganar

Como beneficio adicional, el código compilado no contiene una operación de agregar (aunque no puede hablar por la llamada readf)

monstruo de trinquete
fuente
12

Python 2, 43 bytes

print len('%s%s'%(input()*'?',input()*'!'))
Omar
fuente
3
Muy ingenioso, pero es posible que desee cambiar el carácter utilizado en la cadena a algo diferente a un desempate como "~"
3Doubloons
Gracias por el consejo Alex, ya me había olvidado de la regla de desempate.
Omar
print sum(input(),input())
razpeitia
99
razpeitia: Creo que la suma es una función de "suma" y, por lo tanto, no está permitida.
Omar
6

GolfScript

No +/- o desempates:

# Twiddle some bits to get a few small integers
[]!~abs:two~abs:three!:zero~:minusone;

~[two base minusone%\two base minusone%]zip
zero:c;
{
    # Stack holds [x y] or [x] with implicit y is zero
    # Half adder using x y c: want to end up with sum on stack and carry back in c
    [~c zero]three<zero$
    ~^^\
    $~;:c;;
}%
[~c]minusone%two base

Versión mucho más simple con dos personajes de desempate, usando el mismo truco de concatenación de listas que otras personas están usando:

~[\]{,~}%,

Supongo que GolfScript no está descalificado por tener )como operador de incremento, ya que en realidad no lo estoy usando.

Peter Taylor
fuente
6

C (solo 32 bits)

int main(int ac, char *av) {
    scanf("%d\n%d", &ac, &av);
    return printf("%d\n", &av[ac]);
}

La aritmética del puntero es igual de buena.
¿Cómo coincide con los requisitos?
* No +o -
* n /, =, ., 0- 9
* Sólo 3 pares de paréntesis, lo que parece a mí mínima (que necesita main, scanf, printf).
* Uno *(el enfoque del puntero lo requiere).
* Cuatro ,(podría guardar uno definiendo variables normales, no ac,av)

Uri Goren
fuente
6

C ++ 0 +/-, 3 desempates

#include <vector>
#include <iostream>

#define WAX (
#define WANE )
#define SPOT .

int main WAX WANE {
    unsigned x;
    unsigned y;
    std::cin >> x >> y;
    std::vector<int> v WAX x WANE;
    std::vector<int> u WAX y WANE;
    for WAX auto n : u WANE {
        v SPOT push_back WAX n WANE;
    }
    std::cout << v SPOT size WAX WANE;
}
R. Martinho Fernandes
fuente
5

Haskell, 0 + 2

import Monad
main = join $ fmap print $ fmap length $ fmap f $ fmap lines getContents
f x = join $ flip replicate [] `fmap` fmap read x

Esto usa no +o -caracteres, y solo dos =del conjunto de caracteres de desempate, uno de los cuales es obligatorio para el enlace main. La suma se realiza mediante la concatenación de listas de las longitudes apropiadas.

hammar
fuente
4

EDITAR Esto fue publicado ANTES de que las reglas cambiaran para no permitir sum...

El lenguaje R: No hay llamadas +ao -... ¡Y 9 personajes de desempate!

sum(as.numeric(readLines(n=2)))

Ejemplo:

> sum(as.numeric(readLines(n=2)))
123
456
[1] 579

El [1] 579es la respuesta 579 (el [1]es hacer un seguimiento de dónde se encuentra en el vector de resultados ya que en R todos los valores son vectores, en este caso de longitud 1)

Tenga en cuenta que R tiene +operadores al igual que la mayoría de los lenguajes; resulta que también tiene operadores sumque resumen un montón de vectores.

En este caso, readLinesdevuelve un vector de cadena de longitud 2. Luego lo coacciono a numérico (dobles) y lo sumo ...

Solo para mostrar algunas otras características de R:

> 11:20 # Generate a sequence
 [1] 11 12 13 14 15 16 17 18 19 20

> sum(1:10, 101:110, pi)
[1] 1113.142
Tommy
fuente
1
+1 Por hacerme tener que cambiar las reglas para prohibir la función sum ().
PhiNotPi
@PhiNotPi - ¿Cambiando las reglas? ¡Eso es hacer trampa! :-) ... Pero probablemente deberías decir "funciones similares a la suma" o simplemente las usaré colSumsen su lugar ... Tal vez también prohíba las "funciones similares a la negación" mientras estás en eso ...
Tommy
2
Voy a seguir tu consejo. Por lo que puedo decir, a todos (incluido yo) en este sitio nos encanta señalar las lagunas en las reglas.
PhiNotPi
4

El lenguaje R

Nuevas reglas, nueva respuesta, mismo lenguaje. No hay llamadas +ao-

ACTUALIZACIÓN Usando scan, se reduce a 11 caracteres de desempate (y 27 caracteres en total).

as.numeric(scan())%*%c(1,1)

Original: 13 personajes de desempate!

as.numeric(readLines(n=2)) %*% c(1,1)

Ejemplo:

> as.numeric(readLines(n=2)) %*% c(1,1)
123
456
     [,1]
[1,]  579

Esta vez, el resultado se logra mediante la multiplicación de matrices. La respuesta se muestra como una matriz 1x1.

Tommy
fuente
No hay nada que pueda hacer para prohibir esto. Quizás R sea bueno en este desafío, ya que se basa principalmente en las matemáticas. O tal vez este desafío es simplemente fácil.
PhiNotPi
+1 Niza. Puede hacer esto aún más corto con scan()en lugar dereadlines(n=2)
Andrie
@Andrie - Sí, pero entonces se basan en el usuario que introduce exactamente dos números ... que está bien para este desafío supongo ...
Tommy
4

Haskell, 0 +/ -, 6 2 desempates ( =)

(no utiliza el truco de concatenación de cadena / lista)

main = interact f
f x = show $ log $ product $ map exp $ map read $ lines x
JB
fuente
Puede eliminar todos los puntos a expensas de un extra = reemplazando la composición: en lugar de "fgh" escriba "a where ax = f $ g $ h x"
Omar
3

Javascript, 56

p=prompt;alert(Array(~~p()).concat(Array(~~p())).length)

¡Gracias a @JiminP por el ~~ consejo! Voy por menos bytes, por lo que el 1 byte se guarda en el indicador p =; Todavía vale la pena. Entiendo su argumento sobre los caracteres de desempate, pero para ser honesto, ¿no preferiría la menor cantidad de bytes :-p

Versión 69

i=parseInt;p=prompt;alert(Array(i(p())).concat(Array(i(p()))).length)

Gracias a algunos comentarios de @Ilmari y @JiminP, he reducido 13 bytes de mi solución original.

Originalmente, 82

i=parseInt;p=prompt;a=Array(i(p()));a.push.apply(a, Array(i(p())));alert(a.length)
stephencarmody
fuente
Ese espacio después de la coma es completamente innecesario; eliminarlo te lleva a 81.
Ilmari Karonen
Usar concaty poner cálculos alertes más corto. i=parseInt;p=prompt;alert(Array(i(p())).concat(Array(i(p()))).length) Por cierto, no sabía que Array(n)devuelve una matriz con longitud n. La consola de Google Chrome me dio []y pensé que no había nada ...
JiminP
1
Oh, ya que lo importante son los personajes de desempate, p=promptno es bueno. Y, parseInt(x)es casi equivalente a ~~x. alert(Array(~~prompt())['concat'](Array(~~prompt()))['length'])(12 caracteres de desempate) PS. Podría usar esto como mi entrada, pero eso solo me da la sensación de robar.
JiminP
3

do

b[500];i;j;main(){scanf("%d%d",&i,&j);printf("%d\n",sprintf(b,"%*s%*s",i,"",j,""));
Patricio
fuente
3

APL (sin +/-, sin disyuntores, 8 o 10 caracteres)

Esta entrada es similar a las otras que concatenan secuencias generadas a partir de la entrada y encuentran la longitud ... pero está en APL, lo que puede parecer confuso incluso para un pequeño problema como este. Utilicé Dyalog APL , que ofrece una licencia educacional libre.

Código:

⍴⊃⍪⌿⍳¨⎕⎕

De derecha a izquierda:

  • Cada cita-quad ( ) solicita la entrada del usuario y la evalúa.
  • Cada operador ( ¨) aplica la función de generador de índice ( ) a cada uno de los elementos de la matriz a su derecha.
  • Esto aplana la matriz resultante de matrices en una matriz. La matriz de entrada se reduce a una lista plana por el operador de reducción ( /), que pliega la matriz utilizando la función de concatenación ( ,). En aras de este desafío, se utiliza el operador de reducción unidimensional ( ), junto con el operador de concatenación a lo largo del primer eje ( ).
  • Como resultado del uso del operador de reducción, la matriz está encerrada , que es como colocarla en la bolsa; todo lo que vemos en el exterior es una bolsa, no su contenido. El operador revelar ( ) nos proporciona el contenido de la matriz incluida (la bolsa).
  • Finalmente, la forma de la función ( ) nos da las longitudes de las dimensiones de una matriz. En este caso, tenemos una matriz unidimensional, por lo que obtenemos el número de elementos en la matriz, que es nuestro resultado.

Si necesitamos generar explícitamente el resultado, podemos hacerlo así:

⎕←⍴⊃⍪⌿⍳¨⎕⎕

Código de Python comparable, con los símbolos APL correspondientes arriba:

import operator

⎕←     ⍴    ⌿        ⍪                 ¨              ⍳                ⎕        ⎕         ⊃
print (len (reduce (operator.__add__, [map (lambda n: range (1, n+1), [input(), input()])][0])))

Me gustaría saber si hay una versión más corta posible en APL - otra versión más simple que se me ocurrió que tiene más de desempate (aunque todavía a 8 caracteres) es: ⍴(⍳⎕),⍳⎕.

Dillon Cower
fuente
¿Su generador de índice comienza en 1 o 0?
MrZander
3

No vi a nadie hacerlo de la manera de Ingeniería Eléctrica, así que aquí está mi opinión (en rubí):

def please_sum(a, b)
    return (a&b !=0)? please_sum( ((a&b)<<1) , a^b ):a^b
end

Es un poco feo, pero hace el trabajo. Los dos valores se comparan por bit a bit AND. Si no tienen ningún bit en común, no hay "acarreo" en la siguiente columna binaria, por lo que la adición se puede completar haciendo un bit XORa bit . Si hay un acarreo, debe agregar el acarreo al bit XOR. Aquí hay un pequeño script de ruby ​​que usé para asegurarme de que mi lógica digital no estuviera demasiado oxidada:

100.times do
    a=rand 10
    b=rand 10
    c=please_sum(a,b)
    puts "#{a}+#{b}=#{c}"
    end

¡Aclamaciones!

Noah
fuente
3

Semilla , 3904 3846 11 bytes, 0 +/-, 10 disyuntores

4 141745954
Krzysztof Szewczyk
fuente
2

Shell, 52

read a
read b
(seq 1 $a;seq 1 $b)|wc|awk '{print$1}'

Esta es básicamente la misma respuesta que di para otro problema.

Joey Adams
fuente
Similar: xargs -n1 jot | wc -lque toma la misma -reducción awkpero no puedo ver cómo evitarla en elxargs
Ben Jackson
+/- y los desempates mencionados anteriormente son interesantes, no personajes.
usuario desconocido
2

do

a,b;A(int a,int b){return a&b?A(a^b,(a&b)<<1):a^b;}
main(){scanf("%d%d",&a,&b);printf("%d\n",A(a,b));}
saeedn
fuente
Cuento 20 desempates ... ¿Estoy en lo cierto?
FUZxxl
2
22 desempates: 0 /*=., 7 (, 7 ), 7 ,, 1[0-9]
saeedn
2

DO#

No es el más corto de ninguna manera:

private static int getIntFromBitArray(BitArray bitArray)
{
    int[] array = new int[1];
    bitArray.CopyTo(array, 0);
    return array[0];
}

private static BitArray getBitArrayFromInt32(Int32 a)
{
    byte[] bytes = BitConverter.GetBytes(a);
    return new BitArray(bytes);
}

static void Main(string[] args)
{
    BitArray first = getBitArrayFromInt32(int.Parse(Console.ReadLine()));
    BitArray second = getBitArrayFromInt32(int.Parse(Console.ReadLine()));
    BitArray result = new BitArray(32);

    bool carry = false;
    for (int i = 0; i < result.Length; i++)
    {
        if (first[i] && second[i] && carry)
        {
            result[i] = true;
        }
        else if (first[i] && second[i])
        {
            result[i] = false;
            carry = true;
        }
        else if (carry && (first[i] || second[i]))
        {
            result[i] = false;
            carry = true;
        }
        else
        {
            result[i] = carry || first[i] || second[i];
            carry = false;
        }
    }
    Console.WriteLine(getIntFromBitArray(result));
}
Matthew Steeples
fuente
Eso es agotador, Matthew.
Cary Swoveland
2

J, 15 7 caracteres, 1 desempate, programa incompleto

Este es mi intento de J. No es un programa completo, porque todavía no he descubierto cómo escribir uno. Simplemente ponga esa línea en un script para obtener la función pque se puede usar para agregar una cantidad arbitraria de números. Es una mónada y toma una lista de números para agregar (como p 1 2 3 4):

p=:#@#~

La idea es muy simple. La función está escrita en tácito, también conocido como estilo sin sentido. Aquí hay una definición puntiaguda:

p=:3 :'##~y'

Lee de derecha a izquierda. En la versión tácita, @compone las partes de la función. (como un ∘ en matemáticas [(f∘g) (x) = f (g (x)])

  • yes el parámetro de p.
  • ~hace un verbo reflexivo. Para algún verbo m, m~ aes igual a a m a.
  • #(copia, a#b): Cada elemento en ase replica iveces, donde iestá el elemento en el mismo índice que el elemento actual ade b. Por lo tanto, #~replica un elemento n nveces.
  • #(cuenta, #b): Cuenta el número de elementos en b.

Conclusión: J es impresionante y menos legible que Perl (eso lo hace aún más impresionante)

Ediciones

  • 15 -> 7 usando en #lugar de i.. ¡Sí! Menos caracteres que golfscript.

Más de un programa

Este consulta la entrada, pero aún no es un programa completo: (13 caracteres, 3 interruptores)

##~".1!:1<#a:
FUZxxl
fuente
J es definitivamente increíble, pero créeme, no puedes dejar de lado la parte de análisis del problema cuando resuelves desafíos con él ;-)
JB
@JB Bueno, puedes usar la función incorporada toJ, pero sigo recibiendo errores de dominio.
FUZxxl
2

Javascript (17 caracteres de desempate)

eval('걢갽거걲걯걭거건갨걡갽거걲걯걭거건갨걹갽걦걵걮걣건걩걯걮갨걡갩걻걣갽걮걥걷갠걕걩걮건갸걁걲걲걡걹갨걡갩갻걦걯걲갨걩갠걩걮갠걣갩걩걦갨걩갽갽걾걾걩갩걸갮거걵걳걨갨갱갩걽갬걸갽걛걝갩갩갻걹갨걡갩갻걹갨걢갩갻걡걬걥걲건갨걸갮걬걥걮걧건걨갩갻'['split']('')['map'](function(_){return String['fromCharCode'](_['charCodeAt'](~~[])^0xac00)})['join'](''))

: P ("Ofuscado" para reducir el número de caracteres de desempate. Internamente, es b=prompt(a=prompt(y=function(a){c=new Uint8Array(a);for(i in c)if(i==~~i)x.push(1)},x=[]));y(a);y(b);alert(x.length); ).

JiminP
fuente
2

DO#,

El programa funciona en 1 línea; separados en múltiples líneas para evitar el desplazamiento horizontal.

using C=System.Console;
class A{
static void Main(){
int a,b,x,y;
a=int.Parse(C.ReadLine());
b=int.Parse(C.ReadLine());
do{x=a&b;y=a^b;a=x<<1;b=y;}while(x>0);
C.WriteLine(y);
}}
sirchristian
fuente
1

Clojure (44 caracteres)

(pr(#(count(concat(%)(%)))#(repeat(read)0)))

Editar: arreglado para imprimir en STDOUT en lugar de simplemente devolver la suma.

Omar
fuente
+/- y los desempates mencionados anteriormente son interesantes, no personajes.
usuario desconocido
1

Scala

  • Puntuación:
    • + -: 0
    • () : 5 + 5 + 3 = 13

Código:

(List.fill (readInt) (1) ::: List.fill (readInt) (2)).size
  • List.fill (4) (7) produce List (7, 7, 7, 7)
  • a ::: b concatena 2 listas en una
  • El resto debería ser obvio
usuario desconocido
fuente
1

K, 11

{#,[!x;!y]}

El mismo truco de concatenación que la solución R. Lectura de derecha a izquierda: enumera las dos variables de entrada, concatena y luego cuenta.

tmartin
fuente
1

PowerShell , 27 42 bytes, 0 +-, 4 1 secundario

Gracias a mazzy por guardar ay +4 secundarias

$args|%{[int[]]$_*$_}|measure|select count

Pruébalo en línea! o Pretty Table para 3 bytes adicionales

O bien, agregar cuatro secundarios para guardar 19 bytes:

32 23 bytes, 1 0 +-, 12 5 secundarios

-9 bytes gracias a mazzy

($args|%{,$_*$_}).count

Pruébalo en línea!

Para cada argumento, empujamos nelementos de matriz (que consisten en, [n]pero eso no es importante) a la tubería que se agrupan por los pares y luego se cuentan.

Veskah
fuente
1
Lo siento, esto NO es codegolf. 0 + -, 3 segundos, 27 bytes
mazzy
1
@mazzy Eso es 4 por mi cuenta, pero no obstante gracias: D
Veskah
1
tienes razón. Gracias. 0 + -, 1 desempate, 42 bytes . podrías agregar |flun bonito formato ¡ Pruébalo en línea!
mazzy
1

Keg (SBCS en la wiki de Keg)

Básicamente un puerto de la respuesta R.

¿¿Ï_"Ï_!.

Explicación

¿¿#        Take 2 integer inputs
  Ï_"Ï_#   Generate 2 arrays the length of the integer inputs
       !.# Output the length of the stack
UNA
fuente
1

05AB1E , 2 4 bytes, 0+ /-

F>

Pruébalo en línea!

Disculpas si entendí mal este desafío, pero me sorprendió que no hubiera una respuesta 05AB1E. La respuesta más corta en este idioma que se me ocurre que no usa + o la función de suma incorporada.

Explicación:

 F   #Loop A many times
  >  #Increment B
     #(Implicit output)

-2 Bytes gracias a Grimy.

Bismarck71
fuente
1
¡Gracias! Todavía soy nuevo en 05AB1E.
Bismarck71
1

Python 3

Sin depender de sumas ocultas en otras funciones.

h=input;x,y=int(h()),int(h())
while y:c=x&y;x^=y;y=c<<1
print(x)

Pruébalo en línea!

Hunaphu
fuente
0

re

main(){
    int a,b;
    readf("%d %d",&a,&b);
    write((new int[a]~new int[b]).length);
}

esta vez usando longitudes de matriz

monstruo de trinquete
fuente