Подсчитать сумму всех цифр


38

Эта задача состоит в том, чтобы написать программу или скрипт, который подсчитывает сумму всех цифр в целых числах от 1 до и включая заданное число.

Ввод, одно положительное целое число. Выведите, сумму цифр в этом числе и все меньшие числа.

Примеры:

Input: 5 
Integer Sequence: 1, 2, 3, 4, 5
Sum of Digits: 1 + 2 + 3 +4 + 5 = 15

Input: 12
Integer Sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 
Sum of Digits: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 1 + 0 + 1 + 1 + 1 + 2 = 51

Чтобы было ясно, это значит, что нужно посчитать сумму цифр, а не целых чисел. Для однозначных входов это будет то же самое. Тем не менее, входы больше 10 будут иметь разные ответы. Это был бы неправильный ответ:

Input: 12
Output: 78

Другой пример, чтобы показать разницу:

Input: 10

Integer Sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Sum of Integers (INCORRECT RESPONSE): 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55

Digit Sequence: 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0
Sum of Digits (CORRECT RESPONSE): 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 1 + 0 = 46

Большой тестовый пример (ПРАВИЛЬНЫЙ ОТВЕТ):

Input: 1000000
Output: 27000001

Правила и рекомендации:

  • Представленный код должен быть законченной программой или скриптом, а не просто функцией. Если код требует включает в себя, импорт и т. Д., Они должны быть включены в размещенный код.
  • Номер должен быть введен пользователем, а не жестко запрограммирован. Ввод может быть получен в виде аргумента командной строки, файла, стандартного ввода или любым другим способом, с помощью которого ваш язык может принимать пользовательский ввод.
  • Код должен быть в состоянии правильно обрабатывать ввод по крайней мере до (2^64)-1.
  • Код должен выводить только сумму.
  • Представленные программы и сценарии должны быть удобными для пользователя и не растрачивать компьютерные ресурсы (например: они не должны объявлять безумно большие массивы для хранения каждого символа). Для этого нет строгого бонуса или штрафа, но, пожалуйста, будьте хорошими программистами.

Подсчет очков:

Основной механизм оценки по длине кода. Чем ниже баллы, тем лучше. Следующие бонусы и штрафы также применяются:

  • -25 Бонус, если ваш код может обрабатывать все положительные числа, например:1234567891234567891234564789087414984894900000000
  • -50 Бонус, если ваш код может обрабатывать простые выражения, например 55*96-12. Чтобы получить этот бонус, код должен обрабатывать + - / *операторы (сложение, вычитание, деление, умножение) и обеспечивать порядок операций. Деление - это регулярное целочисленное деление.
    • Данный пример ( 55*96-12) оценивается как 5268. Ваш код должен возвращать то же самое для любого из этих входов - правильный ответ 81393.
  • Бонус -10, если ваш код соответствует бонусу -50 и может обрабатывать ^оператор (экспонента).
  • Бонус -100, если ваш код соответствует бонусу -50 и не используется evalили не похож на обработку выражений.
  • +300 Штраф, если ваш код опирается на какие-либо веб-ресурсы.

2
И что должно 55*96-12вернуться?
ProgramFOX

1
55 * 96-12 = 5268, должен быть тот же вывод, что и введенный 5268
ST3

3
Бонусы могут быть немного на большой стороне, кажется, становится соревнованием на самый большой отрицательный счет :)
Йоахим Исакссон

7
@ ST3, если практически невозможно выиграть без бонусов, то почти лучше просто выполнить их требования или стоить меньше.
Cruncher

3
-1 потому что в этом задании используется устаревший (и ужасный) выигрышный бонус «бонусы».
mbomb007

Ответы:


9

Perl 6: 108 - (25 + 50 + 100) + 0 = -67 очков

Решение для гольфа (финальная линия, основанная на великолепном решении xfix ):

$!=get;for '*',&[*],'/',&[/],'+',&[+],'-',&[-] ->$s,&f{$!~~s:g[(\d+)$s(\d+){}]=f |@()}
say [+] (1..$!)».comb

Решение для игры в гольф:

my $expression = get;
for '*', &[*],
    '/', &[/],
    '+', &[+],
    '-', &[-]
-> $sym, &infix {
    $expression ~~ s:g[(\d+) $sym (\d+) {}] = infix($0, $1)
}
say [+] (1..$expression)».comb

Этап оценки работы итерации над каждым символом *, /, +, -, находя , когда , которая находится между двумя целыми числами, и заменяя , что с помощью функции , что символ представляет.

Более подробно: он берет каждый символ (например +) и инфиксную функцию, которую он должен представлять (например, &[+]сокращение для &infix:<+>той же функции, которую Perl 6 вызывает при выполнении 1 + 2), и выполняет глобальную подстановку ( s:g[…] = …которая похожа на Perl 5 s/…/…/ge), который совпадает с двумя целыми числами, разделенными символом ( (\d+) $sym (\d+)), и заменяет его выводом соответствующей инфиксной функции, вызываемой этими целыми числами ( infix($0, $1)).

Наконец, это оцененное выражение вводитсяsay [+] (1..$expression)».comb , что xfix очень хорошо объясняет в его решении .

Извините, что так поздно на вечеринку ☺

РЕДАКТИРОВАТЬ: Удалена поддержка экспонентов; в любом случае это было ровно 10 символов, и ассоциативность не была правильно сделана.


Это здорово. Мне нравится, как вы сделали очень простой парсер - я пытался, но мне не удалось сделать что-то такое короткое, как это. Вместо этого my $gвы можете использовать что-то заранее объявленное (я думаю, что это $!может сработать, но я не проверял).
Конрад Боровски

