Contagem da soma de todos os dígitos

38

Esse desafio é escrever um programa ou script que conte a soma de todos os dígitos dentro dos números inteiros, de 1 até e incluindo um determinado número.

Entrada, um número inteiro positivo. Saída, a soma dos dígitos nesse número e todos os números menores.

Exemplos:

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

Para ficar claro, isso é contar uma soma dos dígitos - não dos números inteiros. Para entradas de um dígito, será o mesmo. No entanto, entradas maiores que 10 terão respostas diferentes. Esta seria uma resposta incorreta :

Input: 12
Output: 78

Outro exemplo, para mostrar a diferença:

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

Um caso de teste maior (RESPOSTA CORRETA):

Input: 1000000
Output: 27000001

Regras e Diretrizes:

  • O código enviado deve ser um programa ou script completo - não apenas uma função. Se o código exigir inclusões, importações, etc., eles deverão ser incluídos no código publicado.
  • O número deve ser inserido pelo usuário - não codificado. A entrada pode ser recebida como argumento da linha de comando, arquivo, stdin ou qualquer outro meio pelo qual seu idioma possa receber a entrada do usuário.
  • O código deve ser capaz de manipular adequadamente as entradas pelo menos até (2^64)-1.
  • O código deve gerar apenas a soma.
  • Os programas e scripts enviados devem ser fáceis de usar e não desperdiçar recursos de computador (por exemplo: eles não devem declarar matrizes incrivelmente grandes para conter todos os caracteres). Não há bônus ou penalidade estrita para isso, mas seja um bom programador.

Pontuação:

O mecanismo de pontuação principal é pelo tamanho do código. Pontuações mais baixas são melhores. Os seguintes bônus e penalidades também se aplicam:

  • -25 Bônus se o seu código puder lidar com todos os números positivos, por exemplo:1234567891234567891234564789087414984894900000000
  • -50 Bônus se o seu código puder lidar com expressões simples, por exemplo 55*96-12. Para se qualificar para esse bônus, o código deve manipular + - / *operadores (adição, subtração, divisão, multiplicação) e impor a ordem das operações. Divisão é divisão inteira regular.
    • O exemplo dado ( 55*96-12) é avaliado como 5268. Seu código deve retornar o mesmo para qualquer uma dessas entradas - a resposta correta é 81393.
  • -10 Bônus se o seu código se qualifica para o bônus -50 e pode lidar com o ^operador (expoente).
  • Bônus -100 se o seu código se qualifica para o bônus -50 e não usa evalou similar para manipular expressões.
  • +300 de penalidade se o seu código depender de quaisquer recursos da web.
ST3
fonte
2
E o que deveria 55*96-12retornar?
precisa
1
55 * 96-12 = 5268, deve ser a mesma saída inserida 5268
ST3
3
Os bônus podem ser um pouco no lado grande, parece estar se tornando uma competição no maior pontuação negativa :)
Joachim Isaksson
7
@ ST3 Se for virtualmente impossível ganhar sem os bônus, é quase melhor apenas cumpri-los, ou valer menos.
Cruncher
3
-1 porque esse desafio usa o incentivo de pontuação desatualizado (e terrível) dos "bônus".
Mbomb007

Respostas:

9

Perl 6: 108 - (25 + 50 + 100) + 0 = -67 pontos

Solução Golfed (linha final baseada na excelente solução do xfix ):

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

Solução sem golfe:

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

A etapa de avaliação funciona por iteração sobre cada símbolo de *, /, +, -, encontrar quando que fica entre dois inteiros, e substituindo que usar a função que o símbolo representa.

Mais detalhadamente: ele pega cada símbolo (por exemplo +) e a função infix que deve representar (por exemplo, &[+]qual é a abreviação para &infix:<+>a mesma função que o Perl 6 chama quando você executa 1 + 2) e faz uma substituição global ( s:g[…] = …que é como o Perl 5 s/…/…/ge), que corresponde a dois números inteiros separados pelo símbolo ( (\d+) $sym (\d+)) e o substitui pela saída da função infix correspondente chamada com esses números inteiros ( infix($0, $1)).

Finalmente, essa expressão avaliada é inserida say [+] (1..$expression)».comb, o que xfix explica muito bem em sua solução .

Desculpe estar atrasado para a festa ☺

Edição: Removido suporte para expoentes; eram exatamente 10 caracteres de qualquer maneira e não faziam associatividade corretamente.

