Добавление без использования знака + или -


24

До этого было много испытаний «Делай __ без _ _», но я надеюсь, что это одна из самых сложных задач.

Соревнование

Вы должны написать программу, которая берет два натуральных числа (целые числа> 0) из STDIN и печатает сумму двух чисел в STDOUT. Проблема в том, что вы должны использовать как можно меньше знаков +и -знаков. Вам не разрешено использовать какие-либо функции типа суммы или отрицания.

Примеры

вход

123
468

выход

591

вход

702
720

выход

1422

Tie Breaker: Если две программы имеют одинаковое количество +и -персонажей, победителем является человек с меньшим количеством / * ( ) = . ,и 0-9символов.

Не разрешено: Языки, на которых стандартные операторы сложения / вычитания и увеличения / уменьшения являются символами, отличными от +или -не разрешенными. Это означает, что пробелы в языке не допускаются.


1
Возможно, это было намного проще, чем я думал, особенно в других языках, где есть функции sum (). Я должен это исправить.
PhiNotPi

50
100 повторений за каждого, кто может сделать это в Brainfuck.
Питер Олсон

3
@ Питер Олсон Ну, я думаю, что BF не будет завершен без или +или -...
FUZxxl

3
Просто чтобы уточнить, эта проблема не заботится о длине кода, верно? Только количество +, -а галстук персонажей? ... или вам нужно снова изменить правила :-)
Томми

@ Томми Нет, это не так.
PhiNotPi

Ответы:


29

Perl (без +/-, без прерывателей, 29 символов)

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

В качестве бонуса вы можете сделать кодовую сумму более двух чисел, добавив больше xs в s!!xx!.

В качестве альтернативы, здесь есть два 21-символьных решения с 1 и 3 выключателями соответственно

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

say log exp(<>)*exp<>

Примечание. В этих решениях используется sayфункция, доступная начиная с Perl 5.10.0 с -Eпереключателем командной строки или с помощью use 5.010. Посмотрите историю изменений этого ответа для версий, которые работают на старых perl.


Как работает решение без прерывателей связей?

  • s!!xx!является оператором замены регулярного выражения , работающим по умолчанию с $_переменной, которая заменяет пустую строку строкой xx. (Обычно /используется в качестве регулярного выражения разделителем в Perl, но на самом деле почти любой символ может быть использован я выбрал. , !Так как это не тай-брейка.) Это просто причудливый способ предваряя "xx"к $_- или, так как $_начинается пустой (неопределенный, на самом деле), это действительно способ писать $_ = "xx"без использования знака равенства (и с одним символом меньше тоже).

  • s!x!$"x<>!egеще одна замена регулярное_выражение, на этот раз заменяя каждый xв $_со значением выражения $" x <>. ( gПереключатель задает глобальную замену, eуказывает, что замена должна оцениваться как код Perl, а не использоваться в качестве литеральной строки.) $"Это специальная переменная , значением по умолчанию которой является один пробел; используя его вместо " "сохранения одного символа (Любая другая переменная, известная как имеющая односимвольное значение, например, $&или $/, будет работать здесь одинаково хорошо, за исключением того, что использование $/обойдется мне в тай-брейк.)

    Оператор <> ввода строки в скалярном контексте считывает одну строку из стандартного ввода и возвращает ее. xПрежде , чем это Perl оператор повторения строки , а на самом деле ядро этого решения: он возвращает его левый операнд (один символ пробела) повторяется несколько раз , заданных правого операнд (линия мы только что прочитали в качестве входных данных).

  • y!!!cэто просто неясный способ (ab) использовать оператор транслитерации для подсчета символов в строке ( $_по умолчанию снова). Я мог бы просто написать say length, но запутанная версия на один символ короче. :)


3
+1 - потрясающе и совершенно нечитабельно ;-) Это, кажется, идеальный ответ, так как количество символов в этом задании не имеет значения.
Томми

@ Томми, есть и другие идеальные ответы. Может быть, мы должны настаивать на том, чтобы количество символов стало окончательным.
Питер Тейлор

@Peter: я вроде бы предположил, что это уже было, по умолчанию.
Ильмари Каронен

1
если счетчик символов является последним прерывателем связей, и в других категориях существует множество записей, привязанных к нулю, разве это не связано code-golfс некоторыми исходными ограничениями?
Спарр

47

R (24 символа)

length(sequence(scan()))