@xfix, я не уверен, как это поможет гольфу. Есть один способ по- настоящему сыграть в гольф, но он требует еще не полностью функционального синтаксиса «infix: [$ var]»: my$g=get;for <* / + -> {$g~~s:g[(\d+)$^s(\d+){}]=infix:[$^s] |@()};say [+] (1..$g)».combэто снизит счет до 88 символов или -97 очков
Mouq

Ох, $! поможет избавиться от «моего»! Спасибо @xfix
Mouq

14

Mathematica 30- (10 + 50) = -30

Укорочена на 4 знака благодаря ибельтукам.

Range@nвозвращает число от 1 до n.

Integerdigits@n разбивает каждое из этих чисел на свои цифры.

Total[n,2]суммирует цифры. 2 - разрешить суммирование на разных уровнях, то есть списках списков.

IntegerDigits@Range@#~Total~2&

тестирование

IntegerDigits@Range@#~Total~2&[12]

51

IntegerDigits@Range@#~Total~2 &[1000000]

27000001


Выражения

IntegerDigits@Range@#~Total~2 &[55*96 - 12]

55*96 - 12

81393
5268

IntegerDigits@Range@#~Total~2 &[5268]

81393


IntegerDigits@Range@#~Total~2 &[55*96^2 - 12]
55*96^2 - 12

12396621
506868

IntegerDigits@Range@#~Total~2 &[506868]

12396621


Вы должны добавить информацию о действительных аргументах, чтобы получить все очки брауни: D
Ив Клетт

1
Я не знаю, подумал бы я, что не использую eval
Cruncher

3
Re: Eval в Mathematica. Это символический язык, на котором интерфейс всегда пытается автоматически решить математические задачи. Вам нужно будет добавить дополнительный код (Hold []), чтобы предотвратить это.
Майкл Стерн

1
Tr@Flattenможет быть уменьшена до Total[...,2]: IntegerDigits@Range@#~Total~2&.
ибельтуков

1
Разве вы не обрабатываете как угодно большое int и не заслуживаете еще -25?
aka.nice

12

C: 150 138 - (100 + 50) = -12

a,b,c;main(d){for(scanf("%d ",&a);~scanf("%c%d ",&d,&b);a=d^43?d%5?d%2?a/b:a*b:a-b:a+b);for(;a;)for(b=a--;b;b/=10)c+=b%10;printf("%d",c);}

Очень постыдно крадет ответ @Fors отсюда, чтобы выполнить оценку выражения: https://codegolf.stackexchange.com/a/11423/13877

Пример использования:

./a.exe <<< "5 + 7"
51

Примечание: реализация выражения не предполагает приоритета операторов и использует значения по мере их получения; бывший, 1+2*3 = 9а не типичный 7.


1
Это не касается приоритета операторов, но вопрос не определяет, должен ли применяться стандартный приоритет операторов ... ping @ ST3, это, вероятно, следует уточнить. Во всяком случае, это, вероятно, следует упомянуть в ответе.
FireFly

@FireFly Я изменил ответ, чтобы отразить этот факт.
Джош

@ Джош - пожалуйста, ответь на 2 ^ 64 - 5
SergeyS

10

sed, 411 283 - 25 = 258

Я не могу быть обеспокоен тем, чтобы играть в гольф прямо сейчас. :-) Не рекомендуется для использования даже с удаленно большими целыми числами, но технически это может иметь дело с произвольно большими целыми числами (хотя, скорее всего, вам не хватит оперативной памяти, так как я (более или менее должен) кодировать число в унарный).

s/$/x0123456789/
:l
/9$/H
:b
s/(.)(y*x\1)/y\2/
/(.)y*x\1/b b
s/(.)([xy].*)(.)\1/\3\2\3\1/
:c
s/y(.*(.))/\2\1/
/y/b c
/0$/b f
/^0*x.*9$/!b l
x
s/x[^\n]*\n//g
:d
s/(.)(.*x.*(.)\1)/z\3\2/
/[^z0]x/b d
s/0|x.*|\n//g
H;x
s/./0/g
s/$/x9876543210/
x
:e
x
b l
:f
x
s/.//
/./b e
x
s/^0+|x.*//g

Образец использования

(Строки ввода с отступом для удобства чтения.)

  5
15
  12
51
  33
183

8

питон, 55- (50 + 25 + 10) = -30

Неэффективно, но короче и может обрабатывать выражения.

РЕДАКТИРОВАТЬ: Спасибо Wolframh и legoStormtroopr за трюки: D

s,t=0,input()
while t:s+=sum(map(int,`t`));t-=1
print s

питон, 149- (25 + 50 + 10) = 64

Моя первая версия

def d(n):
 if n/10==0:return n*(n+1)/2
 c,t=0,n
 while t/10:c,t=c+1,t/10
 p=10**c;m=n%p
 return d(m)+t*(m+1)+p*t*(t-1)/2+p*c*t*45/10
print d(input())

вход:

1234567891234567891234564789087414984894900000000

выход:

265889343871444899381999757086453238874482500000214

Я получаю ошибку переполнения, когда пытаюсь запустить ваше xrangeрешение1234567891234567891234564789087414984894900000000
Джош

1
@ Джош избавился от xrange: D
Васи

2
Некоторые советы: Вы можете заменить eval(raw_input())на input(). whileЦикл может быть while t:s+=sum(map(int,т ));t-=1.
Восстановить Монику

2
Вы можете сократить это, просто используя input()вместо того eval(raw_input()), чтобы , как inputуже evalс выражением! Это означает, что вы можете получить -10 за символ силы и бонус -100 за неиспользование eval!!!

