Підрахуйте суму всіх цифр


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

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

  • Надісланий код повинен бути повноцінною програмою або сценарієм - не лише функцією. Якщо код вимагає включення, імпорту тощо, вони повинні бути включені до розміщеного коду.
  • Номер повинен бути введений користувачем - не жорстко закодований. Вхід може бути отриманий як аргумент командного рядка, файл, stdin або будь-який інший спосіб, за допомогою якого ваша мова може приймати дані користувача.
  • Код повинен бути в змозі належним чином обробляти входи, щонайменше, до (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 дуже добре пояснює у своєму рішенні .

Вибачте, що запізнилися на вечірку ☺

EDIT: Видалена підтримка експонентів; це було рівно 10 символів і не робив асоціативності правильно.


Це чудово. Мені подобається, як ти зробив дуже простий парсер - я спробував, але мені не вдалося зробити щось таке коротке. Замість my $gвас, можливо, ви хочете використовувати щось попередньо визначене (я думаю, це $!могло б працювати, але я не перевіряв).
Конрад Боровський

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

Ох, $! допоможе позбутися від "мого"! Спасибі @xfix
Mouq

14

Математика 30- (10 + 50) = -30

Скорочено на 4 символи завдяки ybeltukov.

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: Евал в Математиці. Це символічна мова, в якій фронт-енд завжди намагається вирішити подібний Math автоматично. Вам потрібно буде додати додатковий код (Утримувати []), щоб не допустити цього.
Майкл Стерн

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

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 Я змінив відповідь, щоб відобразити цей факт.
Джош

@Josh - будь ласка, надайте відповідь за 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

Неефективний, але коротший, а також здатний обробляти вирази.

EDIT: Дякую Вольфрам та 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
@Josh позбувся 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

Пітон - 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до 5рівно 10раз кожен ( (10**sig)*g(val-1)). Усі інші цифри в цьому числі ми побачимо рівно 60 разів ( (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(ціле ділення), і все може залишитися ints.
Відновіть Моніку

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", відповідно до відповіді Математики Каррахера.
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);}

C, 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

Подвійний евал, всю дорогу через небо! Як і у випадку з іншими рішеннями 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і :+будь-яким.
Пол Престиждж

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: Так. Оператор скорочення може бути використаний багатьма цікавими способами в 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

Downvoter повинен пояснити свої заперечення щодо цієї відповіді. Я щойно спробував це, і, хоча він не заробляє жодних бонусів, він працює чудово, наскільки я бачу.
Гарет

Насправді, подивившись на головну відповідь, цей також, здається, заробляє вирази та бонуси оператора енергії за рахунок 22-60 = -38.
Гарет

Це +/,10#.inv>:i.було б коротше. Але це все-таки функція, а не повна програма, як просив ОП.
швейцарський

@Gareth Бонуси не поширюються на цю відповідь, тому що ви б просто писали вирази всередині коду, а не як вхідні дані.
швейцарський

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)

Мені здається, що кодегольф дико упереджений до мов з односимвольними функціями. Це рішення було б значно коротшим, якби ми заздалегідь визначилися 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!

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

@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, мені довелося скористатися поворотом, щоб отримати довжину рядка, а потім використати інший цикл, щоб розділити цю рядок вгору і додати її до суми - s.
Ви можете змінити ім'я powershell.exeна p.exeв на C: \ 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. :-)
Позначте

На жаль, тепер я бачу, чому ви зберегли темп-змінну (для бонусних балів). Підказка PowerShell все ще стоїть, хоча ...
Позначте

Добре помічений, спасибі Чи зміниться це зараз.
нечисте м'ясо

Пакет не працює. Вона обмежена (2 ^ 31) -1 (підписане 32-бітове ціле число). Виклик вимагає обробки входів до (2 ^ 64) -1 (непідписане 64-бітове ціле число, але вихід для цього значення переповнюватиме його). Тут PowerShell має виразну перевагу - його [decimal]тип передбачає значення до (2 ^ 96) -1.
Іссі

1
Я дам Batch хороший кредит за невиконання цілого поділу. Це те, що PowerShell повністю не вистачає.
Іссі

3

Діалог APL , 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, що прийнятно відповідно до ОП .

-10 бонус, тому що він також обробляє ^( *в APL).

-100 бонус, оскільки введення вираження обробляється без явного використання eval(тобто в APL).


