Aggiunta senza usare un segno + o -


24

Ci sono state molte sfide "Do __ without _ _" prima, ma spero che questa sia una delle più impegnative.

La sfida

Devi scrivere un programma che prende due numeri naturali (numeri interi> 0) da STDIN e stampa la somma dei due numeri su STDOUT. La sfida è che si deve usare come pochi +e -segni il più possibile. Non è consentito utilizzare alcuna funzione di somma o negazione.

Esempi

ingresso

123
468

produzione

591

ingresso

702
720

produzione

1422

Tie Breaker: se due programmi hanno lo stesso numero di +e -personaggi, il vincitore è la persona con meno / * ( ) = . ,e 0-9personaggi.

Non consentito: lingue in cui gli operatori di addizione / sottrazione standard e incremento / decremento sono simboli diversi +o -non consentiti. Ciò significa che Whitespace la lingua non è consentita.


1
Forse questa sfida è stata molto più semplice di quanto pensassi, soprattutto in altre lingue, dove ci sono funzioni sum (). Devo risolvere questo.
PhiNotPi

50
Bounty di 100 rappresentanti per chiunque possa farlo in Brainfuck.
Peter Olson,

3
@Peter Olson Beh, immagino che BF non stia diventando completo senza nessuno dei due +o -...
FUZxxl

3
Giusto per chiarire, a questa sfida non interessa la lunghezza del codice, giusto? Solo il numero di +, -e tie breaker personaggi? ... o devi cambiare di nuovo le regole :-)
Tommy,

@ Tommy No, non è così.
PhiNotPi

Risposte:


29

Perl (no +/-, nessun pareggio, 29 caratteri)

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

Come bonus, puoi fare in modo che il codice sommi più di due numeri aggiungendo più xs al s!!xx!.

In alternativa, ecco due soluzioni a 21 caratteri con 1 e 3 tie-breaker rispettivamente

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

say log exp(<>)*exp<>

Nota: queste soluzioni utilizzano la sayfunzione, disponibile da Perl 5.10.0 con l'opzione della -Eriga di comando o con use 5.010. Vedi la cronologia delle modifiche di questa risposta per le versioni che funzionano su perls precedenti.


Come funziona la soluzione senza interruzioni?

  • s!!xx!è un operatore di sostituzione regexp , che opera di default sulla $_variabile, che sostituisce la stringa vuota con la stringa xx. (Di solito /è usato come delimitatore regexp in Perl, ma in realtà si può usare quasi ogni personaggio. Ho scelto !dato che non è un pareggio.) Questo è solo un modo stravagante di anteporre "xx"a $_- o, poiché $_inizia vuoto (indefinito, in realtà), è davvero un modo per scrivere $_ = "xx"senza usare il segno uguale (e anche con un carattere in meno).

  • s!x!$"x<>!egè un'altra sostituzione regexp, questa volta sostituendo ogni xin $_con il valore dell'espressione $" x <>. (L' gopzione specifica la sostituzione globale, especifica che la sostituzione deve essere valutata come codice Perl anziché essere utilizzata come stringa letterale.) $"È una variabile speciale il cui valore predefinito risulta essere un singolo spazio; usandolo invece di " "salva un carattere. (Qualsiasi altra variabile nota per avere un valore di un carattere, come $&o $/, funzionerebbe ugualmente bene qui, tranne per il fatto che l'uso $/mi costerebbe un pareggio.)

    L' <> operatore di input di riga , in un contesto scalare, legge una riga dall'input standard e la restituisce. Il xprima è l' operatore di ripetizione della stringa Perl ed è davvero il nucleo di questa soluzione: restituisce il suo operando di sinistra (un singolo carattere di spazio) ripetuto il numero di volte dato dal suo operando di destra (la riga che abbiamo appena letto come input).

  • y!!!cè solo un modo oscuro di (ab) usare l' operatore di traslitterazione per contare i caratteri in una stringa ( $_di default, di nuovo). Avrei potuto semplicemente scrivere say length, ma la versione offuscata è più corta di un personaggio. :)