Mouq
fonte
Isso é ótimo. Eu gosto de como você fez um analisador muito simples - tentei, mas não consegui fazer algo tão curto quanto isso. Em vez de my $gvocê pode querer usar algo pré-declarado (acho que $!poderia funcionar, mas não testei).
21978 Konrad Borowski
@ xfix, não sei como isso ajudaria o golfe. Existe uma maneira de realmente golf-lo, mas requer a "infix: [$ var]" ainda não totalmente funcional sintaxe: my$g=get;for <* / + -> {$g~~s:g[(\d+)$^s(\d+){}]=infix:[$^s] |@()};say [+] (1..$g)».combIsso iria obter a pontuação até 88 caracteres ou -97 pontos
Mouq
Ohh, o $! ajudaria a se livrar do 'meu'! Obrigado @xfix
Mouq
14

Mathematica 30- (10 + 50) = -30

Encurtado por 4 caracteres graças a ybeltukov.

Range@nretorna os números de 1 a n.

Integerdigits@n divide cada um desses números em seus dígitos.

Total[n,2]soma os dígitos. O 2 é para permitir a soma entre diferentes níveis, ou seja, listas de listas.

IntegerDigits@Range@#~Total~2&

Teste

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

51

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

27000001


Expressões

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

DavidC
fonte
Você deve adicionar informações sobre os argumentos válidos para obter todos os pontos de brownie: D
Yves Klett
1
Eu não sei se eu consideraria que não usar eval
Cruncher
3
re: Eval no Mathematica. É uma linguagem simbólica na qual o front-end sempre tenta resolver a matemática automaticamente. Você precisaria adicionar código adicional (mantenha pressionado []) para impedir que isso acontecesse.
Michael Stern
1
Tr@Flattenpode ser reduzida a Total[...,2]: IntegerDigits@Range@#~Total~2&.
precisa saber é o seguinte
1
Você não lida com int arbitrariamente grande e merece outro -25?
precisa saber é o seguinte
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);}

Muito vergonhosamente roubando a resposta @Fors daqui para fazer a avaliação da expressão: https://codegolf.stackexchange.com/a/11423/13877

Uso da amostra:

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

Nota: a implementação da expressão não assume precedência do operador e consome valores à medida que os recebe; ex, 1+2*3 = 9ao invés do típico 7.

Josh
fonte
1
Isso não lida com a precedência do operador, mas a pergunta não especifica se a precedência do operador padrão deve ser aplicada ... ping @ ST3, isso provavelmente deve ser esclarecido. De qualquer forma, provavelmente deve ser mencionado na resposta.
FireFly
@FireFly Modifiquei a resposta para refletir esse fato.
Josh
@ Josh - por favor, responda 2 ^
64-5
10

sed, 411283 - 25 = 258

Não posso me incomodar em jogar mais agora. :-) Não recomendado para uso com números inteiros grandes remotamente, mas tecnicamente ele pode lidar com números inteiros arbitrariamente grandes (você provavelmente ficará sem memória RAM muito rapidamente, porém, já que eu (mais ou menos) preciso codificar o número em unário).

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

Uso da amostra

(Linhas de entrada recuadas para facilitar a leitura.)

  5
15
  12
51
  33
183
FireFly
fonte
8

python, 55- (50 + 25 + 10) = -30

Ineficiente, porém mais curto e também capaz de lidar com expressões.

EDIT: Obrigado Wolframh e legoStormtroopr pelos truques: D

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

python, 149- (25 + 50 + 10) = 64

Minha primeira versão

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())

entrada:

1234567891234567891234564789087414984894900000000

saída:

265889343871444899381999757086453238874482500000214
Wasi
fonte
Eu recebo um erro de estouro quando tento executar o seu xrangesolução no1234567891234567891234564789087414984894900000000
Josh
1
@Josh se livrou de xrange: D
Wasi
2
Algumas dicas: Você pode substituir eval(raw_input())por input(). O whileloop pode ser while t:s+=sum(map(int,t ));t-=1.
Reintegrar Monica
2
Você pode encurtar isso usando apenas em input()vez de eval(raw_input()), como inputevalé a expressão! Isso significa que você pode obter o bónus -10 pelo símbolo de poder e o bônus -100 por não usar eval!!!
@LegoStormtroopr as regras dizem evale semelhantes , então eu acho que o -100 não contaria
SztupY
8

Python - 108 caracteres menos 85 bônus, 23 golpes, lida com entradas muito, muito muito grandes