@LegoStormtroopr правила говорят evalи тому подобное , поэтому я думаю, что -100 не будет учитываться
SztupY

8

Python - 108 символов минус 85 бонусов, 23 ударов, обрабатывает очень и очень большие входные данные

Большинство из этих решений, кажется, зацикливаются на все целые числа меньше входных и складывают все их цифры. Это работает, но я чувствую, что это не элегантно, и задам вопрос, действительно ли они имеют право на бонус в 25 баллов, поскольку я не думаю, что они смогут справиться с вводом в 1234567891234567891234564789087414984894900000000течение наших жизней. Действительно, на ввод nцифр, эти решения требуют O(10^n)времени. Я решил вместо этого бросить математику на эту проблему.

#Returns the sum of all digits in all x-digit numbers
def f(x):
    return x*(10**(x-1))*45

#Returns the sum of all numbers up to x
def g(x):
    return x*(x+1)/2

#Solves the problem quickly
def magic(x):
    digits = [int(y) for y in list(str(x))]
    digits.reverse()
    total = 0

    for (sig, val) in enumerate(digits):
        total += (10**sig)*g(val-1) + val*f(sig) + val + (val*10**sig)*sum(digits[sig+1:])
    return int(total)

Множество всех xцифр чисел изоморфно множеству {0,1,2,3,4,5,6,7,8,9}^x. Для фиксированного (n,sig)существуют xразличные значения sig, 10^x-1точки с sigго набора индекса к n, а сумма всех цифр 0-9составляет 45. Это все обрабатывается f.

g это то, что мы, вероятно, все знакомы с

magicберет все цифры входного числа и перебирает их от наименее до наиболее значимых. Проще всего отследить это с помощью примера ввода, скажем 1,234,567.

Чтобы иметь дело с диапазоном 1,234,567-1,234,560, мы должны сложить все цифры от 1до 7и добавить в 7разы сумму других цифр, чтобы иметь дело со всеми числами больше чем 1,234,560. Теперь нам нужно разобраться с остатком.

Чтобы разобраться с диапазоном 1,234,560-1,234,500, мы добавим 6( val) и опустим верхний предел до 1,234,559. Делая оставшуюся часть отбрасывания, мы увидим каждое однозначное число 6 раз ( val*f(sig)). Мы увидим все числа от точно 0до каждого времени ( ). Мы увидим все остальные цифры в этом числе ровно 60 раз ( ). Теперь мы имеем дело со всеми числами строго больше, чем . Та же логика будет применяться индуктивно во всех значениях.510(10**sig)*g(val-1)(val*10**sig)*sum(digits[sig+1:])1,234,500

Игра в гольф, благодаря WolframH, сокращает это решение до

d=map(int,str(input()))
print sum(v*(10**s*((v-1)/2+sum(d[:~s]))-~s*9*10**s/2)for s,v in enumerate(d[::-1]))

И сумма цифр суммы всех целых чисел до 1234567891234567891234564789087414984894900000000является265889343871444927857379407666265810009829069029376

Наибольшее число, которое мне удалось набрать в версии для гольфа, составляет 10 ^ 300, и в этот момент поплавки начинают переполняться, и численная нестабильность начинает вызывать проблемы. При быстрой функции возведения в квадрат и умножения эта проблема исчезла бы.

И поддержка LaTeX была бы очень полезна ...


Ницца. Я пытался решить эту проблему с математикой некоторое время назад, но застрял. Позже мне придется тщательно обдумать это и подумать о том, как это работает.
FireFly

Хороший ответ! Это похоже на то, как я рассчитывал, это было бы, если бы вход 1000000 :)
ST3

1
+1 за использование математики. Однако я получаю 2.65889343871e+50, что является приближением с плавающей запятой к реальному решению. Видимо, вы печатали int(t)вместо того, чтобы tв коде, который вы дали. Это не правильно; реальное решение есть 265889343871444899381999757086453238874482500000214. Просто избегайте использования поплавков, т.е. заменяйте **(x-1)их на более короткие **x/10.
Восстановить Монику

1
Гольф это немного больше. Понятно, что нужен только глобальный d(потому что он используется дважды). Устраняя другие (и используя некоторые уловки) каждый достигает d=map(int,str(input()))\nprint sum(v*(10**s*((v-1)/2+sum(d[:~s]))-~s*9*10**s/2)for s,v in enumerate(d[::-1]))(108 символов). Отлично работает на входах любого размера (например int("1"*1000)).
Восстановить Монику

1
@ymbritt 10**-1будет 0.1, а оттуда на всем преобразуемые поплавки. 1/10есть 0(целочисленное деление), и все может оставаться intс.
Восстановить Монику

8

TI-BASIC, 137 - (50 + 10 + 100) = -23