3
+1 - fantastico e totalmente illeggibile ;-) Questa sembra essere la risposta perfetta poiché il conteggio dei personaggi non ha importanza in questa sfida.
Tommy,

@ Tommy, ci sono anche altre risposte perfette. Forse dovremmo spingere affinché il conteggio dei personaggi sia l'ultimo pareggio.
Peter Taylor,

@Peter: ho pensato che fosse già, per impostazione predefinita.
Ilmari Karonen,

1
se il conteggio dei caratteri è il pareggio finale e molte voci sono pari a zero nelle altre categorie, questo non diventa solo code-golfcon alcune restrizioni alla fonte?
Sparr,

47

R (24 caratteri)

length(sequence(scan()))

Cosa fa questo:

  • scan legge input da STDIN (o un file)
  • sequencegenera sequenze di numeri interi a partire da 1 e concatena le sequenze. Ad esempio, sequence(c(2, 3))risulta nel vettore1 2 1 2 3
  • length calcola il numero di elementi nel vettore concatenato

Esempio 1:

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

Esempio 2:

> length(sequence(scan()))
1: 702
2: 720
3:
Read 2 items
[1] 1422

1
Molto intelligente, ottimo lavoro.
Matthew Leggi l'

Questo mi fa
impazzire

+/- i suddetti break-breaker sono interessanti, non personaggi.
utente sconosciuto

Come calcola la lunghezza? senza usare alcuna aggiunta? Se è così, sarei sorpreso.
Tem Pora,

2
@TemPora La domanda limita solo il codice nella risposta, non le operazioni eseguite dietro le quinte. Non limiteremo la domanda, quindi l'architettura del computer sottostante non può incrementare un registro.
mbomb007,

15

D

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

un po 'per la vittoria

come bonus il codice compilato non contiene un'operazione di aggiunta (non può parlare per la chiamata readf però)


12

Python 2, 43 byte

print len('%s%s'%(input()*'?',input()*'!'))

3
Molto inventivo, ma potresti voler cambiare il carattere usato nella stringa in qualcosa di diverso da un pareggio come "~"
3Doubloons

Grazie per il consiglio Alex, mi ero già dimenticato della regola del tie-breaker.
Omar,

print sum(input(),input())
razpeitia,

9
razpeitia: Penso che la somma sia una funzione "simile alla somma" e quindi non consentita.
Omar,

6

GolfScript

Nessun +/- o interruttori:

# 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

Versione molto più semplice con due personaggi tie-breaker, usando lo stesso trucco di concatenazione di elenchi che altre persone stanno usando:

~[\]{,~}%,

Suppongo che GolfScript non sia squalificato per avere )come operatore di incremento, in quanto non lo sto effettivamente utilizzando.


6

C (solo 32 bit)

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

L'aritmetica del puntatore è altrettanto buona.
Come soddisfa i requisiti?
* No +o -
* No /, =, ., 0- 9
* Solo 3 coppie di parentesi, che mi sembra il minimo (è necessario main, scanf, printf).
* Uno *(l'approccio puntatore lo richiede).
* Quattro ,(potrebbe salvarne uno definendo variabili normali, non ac,av)


6

C ++ 0 +/-, 3 tiranti

#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;
}

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

Questo utilizza no +o -caratteri, e solo due =dal set di caratteri tie breaker, uno dei quali è obbligatorio per l'associazione main. La somma viene effettuata concatenando elenchi delle lunghezze appropriate.


4

EDIT Questo è stato pubblicato PRIMA che le regole siano state modificate per non consentire sum...

Il linguaggio R: nessuna chiamata a +o -... E 9 personaggi break-breaker!

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

Esempio:

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