A maioria dessas soluções parece estar repetindo todas as entradas menos que a entrada e somando todas as somas de dígitos. Isso funciona, mas eu acho que é deselegante e questionaria se eles são realmente elegíveis para o bônus de 25 pontos, já que eu não acho que eles seriam capazes de lidar com a entrada 1234567891234567891234564789087414984894900000000durante nossas vidas. De fato, em uma entrada de ndígitos, essas soluções levam O(10^n)tempo. Em vez disso, optei por jogar matemática nesse problema.

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

O conjunto de todos os xnúmeros de dígitos é isomórfico para o conjunto {0,1,2,3,4,5,6,7,8,9}^x. Para um fixo, (n,sig)existem xdiferentes valores para sig, 10^x-1pontos com o sigth índice definido como n, e a soma de todos os dígitos 0-9é 45. Isso é tudo tratado por f.

g é algo com o qual provavelmente todos estamos familiarizados

magicpega todos os dígitos do número de entrada e os repete do menos para o mais significativo. É mais fácil rastrear isso com um exemplo de entrada, digamos 1,234,567.

Para lidar com o intervalo 1,234,567-1,234,560, precisamos somar todos os dígitos de 1até 7e adicionar às 7vezes a soma dos outros dígitos, para lidar com todos os números maiores que 1,234,560. Agora precisamos lidar com o restante.

Para lidar com o intervalo 1,234,560-1,234,500, adicionamos 6( val) e diminuímos o limite superior para 1,234,559. Ao fazer o restante da queda, veremos todos os números de um dígito 6 vezes ( val*f(sig)). Veremos todos os números de 0até 5exatamente 10cada vez ( (10**sig)*g(val-1)). Veremos todos os outros dígitos desse número exatamente 60 vezes ( (val*10**sig)*sum(digits[sig+1:])). Agora, lidamos com todos os números estritamente maiores que 1,234,500. A mesma lógica será aplicada indutivamente em todos os significados.

Jogar com este recurso, graças ao WolframH, reduz essa solução a

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]))

E a soma dos dígitos de todos os números inteiros até 1234567891234567891234564789087414984894900000000é265889343871444927857379407666265810009829069029376

O maior número que eu consegui jogar na versão de golfe é 10 ^ 300, momento em que os carros alegóricos começam a transbordar e a instabilidade numérica começa a causar problemas. Com uma rápida função de exponenciação quadrática e multiplicada, esse problema desapareceria.

E o suporte ao LaTeX seria realmente útil ...

ymbirtt
fonte
Agradável. Eu tentei atacar esse problema com a matemática há um tempo atrás, mas fiquei preso. Terei que revisar isso com cuidado mais tarde e pensar em como funciona.
FireFly
Boa resposta! É semelhante à maneira que eu contava, que seria se a entrada é 1000000 :)
ST3
1
+1 para usar matemática. No entanto, eu entendo 2.65889343871e+50, que é uma aproximação de ponto flutuante da solução real. Aparentemente, você imprimiu em int(t)vez de tcomo no código que você deu. Isso esta errado; a verdadeira solução é 265889343871444899381999757086453238874482500000214. Apenas evite usar flutuadores, ou seja, substitua **(x-1)pelos mais curtos **x/10.
Reintegrar Monica
1
Jogando golfe um pouco mais. É claro que o único global necessário é d(porque é usado duas vezes). Eliminando os outros (e usando alguns truques), chega-se a 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 caracteres). Funciona bem em entradas de qualquer tamanho (como int("1"*1000)).
Reintegrar Monica
1
@ymbritt 10**-1é 0.1, e a partir daí tudo se transforma em carros alegóricos. 1/10é 0(divisão inteira) e tudo pode permanecer ints.
Reintegrar Monica
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

A entrada manipula números até 1E100e avalia automaticamente. Pode lidar com expressões.

Embora seja uma variedade incrivelmente grande, não estou desperdiçando recursos do computador (isso é executado a partir de uma calculadora ).

Timtech
fonte
1
melhor resposta para esta pergunta, eu acho. usando um idioma da calculadora para escrever uma resposta de código de golfe para adicionar números. tão legal!
Malachi
1
@ Malachi Como eu sempre digo, quando o código golf = math, é hora de retirar a calculadora.
Timtech 15/01/14
2
Minha versão que permitia números até 9E99 aparentemente não era boa o suficiente, então não acho que você possa contar esse bônus. Além disso, tenho certeza de que você terá que contar a entrada como "com eval", de acordo com a resposta do Matraática de Carraher.
FireFly
1
Concordo com o FireFly, o bônus de não usar evalnão deve ser recebido.
ST3 16/01
3
Como uma calculadora não é um computador?
David Conrad
6