Input A:Disp cumSum(randIntNoRep(1,A))→L₁:"?:For(A,1,dim(L₁:Ans+sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ",L₁(A),1:End:Disp sub(Ans,2,length(Ans)-1

Ввод обрабатывает числа до 1E100и автоматически оценивает. Может обрабатывать выражения.

Хотя это безумно большой массив, я не трачу компьютерные ресурсы (это запускается из калькулятора ).


1
лучший ответ на этот вопрос я думаю. используя язык калькулятора, чтобы написать код гольф-ответа для сложения чисел. так круто!
Малахи

1
@Malachi Как я всегда говорю, когда код гольф = математика, пора вытащить калькулятор.
Timtech

2
Моя версия, которая допускала числа до 9E99, была явно недостаточно хороша, поэтому я не думаю, что вы можете посчитать этот бонус. Кроме того, я почти уверен, что вам придется считать входные данные «с eval», согласно ответу Carraher's Mathematica.
FireFly

1
Согласитесь с FireFly, бонус не использовать evalне нужно.
ST3

3
Как калькулятор не компьютер?
Дэвид Конрад


6

С 77 74

n,v,i;main(){scanf("%d",&n);for(;i||(i=n--);i/=10)v+=i%10;printf("%d",v);}

С 150 124 - 25 = 99

Вот альтернативная версия, которая технически должна иметь право на 25 бонусов за «любое» положительное целое число, но это непрактично медленно, так как алгоритм имеет линейное время на входе. Несмотря на это, было весело писать. Вручную вычитает число, считываемое как символы ASCII. Эта версия составляет 150 символов. (Теперь с ужасным цикличным кодом!)

n,v;main(int n,char**a){char*p;do{for(p=a[1];*p>47;p++)v+=*p-48;for(;*--p==48;)*p=57;
p[0]--;}while(p>=a[1]);printf("%d",v);}

С 229 224 - (50 + 100) = 74

Вариант обработки выражений. Реализует оператор старшинства в соответствии с типовыми правилами: / * - +. Ограничено до 97 токенов = 48 терминов.

#define F(X,Y)for(q=n+1;q+1!=p;)*q-X?q+=2:(q[-1]Y##=q[1],memmove(q,q+2,(p-q)*4))
n[99],*p,*q,v,i;main(){for(p=n;~scanf("%d%c",p,p+1);)p+=2;F('/',/);F('*',*);
F('-',-);F('+',+);for(;i||(i=n[0]--);i/=10)v+=i%10;printf("%d",v);}

Все положительные целые числа означают, что он должен обрабатывать даже больше, чем 99 цифр.
ST3

@Firefly крутой алгоритм для работы с числами больше встроенных чисел!
Джош

5

GolfScript 18 - 50 = -32

~),{`+}*' '*~]{+}*

Пояснение: Предположим, что ввод "12":

~), # turn input into integer, increment, and then turn into an array of all numbers less than or equal to input.  

Стек есть [0,1,2,3,...,12].

{`+}* # fold string concatenation across the array

Стек есть "01234...9101112".

' '* # join a space between all characters

Стек есть "0 1 2 ... 1 0 1 1 1 2".

~] # evaluate the stack into an array.  No `[` is necessary since the stack is otherwise empty.

Стек есть [0,1,2,...,9,1,0,1,1,1,2].

{+}* # fold addition across the new array

Стек 51, по желанию.

Входными данными здесь могут быть любые допустимые выражения GolfScript, которые могут включать в себя экспоненты. Например:

echo "5 5 + 2 * 8 -" | ruby golfscript.rb h.gs
-> 51

Так как 2(5 + 5) - 8 = 12. Я думаю, что это должно претендовать на бонус, но, возможно, ожидалось, что это будет, только если в обычной форме, а не обратная польская запись GolfScript.


Это также поддерживает ^?
SztupY

Это поддерживает возведение в степень в синтаксисе GolfScript, который является?
Бен Рейх

Вы не получаете бонус 10, потому что программа должна поддерживать ^, а не ?или powи т. Д.
ST3

@ ST3 Как пожелаешь!
Бен Райх

4

Рубин, 37 - 50 = -13

Двойной eval, весь путь по небу! Как и с другими решениями Ruby, я думаю, что теоретически это должно быть в состоянии работать с произвольно большими числами, но время выполнения будет ... ужасным.

p eval [*1..eval(gets)].join.chars*?+

Старая версия (49 - 50 баллов)

p"#{[*1..eval(gets)]}".chars.map(&:to_i).inject:+

Предполагая, что бонус в 10 символов на самом деле требует, чтобы символ для возведения в степень был каретой, я бы подумал, что кратчайший способ добавить это:

.gsub ?^,'**'

Который стоит больше персонажей, чем даст бонус.


Вы можете удалить несколько символов:p"#{[*1..eval(gets)]}".chars.map(&:to_i).inject :+
SztupY

@SztupY хороший звонок, спасибо! Я не использую &почти достаточно в гольфе. На самом деле, вам не нужно пространство между injectи :+либо.
Пол Престиж 15.01.14

4

Perl 6 (28 - 75 + 0 = -47 байт)

say [+] (1..get.eval)».comb

Он может обрабатывать все положительные числа (однако большие будут занимать много времени, потому что в настоящее время реализация Perl 6 медленная, но Perl 6 изначально поддерживает большие целые числа). Он использует eval, чтобы реализовать простой калькулятор (штраф в пять символов стоит пятьдесят символов). Это медленно только потому, что текущие реализации медленны, но в теории, это должно быть достаточно быстро (когда реализации Perl 6 улучшаются, то есть). Также, на удивление, я выигрываю с Mathematica (пока).

