Adicionando sem usar um sinal de + ou -

24

Já houve muitos desafios "Não __ sem _ _" antes, mas espero que este seja um dos mais desafiadores.

O desafio

Você deve escrever um programa que use dois números naturais (números inteiros> 0) de STDIN e imprima a soma dos dois números em STDOUT. O desafio é que você deve usar o mínimo de sinais +e -sinais possíveis. Você não tem permissão para usar nenhuma função de soma ou negação.

Exemplos

entrada

123
468

saída

591

entrada

702
720

saída

1422

Desempatador: Se dois programas tiverem o mesmo número de caracteres +e -, o vencedor será a pessoa com menos caracteres / * ( ) = . ,e 0-9.

Não permitido: idiomas nos quais os operadores padrão de adição / subtração e incremento / decremento são símbolos diferentes +ou -não são permitidos. Isso significa que o espaço em branco no idioma não é permitido.

PhiNotPi
fonte
11
Talvez esse desafio tenha sido muito mais fácil do que eu pensava, especialmente em outros idiomas, onde existem funções sum (). Eu tenho que consertar isso.
PhiNotPi
50
Recompensa de 100 representantes para quem puder fazer isso em Brainfuck.
Peter Olson
3
@ Peter Olson Bem, acho BF não é turing completa sem qualquer +ou -...
FUZxxl
3
Só para esclarecer, esse desafio não se importa com o tamanho do código, certo? Apenas o número de +, -e desempate personagens? ... ou você precisa mudar as regras novamente :-)
Tommy
@ Tommy Não, não.
PhiNotPi

Respostas:

29

Perl (sem +/-, sem desempate, 29 caracteres)

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

Como bônus, você pode fazer o código somar mais de dois números adicionando mais xs ao s!!xx!.

Como alternativa, aqui estão duas soluções de 21 caracteres com 1 e 3 desempatadores, respectivamente

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

say log exp(<>)*exp<>

Nota: Essas soluções usam a sayfunção, disponível desde o Perl 5.10.0 com a -Eopção de linha de comando ou com use 5.010. Veja o histórico de edições desta resposta para versões que funcionam em perls mais antigos.


Como funciona a solução sem desempate?

  • s!!xx!é um operador de substituição de regexp , operando por padrão na $_variável, que substitui a cadeia vazia pela cadeia xx. (Normalmente /é usado como delimitador regexp em Perl, mas realmente quase qualquer personagem pode ser usado eu escolhi. !Já que não é um tie-breaker.) Esta é apenas uma maneira elegante de antecedendo "xx"a $_- ou, uma vez que $_começa vazio (indefinido, na verdade), é realmente uma maneira de escrever $_ = "xx"sem usar o sinal de igual (e com um caractere a menos também).

  • s!x!$"x<>!egé outra substituição de expressão regular, desta vez substituindo cada xno $_com o valor da expressão $" x <>. (A gopção especifica substituição global, eespecifica que a substituição deve ser avaliada como código Perl em vez de ser usada como uma seqüência literal.) $"É uma variável especial cujo valor padrão passa a ser um espaço único; usá-lo em vez de " "salvar um caractere. (Qualquer outra variável conhecida por ter um valor de um caractere, como $&ou $/, funcionaria igualmente bem aqui, exceto que o uso $/me custaria um desempate.)

    O <> operador de entrada de linha , no contexto escalar, lê uma linha da entrada padrão e a retorna. O xantes é o operador de repetição de strings Perl e é realmente o núcleo desta solução: retorna seu operando esquerdo (um caractere de espaço único) repetido o número de vezes fornecido pelo seu operando direito (a linha que acabamos de ler como entrada).

  • y!!!cé apenas uma maneira obscura de (ab) usar o operador de transliteração para contar os caracteres em uma string ( $_por padrão, novamente). Eu poderia ter escrito say length, mas a versão ofuscada é um personagem menor. :)

Ilmari Karonen
fonte
3
+1 - impressionante e totalmente ilegível ;-) Essa parece ser a resposta perfeita, pois a contagem de caracteres não importa neste desafio.
Tommy
@ Tommy, existem outras respostas perfeitas também. Talvez devêssemos pressionar para que a contagem de caracteres seja o empate final.
Peter Taylor
@ Peter: Eu meio que assumi que já era, por padrão.
Ilmari Karonen
11
se a contagem de caracteres é o desempate final e existem muitas entradas vinculadas a zero nas outras categorias, isso não acontece apenas code-golfcom algumas restrições de origem?
Sparr 19/09
47

R (24 caracteres)

length(sequence(scan()))

O que isso faz:

  • scan lê a entrada de STDIN (ou um arquivo)
  • sequencegera sequências inteiras a partir de 1 e concatena as seqüências. Por exemplo, sequence(c(2, 3))resultados no vetor1 2 1 2 3
  • length calcula o número de elementos no vetor concatenado