Scala 66

println((1 to readLine().toInt).flatMap(x=>(x+"").map(_-'0')).sum)
ValarDohaeris
fonte
6

C, 77 74

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

C, 150 124 - 25 = 99

Aqui está uma versão alternativa que tecnicamente deve ser elegível para o bônus de 25 para "qualquer" número inteiro positivo, mas é impraticável lentamente, pois o algoritmo tem tempo linear em sua entrada. Independentemente disso, foi divertido escrever. Subtrai manualmente um número lido como caracteres ASCII. Esta versão é 150 caracteres. (Agora, com código horrível, debochado e cheio de argumentos!)

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, 229224 - (50 + 100) = 74

Variação de manipulação de expressão. Implementos precedência do operador de acordo com regras típicas: / * - +. Limitado a 97 tokens = 48 termos.

#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);}
FireFly
fonte
Todos os números inteiros positivos significam que ele deve lidar com números ainda maiores que 99 dígitos.
ST3
Algoritmo @Firefly legal para trabalhar em números maiores do que os números incorporados!
Josh
5

GolfScript 18 - 50 = -32

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

Explicação: Suponha que a entrada seja "12":

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

A pilha é [0,1,2,3,...,12].

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

A pilha é "01234...9101112".

' '* # join a space between all characters

A pilha é "0 1 2 ... 1 0 1 1 1 2".

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

A pilha é [0,1,2,...,9,1,0,1,1,1,2].

{+}* # fold addition across the new array

A pilha é 51, conforme desejado.

A entrada aqui pode ser qualquer expressão válida do GolfScript, que pode incluir expoentes. Por exemplo:

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

Desde então 2(5 + 5) - 8 = 12. Eu acho que isso deve se qualificar para o bônus, mas talvez fosse esperado que fosse apenas se na forma normal, não na notação polonesa reversa do GolfScript.

Ben Reich
fonte
Também suporta ^?
SztupY
Ele suporta exponenciação na sintaxe GolfScript, que é:?
Ben Reich
Você não ganha bônus de 10, porque o programa tem de suportar ^, não ?ou powe etc.
ST3
@ ST3 Como desejar!
Ben Reich
4

Rubi, 37 - 50 = -13

Avaliação dupla, por todo o céu! Como nas outras soluções Ruby, acho que teoricamente isso deve funcionar com números arbitrariamente grandes, mas o tempo de execução seria ... terrível.

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

Versão mais antiga (pontuação de 49 a 50)

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

Supondo que o bônus de 10 caracteres realmente exija que o exponenciação seja um sinal de intercalação, a maneira mais curta que eu poderia acrescentar é:

.gsub ?^,'**'

O que custa mais caracteres do que o bônus daria.

Paul Prestidge
fonte
Você pode remover alguns caracteres:p"#{[*1..eval(gets)]}".chars.map(&:to_i).inject :+
SztupY 15/01
@SztupY boa chamada, obrigado! Eu não uso &quase o suficiente no golfe. Na verdade, você não precisa do espaço entre injecte :+tampouco.
Paul Prestidge
4

Perl 6 (28 - 75 + 0 = -47 bytes)

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

Ele pode lidar com todos os números positivos (no entanto, os grandes levarão um longo tempo, porque atualmente as implementações do Perl 6 são lentas, mas o Perl 6 suporta inteiros grandes nativamente). Ele usa eval, para implementar uma calculadora simples (pena de cinco caracteres por cinquenta caracteres vale a pena). É lento apenas porque as implementações atuais são lentas, mas, em teoria, deve ser rápido o suficiente (quando as implementações do Perl 6 melhorarem, isto é). Surpreendentemente, também ganhei com o Mathematica (por enquanto).