» в этом коде фактически нет необходимости, но я поместил его здесь из соображений производительности (в противном случае программа выделяла бы всю строку. Причина в том, что Perl 6 не имеет бесконечных строк, но у него есть бесконечные списки.

В любом случае, вы можете спросить, как работает этот код. Ну, я собираюсь передать его по частям.

  • get.eval

    Это получает одну строку ( getфункцию) и оценивает ее ( evalметод).

  • 1..get.eval

    После этого Perl 6 подготавливает объект диапазона от 1оценочного значения. Это диапазон, поэтому ничего огромного не выделяется.

  • ».comb

    .combМетод разбивает строку на символы ( если не вызывается с аргументом ). Например, 'cat'.combвозвращает 'c', 'a', 't'. »сопоставляет элементы списка, поэтому .combон запускается для каждого элемента, а не только для самого списка (например, (4, 9)».sqrtдает 2, 3). Это также не выделяет больше, чем нужно, потому что Perl 6 имеет бесконечные списки (как, например, Haskell).

    »символ на самом деле не нужен, так как .combможет использоваться непосредственно в списке, но это подразумевает неявное приведение строк (и Perl 6 не имеет бесконечных строк, так что это приведет к потере памяти). Например, 1, 2, 3список после преобразования в строку возвращает 1 2 3. Для Perl 6 пробел - это идеально точное число, означающее 0, поэтому код будет работать даже при таком преобразовании. Тем не менее, это будет злоупотреблять вычислительными ресурсами.

  • [+]

    Это оператор сокращения. По сути, []в этом случае вы можете использовать оператор +. Список после оператора сокращения уменьшается, так что [+] 1, 2, 3есть 1 + 2 + 3, который есть 6. Perl 6 использует отдельные операторы для чисел и строк, поэтому он не будет рассматриваться как конкатенация.

  • say

    Наконец, sayвыводит результат. В конце концов, вы хотите увидеть конечный результат, не так ли?


Хм ... [+] 1,2,3,4,5,6,7,8,9,10это 1+2+3+4+5+6+7+8+9+10, я прав?
ST3

@ ST3: да. Оператор Reduce может использоваться многими интересными способами в Perl 6. Например, >может быть связан, так что 3 > 2 > 1это правда. То же свойство применяется для сокращения операторов, так [>] 3, 2, 1до сих пор так, как это означает , что 3 > 2 > 1- [>]может быть использовано для определения числа в порядке убывания.
Конрад Боровски

не могли бы вы использовать get.Intвместо eval? Нужны ли математические выражения?
Ven

@ user1737909: «-50 Бонус, если ваш код может обрабатывать простые выражения». Кроме того, Perl 6 не нуждается в приведении по замыслу (за исключением нескольких редких случаев, например, sortбез аргумента метода сравнения).
Конрад Боровски


3

J, 22

([:+/[:"."0[:":>:@:i.)

объяснение

Оценка продолжается справа налево.

i. n -> 0 1 2...n-1

>: n -> n+1

": numbers -> 'numbers'

"."0 -> (on each scalar item) apply ". -> '123' -> 1 2 3

+/ -> sum

Даунвотер должен объяснить свои возражения на этот ответ. Я только что попробовал и, хотя он не зарабатывает никаких бонусов, он работает просто отлично, насколько я вижу.
Гарет

На самом деле, посмотрев на верхний ответ, он, похоже, также зарабатывает выражения и бонусы для операторов со счетом 22-60 = -38.
Гарет

Это +/,10#.inv>:i.было бы короче. Но это все же функция, а не полная программа, как спросил ОП.
swish

Бонусы @Gareth не применяются к этому ответу, потому что вы просто пишете выражения внутри кода, а не как ввод.
swish

1
@swish Сначала я так и думал, но ответ Mathematica, похоже, работает примерно так.
Гарет

3

R 64 - (50 + 10) = 4

sum(utf8ToInt(paste(0:eval(parse(t=scan(,""))),collapse=""))-48)

Когда это выполняется, у пользователя запрашивается ввод.


Старая версия (не может обрабатывать выражения): 46 символов:

sum(utf8ToInt(paste(0:scan(),collapse=""))-48)

Мне приходит в голову, что Codegolf дико склонен к языкам с односимвольными функциями. Это решение будет значительно короче, если мы предопределим u<-function(x) utf8ToInt(x)и так далее.
Карл Виттофт

@CarlWitthoft Это правда. Но предопределение также учитывает количество символов. Кстати: достаточно u <- utf8ToIntобойтись без function. Это может быть полезно для кода гольф, если функция используется несколько раз.
Свен Хоэнштайн

Итак, если я создаю Rcheatcodegolfпакет, разрешено ли использовать предопределенные функции в этом пакете? :-)
Карл Виттофт

@CarlWitthoft Да, пакеты могут быть использованы. Конечно, пакет не должен быть написан для задачи. Но если он включает короткие имена только для функций, это нормально.
Свен Хоэнштайн

3

Партия - (181 - 50) - 131

Просто для удовольствия.

@set/av=%1
@setLocal enableDelayedExpansion&for /L %%a in (1,1,%v%)do @set a=%%a&powershell "&{'%%a'.length-1}">f&set/pb=<f&for /L %%c in (0,1,!b!)do @set/as+=!a:~%%c,1!
@echo !s!

Я сделаю это немного более читабельным:

@set /a v=%1
setLocal enableDelayedExpansion
for /L %%a in (1,1,%v%) do (
    @set a=%%a
    powershell "&{'%%a'.length-1}">f
    set /p b=<f
    for /L %%c in (0,1,!b!) do @set /a s+=!a:~%%c,1!
)
@echo !s!

Старый метод использует цикл для получения вывода команды powershell, а не для записи и чтения из файла:

@set /a v=%1
@setLocal enableDelayedExpansion&for /L %%a in (1,1,%v%)do @set a=%%a&for /F usebackq %%b in (`powershell "&{'%%a'.length-1}"`)do @for /L %%c in (0,1,%%b)do @set /a s+=!a:~%%c,1!
@echo !s!

Установите входные данные для переменной - v-, /aчтобы принимать арифметические выражения.
К сожалению, включение отложенного расширения было необходимо.
Используйте цикл for для подсчета от 1 до введенного значения - v.
Чтобы обработать числа больше 9, мне пришлось использовать powershell, чтобы получить длину строки, а затем использовать другой цикл for, чтобы разбить эту строку, и добавить ее к сумме - s.
Вы можете изменить имя powershell.exeна p.exeC: \ WINDOWS \ System32 \ WindowsPowerShell \ v1.0 \, а затем вызвать его p "&{'%%a'.length-1}, сохранив всего 9 байтов. Но это не совсем в духе этого.

H:\>sumof.bat 12
51
H:\>sumOf.bat (55*96-12)
81393

Оставил второй, пока я брал перерыв на обед.

Я не могу на самом деле проверить это с числами, которые слишком много, чем это из-за того, как медленно это. Однако это должно работать для довольно большого числа. 2147483647это наибольшее число, которое потребуется (максимум 32-битное целое), прежде чем выдать следующую ошибку -

H:\>sumOf.bat 2147483648
Invalid number.  Numbers are limited to 32-bits of precision.

Это, конечно, лишает меня права на вызов.


1
Отличное решение! Есть несколько способов сыграть в гольф. 1. Вы можете избавиться от временной переменной vи использовать %1напрямую. 2. Вы можете вычесть 1 из своего скрипта PowerShell, а не из длинных, @set /a b=%%b-1что сэкономит вам кучу. С этими изменениями у меня до 211 с оригинальных 240. :-)
Mark

К сожалению, теперь я понимаю, почему вы сохранили свою временную переменную (для бонусных баллов). Наконечник PowerShell все еще остается, хотя ...
Марк

Хорошо заметили, спасибо. Изменит это сейчас.
unclemeat

Пакет не будет работать. Он ограничен (2 ^ 31) -1 (32-разрядное целое число со знаком). Задача требует обработки входных данных до (2 ^ 64) -1 (64-разрядное целое число без знака, но выход для этого значения будет переполнен). Именно здесь PowerShell имеет явное преимущество - его [decimal]тип допускает значения до (2 ^ 96) -1.
Изи

1
Тем не менее, я дам Batch неплохой кредит за невыполнение обязательств по целочисленному делению. Это то, что PowerShell полностью отсутствует.
Изи

3

Дьялог АПЛ , 9 - 160 * = -151

+/⍎¨∊⍕¨⍳⎕

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

получить оценку входных данных,
 например, "7+5"дает12

индексы 1 ... n
[1,2,3,4,5,6,7,8,9,10,12]

⍕¨ отформатировать каждое число в строку
["1","2","3","4","5","6","7","8","9","10","11","12"]

подключить
"123456789101112"

⍎¨ выполнить каждый символ (выдает список из однозначных чисел)
[1,2,3,4,5,6,7,8,9,1,0,1,1,1,2]

+/ сумма  51


* Подсчет очков

-50 бонус, поскольку он даже принимает выражения в качестве входных данных. Выражение должно быть действительным APL, что является приемлемым согласно OP .

-10 бонус, потому что он также обрабатывает ^( *в APL).

-100 бонус, потому что ввод выражения обрабатывается без явного использования eval(то есть в APL).


Вы уверены, что здесь добавлен бонус -100? Потому что он гласит « Бонус -100, если ваш код соответствует бонусу -50 и не использует eval или не похож на обработку выражений». Так ⍎¨как кажется, что каждый символ выполняется один за другим, он вроде как eval (за исключением того, что он выполняет символы один за другим вместо всех одновременно, как evalделает).
Кевин Круйссен

@KevinCruijssen Да, поскольку он не использует eval или аналогичные для обработки выражений. ⍎¨используется только для преобразования цифр в целые числа, а не для обработки выражений.
Адам

Ах, подождите, я неправильно посмотрел на ваше объяснение. Но разве это не своего рода встроенная функция input + eval или eval всегда выполняется неявно при вводе выражений?
Кевин Круйссен

1
@KevinCruijssen всегда принимает выражение в качестве входных данных, оценивает его и возвращает его результат. Таким образом, чтобы ввести строку, вам нужно заключить ее в кавычки. Тот факт, что связанная встроенная функция ( ) возвращает входные данные в виде необработанного текста, не должен иметь значения (особенно потому, что символы указывают, что это основной метод ввода и является специальным вариантом), так как в противном случае получение бонуса потребовало бы выполнения математических операций. Оценщик - совершенно иная задача, чем основная. Я не люблю бонусы, а -100 просто глупый или имел в виду APL, но имхо, он точно подходит для бонуса.
Адам

Если это действительно нормальный способ получения ввода и автоматической обработки выражений, я действительно считаю, что он вписывается и в бонус, так что +1 от меня. Бонусы в наши дни глупы, но это хороший способ использовать их, чтобы свести к минимуму ваш счет.
Кевин Круйссен

2

C # (161)

using C=System.Console;using System.Linq;class X{static void Main(){C.WriteLine(Enumerable.Range(1,int.Parse(C.ReadLine())).SelectMany(i=>i+"").Sum(c=>c-48));}}

милая

using C = System.Console;
using System.Linq;

class X
{
    static void Main()
    {
        C.WriteLine(
            Enumerable.Range(1, int.Parse(C.ReadLine()))
                .SelectMany(i => i + "")
                .Sum(c => c - 48)
            );
    }
}

2

Python3 + Bash (78 - 185 = -107)

python3 -c"print(sum(sum(map(int,str(x+1)))for x in range(int(${1//^/**}))))"
  • может обрабатывать все положительные числа
  • может обрабатывать выражения с помощью операции + - / *
  • может справиться с оператором ^ (power).
  • может обрабатывать выражения без eval или аналогичных

Если результат выражения не является целым числом, он будет сначала обрезан. Если результат выражения отрицательный, результат не определен.

Используйте это как:

bash golf.sh "12 + (42 / 3 + 3^4)"

1: если только вы не считаете вызов Python из Bash как таковой, но я не думаю, что это так. Если вы думаете, что это действительно так, то скорректированный результат равен -7.


Я бы сказал, что если вы не пишете оценщик выражений, то вы используете что-то эквивалентное eval. Но я не ОП, так что удачи!
Tobia

Согласитесь с @Tobia, нет бонуса для оценки выражения.
ST3

2

Ява, 254

class T
{
    public static void main(String[] a)
    {
        long target = 10, count = 0;
        String[] digits = new String[50];
        for (long i = 1; i <= target; i++)
        {
            digits = String.valueOf(i).split("(?!^)");
            for (int j = 0; j < digits.length; j++)
                if (digits.length > j)
                    count += Integer.parseInt(digits[j]);
        }
        System.out.println(count);
    }
}

Обрабатывает выражения. Дайте любое выражение в цель. Ручки, пока длина не может справиться. Если вы убираете все пробелы в одну строку и не печатаете инструкции, это считается до 254 символов (с учетом Java-программирования на основе длинных слов).

PS: это полная программа, а не просто логика. Количество слов, данное для программы, а не только логика.


2

Ява (JDK8), 272

Мой первый вызов, в котором я нахожусь, предложения приветствуются =)

import java.util.*;import java.util.stream.*;class C{public static void main(String[]a){System.out.print(Arrays.asList(IntStream.range(1,new Integer(a[0])).mapToObj(s->s+"").collect(Collectors.joining()).split("")).stream().map(Integer::valueOf).reduce(0,Integer::sum));}}

Отступ:

import java.util.*;
import java.util.stream.*;

class C {

   public static void main(String[] a) {
     System.out.print(Arrays.asList(IntStream.range(1,new Integer(a[0]))
            .mapToObj(s->s+"")
            .collect(Collectors.joining())
            .split(""))
            .stream()
            .map(Integer::valueOf)
            .reduce(0,Integer::sum));
  }
}

+1, поскольку каждый, кто бросает вызов гольф-коду в java, заслуживает этого, но кажется, что Stream API не дает вам преимущества, пока вы играете в гольф. Держу пари, если вы переписываете свое решение и будете использовать циклы вместо потоков, оно будет короче.
user902383

2

CJam, 9 - 25 = -16

CJam на несколько месяцев моложе этой задачи, поэтому она не имеет права на зеленую галочку. Кроме того, это не победит Perl. ;) Мне очень понравился подход, поэтому я все равно хотел опубликовать его.

l~),s:~:+