La [1] 579è la risposta 579 (il [1]è quello di tenere traccia di dove nel vettore conseguenza il vostro sono dal momento che in R tutti i valori sono vettori - in questo caso di lunghezza 1)

Si noti che R ha +operatori proprio come la maggior parte delle lingue: è proprio così che ha sumanche un totale di vettori.

In questo caso, readLinesrestituisce un vettore stringa di lunghezza 2. Quindi lo costringo a numerico (doppio) e lo riassumo ...

Solo per mostrare alcune altre funzionalità di 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

1
+1 Per avermi costretto a cambiare le regole per mettere fuori legge la funzione sum ().
PhiNotPi

@PhiNotPi - Modifica delle regole ?! Questo è barare! :-) ... Ma dovresti probabilmente dire "funzioni simili a una somma" o userò colSumsinvece ... Forse anche fuorilegge le "funzioni simili a una negazione" mentre ci sei ...
Tommy,

2
Prenderò il tuo consiglio. Da quello che posso dire, tutti (incluso me) su questo sito adorano sottolineare le lacune nelle regole.
PhiNotPi

4

Il linguaggio R.

Nuove regole, nuova risposta, stessa lingua. Nessuna chiamata a +o-

AGGIORNAMENTO Usando scan, scende a 11 caratteri tie-breaker (e 27 caratteri in totale).

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

Originale: 13 personaggi di tie-breaker!

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

Esempio:

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

Questa volta il risultato è ottenuto dalla moltiplicazione di matrici. La risposta viene visualizzata come una matrice 1x1.


Non c'è niente che io possa fare per mettere fuori legge questo. Forse R è semplicemente bravo in questa sfida, poiché è principalmente basato sulla matematica. O forse questa sfida è semplice.
PhiNotPi

+1 Nizza. Puoi renderlo ancora più breve con scan()invece direadlines(n=2)
Andrie l'

@Andrie - sì, ma poi fai affidamento sull'utente che inserisce esattamente due numeri ... Il che è OK per questa sfida, immagino ...
Tommy,

4

Haskell, 0 +/ -, 6 2 tie-breakers ( =)

(non usa il trucco di concatenazione di stringhe / liste)

main = interact f
f x = show $ log $ product $ map exp $ map read $ lines x

Puoi eliminare tutti i punti a scapito di un extra = sostituendo la composizione: invece di "fgh" scrivi "a dove ax = f $ g $ h x"
Omar

3

Javascript, 56

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

Grazie a @JiminP sul suggerimento ~~! Sto andando per almeno byte, quindi il risparmio di 1 byte sul prompt p =; ne vale ancora la pena. Capisco la tua discussione sui caratteri tie-breaker, ma ad essere sincero non preferiresti il ​​minimo byte :-p

Versione, 69

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

Grazie ad alcuni feedback di @Ilmari e @JiminP, ho eliminato 13 byte dalla mia soluzione originale.

Inizialmente, 82

i=parseInt;p=prompt;a=Array(i(p()));a.push.apply(a, Array(i(p())));alert(a.length)

Quello spazio dopo la virgola è completamente inutile; rimuoverlo ti porta a 81.
Ilmari Karonen,

L'uso concate l'inserimento dei calcoli alertè più breve. i=parseInt;p=prompt;alert(Array(i(p())).concat(Array(i(p()))).length) A proposito, non sapevo che Array(n)restituisse un array con lunghezza n. La console di Google Chrome mi ha dato []e pensavo che non ci fosse nulla ...
JiminP

1
Oh, dato che l'importante è che i personaggi siano in pareggio, p=promptnon va bene. E, parseInt(x)è quasi equivalente a ~~x. alert(Array(~~prompt())['concat'](Array(~~prompt()))['length'])(12 caratteri di tie-breaker) PS. Potrei usarlo come voce, ma questo mi dà la sensazione di rubare.
JiminP

3

C

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

3

APL (no +/-, nessun pareggio, 8 o 10 caratteri)