» nesse código, na verdade, não é necessário, mas eu o coloquei aqui por razões de desempenho (caso contrário, o programa alocaria uma string inteira. A razão pela qual está aqui é que o Perl 6 não possui seqüências infinitas, mas possui listas infinitas.

De qualquer forma, você pode perguntar como esse código funciona. Bem, eu vou passar parte por parte.

  • get.eval

    Isso obtém uma linha ( getfunção) e a avalia ( evalmétodo).

  • 1..get.eval

    Depois disso, o Perl 6 prepara um objeto de intervalo, do 1valor avaliado. Esse é um intervalo, então nada de grande é alocado.

  • ».comb

    .combO método divide a string em caracteres (a menos que seja chamado com um argumento ). Por exemplo, 'cat'.combretorna 'c', 'a', 't'. »mapeia os elementos da lista, para que .combseja executado em todos os itens - não apenas na lista em si (por exemplo, (4, 9)».sqrtfornece 2, 3). Isso também não aloca mais do que o necessário, porque o Perl 6 possui listas infinitas (como Haskell, por exemplo).

    »O caractere realmente não é necessário, pois .combpode ser usado diretamente na lista, mas isso envolve coerção implícita de strings (e o Perl 6 não possui infinitas strings, portanto isso desperdiçaria memória). Por exemplo, a 1, 2, 3lista após a conversão na string é retornada 1 2 3. Para Perl 6, um espaço é um número perfeitamente fino que significa 0, portanto o código funcionaria, mesmo com essa conversão. No entanto, abusaria dos recursos de computação.

  • [+]

    Este é um operador de redução. Basicamente, []nesse caso, você pode usar um operador +. A lista depois reduzir operador é reduzido, de modo que [+] 1, 2, 3é 1 + 2 + 3, o que é 6. O Perl 6 usa operadores separados para números e seqüências de caracteres, portanto não será considerado concatenação.

  • say

    Finalmente, saygera o resultado. Afinal, você quer ver o resultado final, não é?

Konrad Borowski
fonte
Hmmm ... [+] 1,2,3,4,5,6,7,8,9,10é 1+2+3+4+5+6+7+8+9+10, estou certo?
ST3 11/02
@ ST3: Sim. O operador Reduce pode ser usado de várias maneiras interessantes no Perl 6. Por exemplo, >pode ser encadeado, então isso 3 > 2 > 1é verdade. A mesma propriedade se aplica à redução de operadores, portanto, [>] 3, 2, 1ainda é verdade, pois significa 3 > 2 > 1- [>]pode ser usada para determinar se os números estão em ordem decrescente.
Konrad Borowski
você não poderia usar em get.Intvez de eval? Precisa de expressões matemáticas?
Ven
@ user1737909: "-50 Bônus se o seu código puder lidar com expressões simples". Além disso, o Perl 6 não precisa de projeção por design (além de alguns casos de borda raros, como sortsem argumento do método de comparação).
Konrad Borowski
4

Perl 31 - Sem bônus

map{s/./$%+=$&/ge}0..<>;print$%

Saída de amostra:

perl -e 'map{s/./$%+=$&/ge}0..<>;print$%'
1000000
27000001

Perl 5 com -p, 50 - 28 bytes: -22

map$\+=$_,/./g for 1..eval}{

Experimente online!

Dom Hastings
fonte
3

J, 22

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

Explicação

A avaliação prossegue da direita para a esquerda.

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

>: n -> n+1

": numbers -> 'numbers'

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

+/ -> sum
DevonMcC
fonte
O downvoter precisa explicar suas objeções a esta resposta. Eu apenas tentei e, embora não ganhe nenhum bônus, funciona muito bem até onde posso ver.
Gareth
Na verdade, tendo analisado a resposta principal, essa também parece ganhar as expressões e os bônus do operador de energia por uma pontuação de 22-60 = -38.
Gareth
Isso +/,10#.inv>:i.seria mais curto. Mas ainda é uma função e não um programa completo, como o OP pediu.
swish
Os bônus @Gareth não se aplicam a esta resposta, porque você escreveria expressões dentro do código e não como entrada.
swish
1
@swish Isso é o que eu pensava no começo, mas a resposta do Mathematica parece funcionar assim.
Gareth
3

R, 64 - (50 + 10) = 4

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

Quando isso é executado, o usuário é solicitado a inserir.


Versão antiga (não pode lidar com expressões): 46 caracteres:

sum(utf8ToInt(paste(0:scan(),collapse=""))-48)
Sven Hohenstein
fonte
Ocorre-me que o codegolf é muito influenciado por idiomas com funções de símbolo único. Essa solução seria consideravelmente mais curta se predefiníssemos u<-function(x) utf8ToInt(x)e assim por diante.
Carl Witthoft
@CarlWitthoft Isso é verdade. Mas a predefinição também conta para o número de caracteres. A propósito: basta ter u <- utf8ToIntsem function. Isso pode ser útil para o código de golfe se a função for usada várias vezes.
Sven Hohenstein
portanto, se eu criar um Rcheatcodegolfpacote, é legal usar as funções predefinidas nesse pacote? :-)
Carl Witthoft
@CarlWitthoft Sim, os pacotes podem ser usados. Obviamente, o pacote não deve ser escrito para a tarefa. Mas se incluir nomes abreviados apenas para funções, tudo bem.
Sven Hohenstein
3