Проверьте это здесь.

Идея состоит в том, чтобы создать диапазон от 0 до N. Затем этот диапазон преобразуется в строку, которая просто объединяет целые числа вплотную. Для N = 12 мы получили бы

"0123456789101112"

Затем каждый символ преобразуется в целое число с :~(получая массив целых чисел), а затем суммируется с :+. CJam может иметь дело с произвольно большими целыми числами.


2

Питон 3 + Астор ,1017 1007 байт - (25 + 50 + 100) = Оценка: +842 834

сохранено 10 байт путем удаления tsи измененияp

редактировать: я не могу проверить смехотворно длинное целое число (1234567891234567891234564789087414984894900000000) [зависает мой компьютер], но, насколько мне известно, Python 3 поддерживает произвольно длинные целые числа.

Эта реализация использованиязлоупотребляет АСТ. Я бы не стал злоупотреблять AST как «eval или похожий».

from ast import*
from astor import*
nt,bo,m,d,a,s,n,p,ty=NodeTransformer,BinOp,Mult,Div,Add,Sub,Num,map,type
class M(nt):
    def visit_BinOp(t,z):
        if ty(z.left)==bo and ty(z.right)==bo:return bo(t.visit_BinOp(z.left),z.op,t.visit_BinOp(z.right))
        if ty(z.left)==bo:return bo(t.visit_BinOp(z.left),z.op,z.right)
        if ty(z.right)==bo:return bo(z.left,z.op,t.visit_BinOp(z.right))
        if ty(z.op)==m:return n(z.left.n*z.right.n)
        if ty(z.op)==d:return n(z.left.n/z.right.n);return z