Questa voce è simile alle altre che concatenano sequenze generate dall'input e trovano la lunghezza ... ma è in APL, che può apparire confusa anche per un piccolo problema come questo. Ho usato Dyalog APL , che offre una licenza educativa gratuita.

Codice:

⍴⊃⍪⌿⍳¨⎕⎕

Da destra a sinistra:

  • Ogni quote-quad ( ) richiede input dall'utente e lo valuta.
  • Ciascun operatore ( ¨) applica la funzione generatore di indice ( ) a ciascuno degli elementi dell'array alla sua destra.
  • Ciò appiattisce l'array risultante di array in un array. L'array di input viene ridotto a un elenco semplice dall'operatore di riduzione ( /), che piega l'array utilizzando la funzione di concatenazione ( ,). Per questa sfida, viene utilizzato l' operatore di riduzione unidimensionale ( ), insieme all'operatore di concatenazione lungo il primo asse ( ).
  • Come risultato dell'utilizzo dell'operatore di riduzione, l'array è racchiuso , il che è come metterlo nella borsa; tutto ciò che vediamo all'esterno è una borsa, non il suo contenuto. L'operatore di divulgazione ( ) ci fornisce il contenuto dell'array incluso (il sacchetto).
  • Infine, la forma di funzione ( ) ci fornisce le lunghezze delle dimensioni di un array. In questo caso, abbiamo un array monodimensionale, quindi otteniamo il numero di elementi nell'array, che è il nostro risultato.

Se dobbiamo generare esplicitamente il risultato, possiamo farlo in questo modo:

⎕←⍴⊃⍪⌿⍳¨⎕⎕

Codice Python confrontabile, con i corrispondenti simboli APL sopra:

import operator

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

Mi piacerebbe sapere se c'è una versione più breve possibile in APL - un altro, versione più semplice mi si avvicinò con che ha più gli spareggi (anche se ancora a 8 caratteri) è: ⍴(⍳⎕),⍳⎕.


Il tuo generatore di indice inizia da 1 o 0?
MrZander,

3

Non ho visto nessuno farlo nel modo dell'ingegneria elettrica, quindi ecco la mia opinione (in rubino):

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

È un po 'brutto, ma fa il lavoro. I due valori vengono confrontati per bit AND. Se non hanno bit in comune, non c'è "carry" nella successiva colonna binaria, quindi l'aggiunta può essere completata inserendoli bit a bit XOR. Se c'è un carry, devi aggiungere il carry al bit a bit XOR. Ecco un piccolo script ruby ​​che ho usato per assicurarmi che la mia logica digitale non fosse troppo arrugginita:

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

Saluti!



2

Shell, 52

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

Questa è sostanzialmente la stessa risposta che ho dato per un altro problema.


Simile: xargs -n1 jot | wc -lche prende la stessa -riduzione, awkma non riesco a vedere come evitarlo nelxargs
Ben Jackson,

+/- i suddetti break-breaker sono interessanti, non personaggi.
utente sconosciuto

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));}

Conto 20 pareggi ... Ho ragione?
FUZxxl