Lote - (181 - 50) - 131

Só por diversão.

@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!

Vou torná-lo um pouco mais legível:

@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!

O método antigo usa o loop for para obter a saída do comando powershell, em vez de gravar e ler um arquivo:

@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!

Defina a entrada como uma variável - v- usando /apara aceitar expressões aritméticas.
Infelizmente, era necessário ativar a expansão atrasada.
Use um loop for para contar de 1 ao valor inserido - v.
Para lidar com números maiores que 9, tive que usar o powershell para obter o comprimento da string e usar outro loop for para dividir essa string e adicioná-la à soma - s.
Você pode alterar o nome powershell.exepara p.exeem C: \ WINDOWS \ System32 \ WindowsPowerShell \ v1.0 \ e chamá-lo com apenas p "&{'%%a'.length-1}, economizando 9 bytes. Mas isso não está realmente no espírito disso.

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

Deixei o segundo correndo enquanto eu tomava meu almoço.

Eu realmente não posso testá-lo com números que são também muito maior do que isso devido à forma como retardá-lo é. No entanto, deve funcionar para números razoavelmente grandes. 2147483647é o maior número necessário (número inteiro máximo de 32 bits) antes de fornecer o seguinte erro -

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

É claro que isso me desqualifica do desafio.

desgrudar
fonte
1
Ótima solução! Existem algumas maneiras de jogar isso para baixo. 1. Você pode se livrar da variável temporária ve usá-la %1diretamente. 2. Você pode subtrair 1 no script do PowerShell em vez do longo, o @set /a b=%%b-1que economiza muito. Com essas mudanças, eu tê-lo para baixo para 211 a partir do original 240. :-)
Mark
Opa, agora entendo por que você manteve sua variável temporária (para os pontos de bônus). A ponta PowerShell continua de pé, embora ...
Mark
Bem visto, obrigado. Vai mudar isso agora.
unclemeat
Lote não funcionará. É limitado a (2 ^ 31) -1 (número inteiro assinado de 32 bits). O desafio requer o manuseio de entradas de até (2 ^ 64) -1 (número inteiro de 64 bits não assinado, mas a saída para esse valor a excederia). É aqui que o PowerShell tem uma vantagem distinta - seu [decimal]tipo permite valores de até (2 ^ 96) -1.
Iszi
1
Entretanto, darei um bom crédito ao lote por ter padronizado a divisão inteira. Isso é algo em que o PowerShell está totalmente ausente.
Iszi
3

Dyalog APL , 9-160 * = -151

+/⍎¨∊⍕¨⍳⎕

Experimente online!

obter entrada avaliada,
 por exemplo, "7+5"12

índices 1 ... n
[1,2,3,4,5,6,7,8,9,10,12]

⍕¨ formate cada número em string
["1","2","3","4","5","6","7","8","9","10","11","12"]

alistar-se (achatar)
"123456789101112"

⍎¨ executar cada caractere (produz uma lista de números de um dígito)
[1,2,3,4,5,6,7,8,9,1,0,1,1,1,2]

+/ soma  51


* Pontuação

-50 de bônus, pois até aceita expressões como entrada. A expressão deve ser APL válida, aceitável de acordo com OP .

-10 de bônus porque porque ele também lida com o ^( *no APL).

-100 de bônus porque a entrada de expressão é manipulada sem o uso explícito de eval(ou seja, no APL).