Что это делает:

  • scan читает ввод из STDIN (или из файла)
  • sequenceгенерирует целочисленные последовательности, начиная с 1, и объединяет последовательности. Например, sequence(c(2, 3))результаты в векторе1 2 1 2 3
  • length вычисляет количество элементов в объединенном векторе

Пример 1:

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

Пример 2:

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

1
Очень умно, хорошая работа.
Мэтью Прочитал


+/- и вышеупомянутые тай-брейки интересны, а не персонажи.
пользователь неизвестен

Как рассчитать длину? без использования каких-либо дополнений? Если так, я был бы удивлен.
Тем Пора

2
@TemPora Вопрос ограничивает только код в ответе, а не операции, выполняемые за сценой. Мы не собираемся ограничивать этот вопрос, поэтому базовая компьютерная архитектура не может увеличивать регистр.
mbomb007

15

D

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

немного вертеться на победу

в качестве бонуса скомпилированный код не содержит операции добавления (хотя не могу говорить за вызов readf)


12

Python 2, 43 байта

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

3
Очень изобретательно, но вы, возможно, захотите изменить символ, используемый в строке, на что-то иное, чем прерыватель
связей,

Спасибо за совет Алекс, я уже забыл про правило тай-брейка.
Омар

print sum(input(),input())
Разпейтия

9
razpeitia: Я думаю, что сумма является «подобной сумме» функцией и поэтому не допускается.
Омар

6

GolfScript

Нет +/- или прерывателей:

# 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

Гораздо более простая версия с двумя символами прерывателя связей, использующая тот же прием конкатенации списков, который используют другие люди:

~[\]{,~}%,

Я предполагаю, что GolfScript не дисквалифицирован за использование )в качестве оператора приращения, поскольку я фактически не использую его.


6

C (только 32 бита)

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

Арифметика указателей так же хороша.
Как это соответствует требованиям?
* Нет +или -
* Нет /, =, ., 0- 9
* Только 3 пары скобок, которые , мне кажется минимальным (вам нужно main, scanf, printf).
* Один *(указательный подход требует этого).
* Четыре ,(можно сохранить одну, определив обычные переменные, а не ac,av)


6

C ++ 0 +/-, 3 выключателя

#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

Хаскелл, 0 + 2

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

При этом используются символы no +или -, и только два =из набора символов прерывателя связей, один из которых обязателен для привязки main. Сумма производится путем объединения списков соответствующей длины.


4

РЕДАКТИРОВАТЬ Это было опубликовано до того, как правила были изменены, чтобы запретить sum...

Язык R: Нет звонков +или -... И 9 символов тай-брейка!

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

Пример:

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

Это [1] 579ответ 579 ( [1]чтобы отслеживать, где в векторе результатов вы находитесь, поскольку в R все значения являются векторами - в данном случае длины 1)

Обратите внимание, что R имеет +операторы, как и большинство языков - так уж сложилось, что он имеет sumтакже суммирующий набор векторов.

В этом случае readLinesвозвращает строковый вектор длины 2. Затем я приводю его к числовому (удваивается) и суммирует ...

Просто чтобы показать некоторые другие особенности 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 Для того, чтобы заставить меня изменить правила, чтобы запретить функцию sum ().
PhiNotPi

@PhiNotPi - Изменение правил ?! Это жульничество! :-) ... Но вы, вероятно, должны сказать "функции, подобные сумме", или я просто буду использовать colSumsвместо этого ... Может быть, также запретить "функции, подобные отрицанию", пока вы в этом ...
Томми

2
Я собираюсь принять ваш совет. Из того, что я могу сказать, каждый (включая меня) на этом сайте любит указывать на лазейки в правилах.
PhiNotPi

4

Язык R

Новые правила, новый ответ, тот же язык. Нет звонков +или-

ОБНОВЛЕНИЕ Используя scan, он падает до 11 символов тай-брейка (и всего 27 символов).

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

Оригинал: 13 символов тай-брейка!

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

Пример:

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

На этот раз результат достигается путем умножения матриц. Ответ отображается в виде матрицы 1x1.


Я ничего не могу сделать, чтобы запретить это. Возможно, R хорошо справляется с этой задачей, поскольку в основном она основана на математике. Или, может быть, этот вызов просто.
PhiNotPi

+1 Хорошо. Вы можете сделать это еще короче с scan()вместоreadlines(n=2)
Andrie

@Andrie - да, но тогда вы полагаетесь на то, что пользователь вводит ровно два числа ... Я думаю, что это нормально для этого вызова ...
Томми