2
22 pareggi: 0 /*=., 7 (, 7 ), 7 ,, 1[0-9]
saeedn

2

C #

Non è il più corto di qualsiasi tratto:

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));
}

È estenuante, Matthew.
Cary Swoveland,

2

J, 15 7 caratteri, 1 pareggio, programma incompleto

Questo è il mio tentativo di J. Non è un programma completo, perché non ho ancora capito come scriverne uno. Basta inserire quella riga in uno script per ottenere la funzione pche può essere utilizzata per aggiungere una quantità arbitraria di numeri. È una monade e prende un elenco di numeri da aggiungere (come p 1 2 3 4):

p=:#@#~

L'idea è molto semplice. La funzione è scritta in tacito stile inutile. Ecco una definizione appuntita:

p=:3 :'##~y'

Leggi da destra a sinistra. Nella versione tacita, @compone le parti della funzione. (come un ∘ in matematica [(f∘g) (x) = f (g (x)])

  • yè il parametro di p.
  • ~rende un verbo riflessivo. Per alcuni verbi m, m~ aè uguale a a m a.
  • #(copia a#b): ogni elemento in aè replicato ivolte, dove si itrova l'elemento con lo stesso indice dell'elemento corrente adi b. Quindi, #~replica un oggetto n nvolte.
  • #(count, #b): conta il numero di elementi in b.

Conclusione: J è stupendo e meno leggibile di Perl (il che lo rende ancora più straordinario)

Le modifiche

  • 15 -> 7 usando #invece di i.. Si! Meno caratteri di golfscript.

Più di un programma

Questo richiede input, ma non è ancora un programma completo: (13 caratteri, 3 interruttori)

##~".1!:1<#a:

J è decisamente fantastico, ma credimi, non puoi semplicemente tralasciare la parte di analisi del problema quando risolvi le sfide ;-)
JB

@JB Bene, puoi usare la funzione integrata toJ, ma continuo a ricevere errori di dominio.
FUZxxl

2

Javascript (17 personaggi tie-breaker)

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

: P ("Offuscato" per ridurre il numero di caratteri di tie-breaker. Internamente, lo è 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); .)


2

C #,

Il programma funziona su 1 riga; separati su più righe per evitare lo scorrimento orizzontale.

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);
}}

1

Clojure (44 caratteri)

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

Modifica: risolto per stampare su STDOUT invece di restituire semplicemente la somma.


+/- i suddetti break-breaker sono interessanti, non personaggi.
utente sconosciuto

1

Scala

  • Punto:
    • + -: 0
    • (). : 5 + 5 + 3 = 13

Codice:

(List.fill (readInt) (1) ::: List.fill (readInt) (2)).size
  • List.fill (4) (7) produce List (7, 7, 7, 7)
  • a ::: b concatena 2 elenchi in uno
  • Il resto dovrebbe essere ovvio

1

K, 11

{#,[!x;!y]}

Stesso trucco di concatenazione della soluzione R. Lettura da destra a sinistra: enumera le due variabili di input, concatena e quindi conta.


1

PowerShell , 27 42 byte, 0 +-, 4 1 secondario

Grazie a mazzy per aver salvato un +e 4 secondari

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

Provalo online! o Pretty Table per altri 3 byte

-Oppure- aggiungendo quattro secondari per salvare 19 byte:

32 23 byte, 1 0 +-, 12 5 secondari

-9 byte grazie a mazzy

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

Provalo online!

Per ogni argomento, ninviamo elementi della matrice (costituiti da [n]ma non è importante) alla pipeline che vengono raggruppati per parentesi e quindi conteggiati.



1
Mi dispiace, questo NON è codegolf. 0 + -, 3 secondries, 27 byte
mazzy

1
@mazzy Sono 4 per il mio conteggio, ma grazie comunque: D
Veskah,

1
hai ragione. Grazie. 0 + -, 1 Tie Breaker, 42 byte . potresti aggiungere |flper un bel formato Provalo online!
mazzy,

1

Keg (SBCS su Keg wiki)

Fondamentalmente una porta della risposta R.

¿¿Ï_"Ï_!.

Spiegazione

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

1

05AB1E , 2 4 byte, 0 +/-

F>

Provalo online!

Mi scuso se ho frainteso questa sfida, ma sono rimasto sorpreso dal fatto che non ci fosse una risposta 05AB1E. Potrei trovare la risposta più breve in questa lingua che non utilizza + o la funzione di somma integrata.

Spiegazione:

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

-2 byte grazie a Grimy.


1
Grazie! Sono ancora nuovo di 05AB1E.
Bismarck71,

1

Python 3

Senza fare affidamento su somme nascoste in altre funzioni.

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

Provalo online!


0

D

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

questa volta usando lunghezze di array

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.