Adão
fonte
Tem certeza de que o bônus -100 foi adicionado aqui? Porque ele afirma " -100 Bonus se o seu código se qualifica para o bônus -50 e não usa eval ou similar para manipular expressões. " Como ⍎¨parece executar cada caractere um por um, é quase o mesmo que um eval (exceto que executa os caracteres um por um em vez de todos ao mesmo tempo, como evalfaz).
Kevin Cruijssen
@KevinCruijssen Sim, pois não usa eval ou similar para lidar com expressões. ⍎¨é usado apenas para converter dígitos em números inteiros, não para manipular expressões.
Adám
Ah, espere, olhei para a sua explicação incorretamente. Mas não é o tipo de entrada + avaliação integrada então, ou a avaliação é sempre feita implicitamente quando as expressões são inseridas?
Kevin Cruijssen 9/10
1
@KevinCruijssen sempre pega uma expressão como entrada, avalia-a e retorna seu resultado. Então, para inserir uma string, você precisará colocar aspas. O fato de um built-in ( ) retornar a entrada como texto bruto não deve importar (especialmente porque os símbolos indicam que é o método de entrada principal e é uma variante especial), pois, caso contrário, obter o bônus exigiria a implementação de uma matemática avaliador - uma tarefa totalmente diferente da principal. Eu não gosto de bônus, e o -100 é bobo ou tinha APL em mente, mas imho, parece um ajuste exato para o bônus.
Adám
Se, de fato, é a maneira normal de obter informações e manipular expressões automaticamente, eu também acho que isso se encaixa no bônus, portanto, +1 de mim. De qualquer forma, os bônus são bobos hoje em dia, mas é uma maneira agradável de utilizá-los para minimizar sua pontuação.
Kevin Cruijssen
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));}}

Bonita

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)
            );
    }
}
Firo
fonte
2

Python3 + Bash (78 - 185 = -107)

python3 -c"print(sum(sum(map(int,str(x+1)))for x in range(int(${1//^/**}))))"
  • pode lidar com todos os números positivos
  • pode manipular expressões com a operação + - / *
  • pode lidar com o operador ^ (poder).
  • pode lidar com expressões, sem avaliação ou similar¹

Se o resultado da expressão não for inteiro, ele será truncado primeiro. Se o resultado da expressão for negativo, o resultado será indefinido.

Use-o como:

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

1: a menos que você conte invocando o Python do Bash como tal, mas não acho que seja esse o caso. Se você acha que realmente é, então a pontuação ajustada é -7.

Stefano Sanfilippo
fonte
Eu diria que, se você não escreveu um avaliador de expressão, está usando algo equivalente a avaliar. Mas eu não sou o OP, então boa sorte!
Tobia
Concorde com @Tobia, sem bônus para avaliador de expressão.
ST3
2

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

Manipula expressões. Dê a expressão que desejar no alvo. Alças até que o comprimento possa suportar. Se você limpar a remoção de todos os espaços em uma linha e nenhuma declaração para imprimir, ela conta com 254 caracteres (considerando as longas palavras baseadas na programação Java).

PS: Este é um programa completo, não apenas lógico. Contagem de palavras dada para o programa, não apenas a lógica.

Sri
fonte
2

Java (JDK8), 272

Meu primeiro desafio, sugestões são bem-vindas =)

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

Recuado:

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));
  }
}
whyem
fonte
+1 como todo mundo que desafia o código de golfe em java merece, mas parece que a API do Stream não oferece vantagens durante o jogo. Aposto que se você reescrever sua solução e usar loops, o fluxo será mais curto.
user902383
2

CJam, 9 - 25 = -16

O CJam é alguns meses mais novo que esse desafio, portanto, não é elegível para a marca de seleção verde. Além disso, isso não está superando o Perl. ;) Eu gostei bastante da abordagem, então queria publicá-la de qualquer maneira.

l~),s:~:+

Teste aqui.

A idéia é criar um intervalo de 0 a N. Esse intervalo é então convertido em uma string, que apenas concatena os números inteiros consecutivos. Para N = 12, teríamos

"0123456789101112"

Cada caractere é convertido em um número inteiro com :~(produzindo uma matriz de números inteiros) e, em seguida, resumido com :+. O CJam pode lidar com números inteiros arbitrariamente grandes.

Martin Ender
fonte
2

Python 3 + astor ,1017 1007 bytes - (25 + 50 + 100) = Pontuação: 842 834

salvou 10 bytes removendo tse alterandop

edit: Não consigo testar o número inteiro ridiculamente longo (1234567891234567891234564789087414984894900000000) [trava o meu computador], mas, pelo que sei, o Python 3 suporta números inteiros arbitrariamente longos.

Esta implementação usaabusa da AST. Eu não consideraria abusar do AST como "eval ou similar".

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()))))))

Com preguiça de escrever sem limites, então eu vou lhe dar uma explicação das aulas:

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.

A última linha apenas executa essas classes na ordem apropriada na entrada, para preservar a ordem das operações e evitar comportamentos indesejados.