Exemplo 1:

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

Exemplo 2:

> length(sequence(scan()))
1: 702
2: 720
3:
Read 2 items
[1] 1422
Andrie
fonte
11
Muito inteligente, bom trabalho.
Matthew Leia
Isso me
impressiona
+/- e acima mencionados desempate são interessantes, não personagens.
usuário desconhecido
Como calcula o comprimento? sem usar qualquer adição? Se assim for, eu ficaria surpreso.
Tem Pora 28/09
2
@TemPora A pergunta restringe apenas o código na resposta, não as operações realizadas nos bastidores. Não vamos restringir a pergunta para que a arquitetura subjacente do computador não possa incrementar um registro.
mbomb007
15

D

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

pouco girando para a vitória

como bônus, o código compilado não contém uma operação de adição (embora não seja possível falar pela chamada readf)

catraca arrepiante
fonte
12

Python 2, 43 bytes

print len('%s%s'%(input()*'?',input()*'!'))
Omar
fonte
3
Muito criativo, mas você pode querer alterar o caractere usado na cadeia para algo diferente de um tie-breaker como "~"
3Doubloons
Obrigado pelo conselho Alex, eu já tinha esquecido a regra do desempate.
Omar
print sum(input(),input())
Razpeitia
9
razpeitia: Eu acho que soma é uma função "parecida com soma" e, portanto, não é permitida.
Omar
6

GolfScript

Sem +/- ou desempatadores:

# 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

Versão muito mais simples, com dois caracteres desempatadores, usando o mesmo truque de concatenação de lista que outras pessoas estão usando:

~[\]{,~}%,

Suponho que o GolfScript não seja desqualificado por ter )um operador de incremento, pois na verdade não o estou usando.

Peter Taylor
fonte
6

C (apenas 32 bits)

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

A aritmética dos ponteiros é igualmente boa.
Como isso corresponde aos requisitos?
* Não +ou -
* Não /, =, ., 0- 9
* Apenas 3 pares de parênteses, o que me parece mínima (você precisa main, scanf, printf).
* Um *(a abordagem do ponteiro exige).
* Quatro ,(poderia salvar uma definindo variáveis ​​normais, não ac,av)

Uri Goren
fonte
6

C ++ 0 +/-, 3 desempatadores

#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
fonte
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

Isso usa nenhum +ou -caracteres e apenas dois =do conjunto de caracteres de desempatador, um dos quais é obrigatório para ligação main. A soma é feita concatenando listas dos comprimentos apropriados.

hammar
fonte
4

EDIT Isso foi publicado ANTES que as regras fossem alteradas para não permitir sum...

A linguagem R: Não há chamadas para +ou -... E 9 caracteres para desempate!

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

Exemplo:

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

A [1] 579é a resposta 579 ( [1]é para acompanhar onde está o vetor de resultado, pois em R todos os valores são vetores - nesse caso, o comprimento 1)

Observe que R possui +operadores exatamente como a maioria dos idiomas - acontece que também possui sumum conjunto de vetores.

Nesse caso, readLinesretorna um vetor de string de comprimento 2. Eu o coagido a numérico (dobra) e somado ...

Apenas para mostrar alguns outros recursos do 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
fonte
11
+1 Por me fazer mudar as regras para proibir a função sum ().
PhiNotPi
@PhiNotPi - Mudando as regras ?! Isso é batota! :-) ... Mas você provavelmente deveria dizer "funções do tipo soma" ou simplesmente usarei colSums... Talvez também ilegalize "funções do tipo negação" enquanto estiver trabalhando ...
Tommy
2
Eu vou seguir o seu conselho. Pelo que sei, todos (inclusive eu) neste site gostam de apontar brechas nas regras.
PhiNotPi
4

A linguagem R

Novas regras, nova resposta, mesmo idioma. Nenhuma chamada +ou-

ATUALIZAÇÃO Usando scan, ele cai para 11 caracteres desempatadores (e 27 caracteres no total).

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

Original: 13 personagens desempate!

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

Exemplo:

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

Desta vez, o resultado é alcançado pela multiplicação da matriz. A resposta é exibida como uma matriz 1x1.

Tommy
fonte
Não há nada que eu possa fazer para proibir isso. Talvez R seja apenas bom nesse desafio, pois é principalmente baseado em matemática. Ou talvez esse desafio seja fácil.
PhiNotPi
+1 Nice. Você pode tornar isso ainda mais curto com em scan()vez dereadlines(n=2)
Andrie
@Andrie - sim, mas então você confia no usuário digitando exatamente dois números ... O que é bom para esse desafio, eu acho ...
Tommy
4

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

(não usa o truque de concatenação de string / lista)