class A(nt):
    def visit_BinOp(t,z):
        if ty(z.left)==bo and ty(z.right)==bo:return bo(t.visit_BinOp(z.left),z.op,t.visit_BinOp(z.right))
        if ty(z.left)==bo:return bo(t.visit_BinOp(z.left),z.op,z.right)
        if ty(z.right)==bo:return bo(z.left,z.op,t.visit_BinOp(z.right))
        if ty(z.op)==a:return n(z.left.n+z.right.n)
        if ty(z.op)==s:return n(z.left.n-z.right.n);return z
class S(nt):
    def visit_Num(t,z):return n(sum(p(int,list("".join(p(str,range(1,z.n+1)))))))
print(to_source(S().visit(A().visit(M().visit(parse(input()))))))

Слишком лениво, чтобы писать без гольфа, поэтому я дам вам объяснение классов:

M(NodeTransformer|nt) - converts multiplication and division into their results.
A(NodeTransformer|nt) - converts addition and subtraction into their results.
S(NodeTransformer|nt) - converts numbers into their sum of digits via the Pythonic (naïve) way.

Последняя строка просто выполняет эти классы в соответствующем порядке на входе, чтобы сохранить порядок операций и предотвратить нежелательное поведение.

Пример использования ($ или> означает пользовательский ввод) и, кстати, фактическая программа принимает ввод только один раз:

$ python3 summer.py
> 5
15
> 10
46
> 12
51
> 1000000
27000001
> 55*96-12
81393