Exemplo de uso ($ ou> significa entrada do usuário) e, a propósito, o programa real recebe entrada apenas uma vez:

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

fonte
Isso é incrível, mas ainda horrível. Não tenho certeza se é permitido (usar conscientemente uma solução longa), mas 10/10 de mim.
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Por que não é permitido usar conscientemente uma solução longa? Não vejo problema. Pelo menos eu vou bater soluções com 842+ pontuação;)
Eles deveriam ser respostas competitivas , o que significa mostrar esforço. Além disso, exclua esse comentário. SE O LIMITE PARA IDADE É 13 !!! Você provavelmente deve esperar até ter permissão legal para participar. Devido à COPPA (google it), você precisa ter 13 anos para usar a internet assim.
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Agora estou curioso, quem era esse usuário?
cat
1
@cat Um nome árabe que não consegui pronunciar? Provavelmente conta nuked.
Rɪᴋᴇʀ
1

C # (108)

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

Bonita

int c(int n)
{
    return string.Join("", Enumerable.Range(1, n).Select(i => i + "")).ToArray().Select(c => c - '0').Sum();
}
microbiano
fonte
3
Não é uma resposta válida, pois é função e contagem de caracteres é grande demais
ST3 15/01
1
Você não precisa dos int; em C, tudo é padronizado como int... Ah, é c #.
Wizzwizz4
1

Rubi -> 83-50 = 33

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

Versão "Para testar":

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 

Resultados dos testes

$ 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
Beterraba
fonte
1

C # (80)

É minha outra tentativa.

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

Bonita

double c(int n)
{
    double s = 0;
     while (n > 0)
        foreach(var c in n--+"") 
            s += c - 48;
    return s;
}
microbiano
fonte
O espaço em branco está entre n--e é +necessário? Eu não acho que seja em outras linguagens de estilo C.
FireFly
1
Isso funciona com o intervalo especificado? O resultado para 2^64-1não cabe em 64 bits.
marinus
2
Não é uma resposta válida, pois é função e a contagem de caracteres é muito grande.
ST3
@ marinus Você pode nos dar o resultado de 2 ^ 64-1 para que possamos saber com que faixa precisamos trabalhar? Não ouso testá-lo no meu idioma (PowerShell), pois o tempo de processamento seria enorme.
Iszi
@ Iszi: Na verdade, não vou executá-lo, mas você pode fazer algumas contas: 1) o valor médio de um dígito é 4.5; 2) a soma média de 20 dígitos é 90( 2^64possui 20 dígitos); então o valor esperado estará em torno de 90 * 2^64 ≈ 1.66*10^21. Então você precisaria de pelo menos 71bits, no máximo 72.
marinus
1

Ruby 69-50 = 19 (ou -4)

Definitivamente, isso pode ser jogado juntos, mas aqui está a primeira quinta tentativa

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

Ele também funciona para todos os números, mas é muito lento para eles, pois é mais lento que O (n), então eu não adicionaria o -25. Se a lentidão for boa, seria -4, embora

Ruby 133-50-25 = 58

Esta é a versão mais rápida, executada em menos de O (n) tempo (e usa matemática real!), Para que possa fornecer resultados rapidamente para números inteiros grandes, adicionando -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]
SztupY
fonte
Escrevemos exatamente o mesmo código (você jogou um pouco mais)!
Beterraba
@Beterraba sim, e quase ao mesmo tempo, mas você estava um pouco mais rápido, então eu tenho que descobrir algo diferente :)
SztupY
1

Haskell, 74-25 = 49

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

Vektorweg
fonte
O uso interacte o fato de que >>=para listas é o mesmo que flip concatMapvocê pode jogar até 63 caracteres como este:main=interact$show.sum.map(\c->read[c]). \x->[0..read x]>>=show
Flonk
Mais um byte para salvar: \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)
FireFly
fonte
Um personagem menos: for(i=eval(prompt(s=""));i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c).join()).length).
Escova de dentes
Um pouco menor (você não precisa a .join()): for(i=eval(prompt(s=""));i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c)).length). 78 - 50 = 28 !
Escova de dentes
1

R (72 pontos)

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

Saída:

> f(5)
[1] 15
> f(12)
[1] 51
> f(1000000)
[1] 27000001
djhurio
fonte
Nesses desafios, você precisa escrever explicitamente "f = function (n)" ou apenas a função com n?
skan
@skan, isso depende dos requisitos. Geralmente, não é necessário ter uma função explícita.
djhurio