4

Haskell, 0 +/ -, 6 2 выключателя ( =)

(не использует трюк конкатенации строк / списков)

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

Вы можете устранить все точки за счет дополнительного =, заменив композицию: вместо «fgh» напишите «a, где ax = f $ g $ h x»
Омар

3

Javascript, 56

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

Спасибо @JiminP за подсказку ~~! Я собираюсь наименьшее количество байтов, поэтому 1 байтовое сохранение в приглашении p =; все еще стоит Я понимаю ваш аргумент о символах прерывателя связей, но, если честно, вы бы предпочли не меньше байтов :-p

Версия, 69

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

Благодаря некоторой обратной связи от @Ilmari и @JiminP, я сократил 13 байт моего исходного решения.

Изначально 82

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

Это место после запятой совершенно не нужно; удаление его приводит вас к 81.
Илмари Каронен

Использование concatи положить расчеты в alertкороче. i=parseInt;p=prompt;alert(Array(i(p())).concat(Array(i(p()))).length) Кстати, я не знал, что Array(n)возвращает массив с длиной n. Консоль Google Chrome дала мне, []и я подумал, что ничего не было ...
JiminP

1
О, так как важная вещь - персонажи тай-брейка, p=promptэто не хорошо. И, parseInt(x)почти эквивалентно ~~x. alert(Array(~~prompt())['concat'](Array(~~prompt()))['length'])(12 символов прерывателя) PS. Я мог бы использовать это как свою запись, но это только дает мне чувство воровства.
JiminP


3

APL (без +/-, без прерывателей связи, 8 или 10 символов)

Эта запись похожа на другие, которые объединяют последовательности, сгенерированные из входных данных, и находят длину ... но это в APL, что может показаться непонятным даже для такой небольшой проблемы, как эта. Я использовал Dyalog APL , который предлагает бесплатную образовательную лицензию.

Код:

⍴⊃⍪⌿⍳¨⎕⎕

Справа налево:

  • Каждая цитата-quad ( ) запрашивает ввод у пользователя и оценивает его.
  • Каждый оператор ( ¨) применяет функцию генератора индекса ( ) к каждому элементу в массиве справа от него.
  • Это сгладит результирующий массив массивов в один массив. Входной массив сокращается до плоского списка с помощью оператора сокращения ( /), который сворачивает массив с помощью функции конкатенации ( ,). Для решения этой задачи используется одномерный оператор редукции ( ) вместе с оператором конкатенации вдоль первой оси ( ).
  • В результате использования оператора сокращения массив заключен , как если бы он был помещен в сумку; снаружи мы видим только сумку, а не ее содержимое. Оператор раскрытия ( ) дает нам содержимое вложенного массива (пакет).
  • Наконец, форма-функция ( ) дает нам длины размеров массива. В этом случае у нас есть одномерный массив, поэтому мы получаем количество элементов в массиве, что является нашим результатом.

Если нам нужно явно вывести результат, мы можем сделать это так:

⎕←⍴⊃⍪⌿⍳¨⎕⎕

Сопоставимый код Python с соответствующими символами APL выше:

import operator

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

Я хотел бы знать , если есть более короткий вариант можно в APL - другой, более простой вариант я придумал , что имеет больше галстука выключатели (хотя до сих пор на 8 символов) является: ⍴(⍳⎕),⍳⎕.


Ваш генератор индекса начинается с 1 или 0?
MrZander

3

Я не видел, чтобы кто-то делал это с помощью электротехники, поэтому вот мое мнение (в рубине):

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

Это немного уродливо, но это делает работу. Два значения сравниваются поразрядно AND. Если у них нет общих битов, в следующем двоичном столбце нет «переноса», поэтому сложение можно завершить путем их побитового XORввода. Если есть перенос, вы должны добавить перенос к побитовой XOR. Вот небольшой рубиновый скрипт, который я использовал, чтобы убедиться, что моя цифровая логика не слишком ржавая:

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

Ура!



2

Shell, 52

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

Это в основном тот же ответ, который я дал для другой проблемы.


Похоже: xargs -n1 jot | wc -lчто требует того же -сокращения, awkно я не вижу, как этого избежатьxargs
Бен Джексон

+/- и вышеупомянутые тай-брейки интересны, а не персонажи.
пользователь неизвестен

2

С

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

Я считаю 20 брейк-брейков ... Я прав?
FUZxxl