Ви впевнені, що сюди додається бонус -100? Тому що в ньому зазначається " -100 бонус, якщо ваш код відповідає бонусу -50 і не використовує eval або подібний для обробки виразів ". Оскільки, ⍎¨здається, кожен символ виконує по одному, він такий же, як і eval (за винятком того, що він виконує символи по одному замість усіх одночасно, як evalце роблять).
Kevin Cruijssen

@KevinCruijssen Так, оскільки він не використовує eval або подібне для обробки виразів. ⍎¨використовується лише для перетворення цифр у цілі числа, а не для обробки виразів.
Адам

А чекай, я неправильно переглянув твоє пояснення. Але хіба це не вбудований + введений eval тоді, чи завжди eval робиться неявно, коли вводяться вирази?
Kevin Cruijssen

1
@KevinCruijssen завжди приймає вираз як вхідний, оцінює його та повертає його результат. Отже, щоб ввести рядок, вам доведеться ставити лапки навколо нього. Той факт, що пов’язаний вбудований ( ) повертає введення як сирий текст, не має значення (тим більше, що символи вказують, що це основний метод введення та є спеціальним варіантом), оскільки в іншому випадку отримання бонусу вимагатиме впровадження математики оцінювач - зовсім інше завдання, ніж основне. Мені не подобаються бонуси, і -100 - це просто нерозумно або мав на увазі APL, але так, здається, це точно підходить для бонусу.
Adám

Якщо це дійсно нормальний спосіб отримання даних і автоматично обробляє вирази, я дійсно вважаю, що це також входить у бонус, тому +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//^/**}))))"
  • може впоратися з усім позитивним числом
  • може обробляти вирази за допомогою операції + - / *
  • може працювати з оператором ^ (потужність).
  • може обробляти вирази, без овалу чи подібного¹

Якщо результат вираження не є цілим, він буде усікатися спочатку. Якщо результат виразу негативний, результат не визначений.

Використовуйте його так:

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

1: якщо ви не вважаєте посиланням Python від Bash як такого, але я не думаю, що це так. Якщо ви думаєте, що це насправді так, то скоригована оцінка дорівнює -7.


Я б сказав, що якщо ви не написали оцінювач виразів, то ви використовуєте щось еквівалентне eval. Але я не ОП, тож удача!
Тобія

Погодьтеся з @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

Java (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 не дає вам переваги під час гри в гольф. Буду сумнівом, якщо ви перезаписуєте своє рішення, і ви будете використовувати петлі замість потоків, це буде коротше.
користувач902383

2

CJam, 9 - 25 = -16

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

l~),s:~:+

Тестуйте це тут.

Ідея полягає у створенні діапазону від 0 до N. Цей діапазон потім перетворюється на рядок, який просто об'єднує цілі числа спина назад. Для N = 12 ми отримаємо

"0123456789101112"

Потім кожен символ перетворюється на ціле число з :~(даючи масив цілих чисел), а потім підсумовується з :+. CJam може мати справу з довільно великими цілими числами.


2

Python 3 + astor ,1017 рік 1007 байт - (25 + 50 + 100) = Оцінка: 842 834

збережено 10 байт шляхом видалення tsта зміниp

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

Ця реалізація використовуєзловживання AST. Я б не вважав зловживання 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+;)

Вони повинні бути конкурентними відповідями, тобто показувати зусилля. Крім того, ВИДАЛИТИ ЦЕ КОМЕНТАР. СЕ ОГРАНИЧУЄТЬСЯ НА ВІК ВІД 13! Вам, мабуть, слід дочекатися, поки вам законно дозволено перебувати. Через COPPA (google it) вам потрібно 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 бітам.
marinus

2
Це неправдива відповідь, оскільки це функція, а кількість знаків - це велике.
ST3

@marinus Чи можете ви дати нам результат для 2 ^ 64-1, щоб ми могли знати, з яким діапазоном нам потрібно працювати? Я не наважуюся перевірити його на своїй мові (PowerShell), оскільки час обробки був би величезним.
Іссі

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

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 yup, і майже в той же час, але ти був трохи швидше, тому я повинен з'ясувати щось інше :)
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 = функція (n)" або просто функцію з n?
скан

@skan, це залежить від вимог. Зазвичай не потрібно мати явної функції.
dhhurio
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.