main = interact f
f x = show $ log $ product $ map exp $ map read $ lines x
JB
fonte
Você pode eliminar todos os pontos às custas de um extra = substituindo a composição: em vez de "fgh", escreva "a onde ax = f $ g $ h x"
Omar
3

Javascript, 56

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

Graças a @JiminP na ponta ~~! Eu estou indo para menos bytes, então a economia de 1 byte no prompt p =; ainda vale a pena. Entendo sua argumentação sobre caracteres desempatadores, mas, para ser sincero, você prefere o mínimo de bytes :-p

Versão, 69

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

Graças a alguns comentários de @Ilmari e @JiminP, retirei 13 bytes da minha solução original.

Originalmente, 82

i=parseInt;p=prompt;a=Array(i(p()));a.push.apply(a, Array(i(p())));alert(a.length)
stephencarmody
fonte
Esse espaço após a vírgula é completamente desnecessário; removê-lo vai te derrubar a 81.
Ilmari Karonen
Usar concate inserir cálculos alerté mais curto. i=parseInt;p=prompt;alert(Array(i(p())).concat(Array(i(p()))).length) BTW, eu não sabia que Array(n)retorna uma matriz com comprimento n. O console do Google Chrome me deu []e eu pensei que não havia nada ...
JiminP 3/11/11
11
Ah, já que o importante são os personagens desempate, p=promptnão é bom. E, parseInt(x)é quase equivalente a ~~x. alert(Array(~~prompt())['concat'](Array(~~prompt()))['length'])(12 caracteres de desempate) PS. Eu poderia usar isso como minha entrada, mas isso me dá uma sensação de roubo.
JiminP
3

C

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

APL (sem +/-, sem desempate, 8 ou 10 caracteres)

Essa entrada é semelhante às outras que concatenam seqüências geradas a partir da entrada e encontram o comprimento ... mas está no APL, que pode parecer confuso mesmo para um pequeno problema como esse. Eu usei o Dyalog APL , que oferece uma licença educacional gratuita.

Código:

⍴⊃⍪⌿⍳¨⎕⎕

Da direita para esquerda:

  • Cada quote-quad ( ) solicita a entrada do usuário e a avalia.
  • O operador each ( ¨) aplica a função de gerador de índice ( ) a cada um dos itens da matriz à sua direita.
  • Isso nivela a matriz resultante de matrizes em uma matriz. A matriz de entrada é reduzida a uma lista simples pelo operador de redução ( /), que dobra a matriz usando a função de concatenação ( ,). Para esse desafio, é utilizado o operador de redução unidimensional ( ), juntamente com o operador de concatenação ao longo do primeiro eixo ( ).
  • Como resultado do uso do operador de redução, a matriz é fechada , o que é como colocá-la na sacola; tudo o que vemos do lado de fora é uma bolsa, não seu conteúdo. O operador de divulgação ( ) fornece o conteúdo da matriz fechada (a bolsa).
  • Finalmente, a forma da função ( ) fornece os comprimentos das dimensões de uma matriz. Nesse caso, como temos uma matriz unidimensional, obtemos o número de itens na matriz, que é o nosso resultado.

Se precisarmos produzir explicitamente o resultado, podemos fazer o seguinte:

⎕←⍴⊃⍪⌿⍳¨⎕⎕

Código Python comparável, com os símbolos APL correspondentes acima:

import operator

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

Eu gostaria de saber se há uma versão mais curta possível em APL - outra, versão mais simples que eu vim com que tem mais desempates (embora ainda em 8 caracteres) é: ⍴(⍳⎕),⍳⎕.

Dillon Cower
fonte
Seu gerador de índice inicia em 1 ou 0?
MrZander
3

Eu não vi ninguém fazer isso da maneira da Engenharia Elétrica, então aqui está a minha opinião (em rubi):

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

É um pouco feio, mas faz o trabalho. Os dois valores são comparados pouco a pouco AND. Se eles não tiverem nenhum bit em comum, não haverá "carry" na próxima coluna binária; portanto, a adição poderá ser concluída bit- XORa- bit . Se houver um transporte, você precisará adicioná-lo ao bit a bit XOR. Aqui está um pequeno script em rubi que eu usei para garantir que minha lógica digital não estivesse muito enferrujada:

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

Felicidades!

Noé
fonte
3

Semente , 3904 3846 11 bytes, 0 +/-, 10 desempatadores

4 141745954
Krzysztof Szewczyk
fonte
2

Shell, 52

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

Esta é basicamente a mesma resposta que dei para outro problema.

Joey Adams
fonte
Similar: xargs -n1 jot | wc -lo que leva a mesma -redução awk, mas eu não posso ver como evitá-la noxargs
Ben Jackson
+/- e acima mencionados desempate são interessantes, não personagens.
usuário desconhecido
2