Это удивительно, но все же ужасно. Не уверен, что это разрешено (сознательно использовать длинное решение), но 10/10 от меня.
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Почему нельзя сознательно использовать длинное решение? Я не вижу проблем. По крайней мере, я побью решения с результатом 842+;)

Они должны быть конкурентными ответами, что означает проявление усилий. Также УДАЛИТЕ ЭТО КОММЕНТАРИЙ. SE Предел для возраста 13 !!! Вам, вероятно, следует подождать, пока вам по закону не разрешат быть включенным. Из-за COPPA (Google), вам нужно быть 13 лет, чтобы использовать Интернет, как это.
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Теперь мне интересно, кто этот пользователь?
кот

1
@cat Арабское имя, которое я не мог произнести? Вероятно, ядерный аккаунт.
Rɪᴋᴇʀ

1

C # (108)

int c(int n){return string.Join("",Enumerable.Range(1,n).Select(i=>i+"")).ToArray().Select(c=>c-'0').Sum();}

милая

int c(int n)
{
    return string.Join("", Enumerable.Range(1, n).Select(i => i + "")).ToArray().Select(c => c - '0').Sum();
}

3
Это неверный ответ, так как это функция, и количество символов довольно большое
ST3

1
Вам не нужны ints; в C все по умолчанию int... О, это C #.
wizzwizz4

1

Рубин -> 83-50 = 33

p (1..eval(gets.chomp)).each.inject{|c,e|c+e.to_s.chars.map{|x|x.to_i}.inject(:+)}                     

«Тестировать» версию:

module Math
  class CountSum
    def sum(number)
      (1..number).each.inject do |c, e|
        c + e.to_s.chars.map{ |x| x.to_i }.inject(:+)                                                  
      end
    end
  end
end 

Результаты тестов

$ rspec sum_spec.rb  --format doc --color

Math::CountSum
  #sum
    single digit number
      when 5, should return 15
    double digit number
      when 12, should return 51
    arbitrary number
      when 1000000 should return 27000001

Finished in 5.34 seconds
3 examples, 0 failures

1

C # (80)

Это моя другая попытка.

double c(int n){double s=0;while(n>0)foreach(var c in n--+"")s+=c-48;return s;}

милая

double c(int n)
{
    double s = 0;
     while (n > 0)
        foreach(var c in n--+"") 
            s += c - 48;
    return s;
}

Есть ли пробел между n--и +нужно? Я не думаю, что это на других языках в стиле Си.
FireFly

1
Работает ли это с заданным диапазоном? Результат для 2^64-1не вписывается в 64 бит.
Маринус

2
Это неверный ответ, так как это функция, и количество символов довольно большое.
ST3

@marinus Можете ли вы дать нам результат для 2 ^ 64-1, чтобы мы могли знать, с каким диапазоном нам нужно работать? Я не осмелюсь протестировать его на своем языке (PowerShell), поскольку время обработки будет огромным.
Иззи

@Izzi: Я не собираюсь его запускать, но вы можете немного посчитать: 1) среднее значение цифры 4.5; 2) средняя сумма из 20 цифр равна 90( 2^64имеет 20 цифр); поэтому ожидаемое значение будет около 90 * 2^64 ≈ 1.66*10^21. Так что вам понадобится хотя бы 71немного, максимум 72.
Маринус

1

Рубин 69-50 = 19 (или -4)

Это определенно можно сыграть в гольф вместе, но вот первая пятая попытка

p (1..eval(gets)).inject{|i,s|i+=s.to_s.chars.map(&:to_i).inject :+}

Он также работает для всех чисел, но очень медленно для них, поскольку работает медленнее, чем O (n), поэтому я бы не стал добавлять -25. Если медленность в порядке, то это было бы -4 хотя

Рубин 133-50-25 = 58

Это более быстрая версия, которая выполняется менее чем за O (n) времени (и использует реальную математику!), Поэтому она может быстро обеспечить результаты для больших целых чисел, поэтому я добавил -25:

n=eval(gets);p (d=->n,l{k=10**l;c,r=n.to_s[0].to_i,n%k;n<10?n*(n+1)/2:c*45*l*k/10+k*(c*(c-1)/2)+(r+1)*c+d[r,l-1]})[n,n.to_s.length-1]

Мы пишем точно такой же код (вы играли в гольф немного больше)!
Бетерраба

@Beterraba да, и почти в то же время, но вы были немного быстрее, поэтому я должен придумать что-то другое :)
SztupY

1

Хаскель, 74-25 = 49

main=getLine>>=print.sum.map(\c->read[c]).concatMap show.(\x->[0..x]).read


Используя interactи тот факт, что >>=для списков то же самое flip concatMap, вы можете main=interact$show.sum.map(\c->read[c]). \x->[0..read x]>>=show
сыграть в

Еще один байт для сохранения: \c->read[c]этоread.(:[])
nimi

1

ECMAScript 6, 86 - 50 = 36

for(s="",i=eval(prompt());i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c).join()).length)

Один символ меньше: for(i=eval(prompt(s=""));i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c).join()).length).
Зубная щетка

Немного меньше (вам не нужно .join()) for(i=eval(prompt(s=""));i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c)).length). 78 - 50 = 28 !
Зубная щетка

1

R (72 балла)

f=function(n) sum(as.integer(strsplit(paste0(1:n,collapse=""),"")[[1]]))

Выход:

> f(5)
[1] 15
> f(12)
[1] 51
> f(1000000)
[1] 27000001

В этих задачах вам нужно явно написать «f = function (n)» или просто функцию с n?
Скан

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