2
22 прерывателя связи: 0 /*=., 7 (, 7 ), 7 ,, 1[0-9]
saeedn

2

C #

Это не самое короткое время:

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

Это утомительно, Мэтью.
Кэри Свовеланд,

2

J, 15 7 символов, 1 прерыватель связи, неполная программа

Это моя попытка J Это не полная программа, потому что я еще не понял, как ее написать. Просто вставьте эту строку в скрипт, чтобы получить функцию, pкоторую можно использовать для добавления произвольного количества чисел. Это монада, которая добавляет список чисел (например, p 1 2 3 4):

p=:#@#~

Идея очень проста. Функция написана в молчаливом или бессмысленном стиле. Вот точное определение:

p=:3 :'##~y'

Читайте справа налево. В негласной версии, @составляет части функции. (как ∘ в математике [(f∘g) (x) = f (g (x)])

  • yэто параметр p.
  • ~делает глагол рефлексивным. Для некоторых глаголов m, m~ aравно a m a.
  • #(copy, a#b): каждый элемент в aреплицируется iраз, где iэто элемент с тем же индексом, что и текущий элемент aof b. Таким образом, #~копия товара n nраз.
  • #(count, #b): подсчитывает количество элементов в b.

Вывод: J потрясающий и менее читаемый, чем Perl (что делает его еще более потрясающим)

Правки

  • 15 -> 7 #вместо i.. Да! Меньше символов, чем в сценарии гольфа.

Больше программы

Этот запрос на ввод, но он еще не полная программа: (13 символов, 3 прерывателя)

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

J определенно потрясающий, но поверьте мне, вы не можете просто не учитывать часть проблемы, когда разбираетесь с ней ;-)
JB

@JB Хорошо, вы можете использовать встроенную функцию toJ, но я продолжаю получать ошибки домена.
FUZxxl

2

Javascript (17 символов тай-брейка)

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

: P («Обфусцировано», чтобы уменьшить количество символов тай-брейка. Внутренне это 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 #,

Программа работает на 1 линии; разделены на несколько строк, чтобы избежать горизонтальной прокрутки.

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 символа)

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

Редактировать: исправлено печатать на STDOUT вместо возврата суммы.


+/- и вышеупомянутые тай-брейки интересны, а не персонажи.
пользователь неизвестен

1

Scala

  • Гол:
    • + -: 0
    • (). : 5 + 5 + 3 = 13

Код:

(List.fill (readInt) (1) ::: List.fill (readInt) (2)).size
  • List.fill (4) (7) создает список (7, 7, 7, 7)
  • a ::: b объединяет 2 списка в один
  • Остальное должно быть очевидным

1

К, 11

{#,[!x;!y]}

Тот же трюк с конкатенацией, что и для решения R. Чтение справа налево: перечислить две входные переменные, объединить, а затем считать.


1

PowerShell , 27 42 байта, 0 +-, 4 1 вторичный

Спасибо Маззи за сохранение +и 4 вторичных

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

Попробуйте онлайн! или Pretty Table для дополнительных 3 байтов

-Или- добавление четырех вторичных файлов для сохранения 19 байтов:

32 23 байта, 1 0 +-, 12 5 вторичных

-9 байт благодаря маззи

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

Попробуйте онлайн!

Для каждого аргумента мы помещаем nэлементы массива (состоящие из, [n]но это не важно) в конвейер, которые группируются по скобкам и затем подсчитываются.



1
Извините, это НЕ Codegolf. 0 + -, 3 вторичных, 27 байтов
mazzy

1
@mazzy Это 4 по моим подсчетам, но, тем не менее, спасибо: D
Веска

1
вы правы. Спасибо. 0 + -, 1 Tie Breaker, 42 байта . Вы можете добавить |flдля красивого формата Попробуйте онлайн!
Маззи

1

Кег (SBCS на Кеге вики)

В основном порт ответа R.

¿¿Ï_"Ï_!.

объяснение

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

1

05AB1E , 2 4 байта, 0 +/-

F>

Попробуйте онлайн!

Извиняюсь, если я неправильно понял этот вызов, но я был удивлен, что ответа 05AB1E не было. Самый короткий ответ на этом языке, который я мог бы найти, который не использует + или встроенную функцию суммы.

Объяснение:

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

-2 байта благодаря Грими.


1
Благодарность! Я все еще новичок в 05AB1E.
Bismarck71


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.