C

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
fonte
Conto 20 desempates ... Estou certo?
FUZxxl
2
22 desempates: 0 /*=., 7 (, 7 ), 7 ,, 1[0-9]
saeedn
2

C #

Não é o mais curto de todos os tempos:

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
fonte
Isso é cansativo, Matthew.
Cary Swoveland
2

J, 15 caracteres, 1 desempate, programa incompleto

Esta é a minha tentativa de J. Não é um programa completo, porque ainda não descobri como escrever um. Basta colocar essa linha em um script para obter a função pque pode ser usada para adicionar uma quantidade arbitrária de números. É uma mônada e pega uma lista de números a serem adicionados (como p 1 2 3 4):

p=:#@#~

A ideia é muito simples. A função é escrita em estilo tácito, também sem sentido. Aqui está uma definição pontiaguda:

p=:3 :'##~y'

Leia da direita para a esquerda. Na versão tácita, @compõe as partes da função. (como um ∘ em matemática [(f∘g) (x) = f (g (x)])

  • yé o parâmetro de p.
  • ~torna um verbo reflexivo. Para algum verbo m, m~ aé igual a a m a.
  • #(cópia a#b): Cada elemento em aé replicado ivezes, onde iestá o elemento no mesmo índice que o elemento atual ade b. Assim, #~replica um item n nvezes.
  • #(count #b): conta o número de elementos em b.

Conclusão: J é impressionante e menos legível que o Perl (o que a torna ainda mais impressionante)

Edições

  • 15 -> 7 usando em #vez de i.. sim! Menos caracteres que golfscript.

Mais de um programa

Este pergunta para entrada, mas ainda não é um programa completo: (13 caracteres, 3 disjuntores)

##~".1!:1<#a:
FUZxxl
fonte
J é definitivamente incrível, mas acredite em mim, você não pode simplesmente deixar de fora a parte de análise do problema quando você resolver os desafios com ele ;-)
JB
@JB Bem, você pode usar a função interna toJ, mas continuo recebendo erros de domínio.
FUZxxl
2

Javascript (17 caracteres desempatadores)

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

: P ("Ofuscado" para reduzir o número de caracteres de desempate. Internamente, é 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
fonte
2

C #,

Programa funciona em 1 linha; separados em várias linhas para evitar a rolagem 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
fonte
1

Clojure (44 caracteres)

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

Edit: corrigido para imprimir em STDOUT em vez de apenas retornar a soma.

Omar
fonte
+/- e acima mencionados desempate são interessantes, não personagens.
usuário desconhecido
1

Scala

  • Ponto:
    • + -: 0
    • () : 5 + 5 + 3 = 13

Código:

(List.fill (readInt) (1) ::: List.fill (readInt) (2)).size
  • List.fill (4) (7) produz a Lista (7, 7, 7, 7)
  • a ::: b concatena 2 listas em uma
  • O resto deve ser óbvio
Usuário desconhecido
fonte
1

K, 11

{#,[!x;!y]}

O mesmo truque de concatenação da solução R. Leitura da direita para a esquerda: enumere as duas variáveis ​​de entrada, concatene e depois conte.

tmartin
fonte
1

PowerShell , 27 42 bytes, 0 +-, 4 1 secundário

Agradecimentos ao mazzy por salvar um +e quatro secundários

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

Experimente online! ou Pretty Table por mais 3 bytes

-Ou- adicionando quatro secundários para salvar 19 bytes:

32 23 bytes, 1 0 +-, 12 5 secundários

-9 bytes graças a mazzy

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

Experimente online!

Para cada argumento, nenviamos elementos de matriz (consistindo em, [n]mas isso não é importante) para o pipeline, que são agrupados pelos parênteses e depois contados.

Veskah
fonte
11
Sinto muito, isso não é codegolf. 0 + -, 3 segundos, 27 bytes
mazzy 19/09
11
@mazzy Isso é 4 pela minha contagem, mas ainda assim obrigado:
V
11
você está certo. obrigado. 0 + -, 1 Desempatador, 42 bytes . você poderia adicionar |flum formato bonito Experimente online!
mazzy 19/09
1

Barril (SBCS no wiki Barril)

Basicamente, uma porta da resposta R.

¿¿Ï_"Ï_!.

Explicação

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

05AB1E , 2 4 bytes, 0 +/-

F>

Experimente online!

Desculpas se eu não entendi esse desafio, mas fiquei surpreso por não haver resposta 05AB1E. Resposta mais curta nesse idioma que eu poderia sugerir que não usa + ou a função soma incorporada.

Explicação:

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

-2 bytes graças ao Grimy.

Bismarck71
fonte
11
Obrigado! Ainda sou novo no 05AB1E.
Bismarck71
1

Python 3

Sem depender de somas ocultas em outras funções.

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

Experimente online!

Hunaphu
fonte
0

D

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

desta vez usando comprimentos de matriz

catraca arrepiante
fonte