Cuenta suma de todos los dígitos


38

Este desafío es escribir un programa o script que cuente la suma de todos los dígitos dentro de los enteros desde 1 hasta e incluyendo un número dado.

Entrada, un entero positivo. Salida, la suma de dígitos en ese número y todos los números más pequeños.

Ejemplos:

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 ser claros, esto es contar una suma de los dígitos , no los enteros. Para entradas de un solo dígito, esto será lo mismo. Sin embargo, las entradas mayores de 10 tendrán respuestas diferentes. Esta sería una respuesta incorrecta :

Input: 12
Output: 78

Otro ejemplo, para mostrar la diferencia:

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

Un caso de prueba más grande (RESPUESTA CORRECTA):

Input: 1000000
Output: 27000001

Reglas y pautas:

  • El código enviado debe ser un programa o script completo, no solo una función. Si el código requiere incluye, importaciones, etc., deben incluirse en el código publicado.
  • El número debe ser ingresado por el usuario, no codificado. La entrada puede recibirse como un argumento de línea de comando, archivo, stdin o cualquier otro medio por el cual su idioma puede tomar la entrada del usuario.
  • El código debe poder manejar correctamente las entradas al menos hasta (2^64)-1.
  • El código solo debería generar la suma.
  • Los programas y scripts enviados deben ser fáciles de usar y no desperdiciar recursos informáticos (por ejemplo, no deben declarar matrices increíblemente grandes para contener cada carácter). No hay una bonificación o penalización estricta por esto, pero sean buenos programadores.

Tanteo:

El mecanismo de puntuación principal es por longitud de código. Los puntajes más bajos son mejores. También se aplican las siguientes bonificaciones y sanciones:

  • -25 Bonificación si su código puede manejar todos los números positivos, por ejemplo:1234567891234567891234564789087414984894900000000
  • -50 Bonificación si su código puede manejar expresiones simples, por ejemplo 55*96-12. Para calificar para este bono, el código debe manejar + - / *(suma, resta, división, multiplicación) operadores y hacer cumplir el orden de las operaciones. La división es una división entera regular.
    • El ejemplo dado ( 55*96-12) se evalúa como 5268. Su código debe devolver lo mismo para cualquiera de esas entradas: la respuesta correcta es 81393.
  • -10 Bonificación si su código califica para la bonificación -50 y puede manejar el ^operador (exponente).
  • -100 de bonificación si su código califica para la bonificación de -50 y no utiliza evalo similar para manejar expresiones.
  • +300 Penalización si su código se basa en cualquier recurso web.

2
¿Y qué debería 55*96-12volver?
ProgramFOX

1
55 * 96-12 = 5268, debe ser la misma salida que la ingresada 5268
ST3

3
Los bonos pueden ser un poco grandes, parece convertirse en una competencia con el mayor puntaje negativo :)
Joachim Isaksson

77
@ ST3 si es prácticamente imposible ganar sin los bonos, entonces es casi mejor hacerlos requisitos, o valer menos.
Cruncher

3
-1 porque este desafío utiliza el anticuado (y horrible) incentivo de puntuación de "bonificaciones".
mbomb007

Respuestas:


9

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

Solución de golf (línea final basada en la gran solución de xfix ):

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

Solución sin golf:

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

La etapa de evaluación funciona mediante la iteración sobre cada símbolo de *, /, +, -, encontrando al que se encuentra entre dos números enteros, y sustituyendo que el uso de la función que representa el símbolo.

Más detalladamente: toma cada símbolo (por ejemplo +) y la función infija que se supone que representa (por ejemplo, &[+]cuál es la abreviatura &infix:<+>y la misma función que Perl 6 llama cuando ejecuta 1 + 2) y realiza una sustitución global ( s:g[…] = …que es como Perl 5 s/…/…/ge), que coincide con dos enteros separados por el símbolo ( (\d+) $sym (\d+)), y lo sustituye con la salida de la función infija correspondiente llamada con esos enteros ( infix($0, $1)).

Finalmente, esta expresión evaluada se alimenta say [+] (1..$expression)».comb, lo que xfix explica muy bien en su solución .

Perdón por llegar tan tarde a la fiesta ☺

EDITAR: Se eliminó el soporte para exponentes; De todos modos, tenía exactamente 10 caracteres y no asociaba correctamente.


Esto es genial. Me gusta cómo hiciste un analizador muy simple: lo intenté, pero no pude hacer algo tan corto como esto. En lugar de my $gque desee utilizar algo predeclarado (creo que $!podría funcionar, pero no lo he probado).
Konrad Borowski

@xfix, no estoy seguro de cómo eso ayudaría al golf. Hay una manera de jugar golf realmente , pero requiere la sintaxis "infix: [$ var]" aún no completamente funcional: my$g=get;for <* / + -> {$g~~s:g[(\d+)$^s(\d+){}]=infix:[$^s] |@()};say [+] (1..$g)».combesto reduciría el puntaje a 88 caracteres o -97 puntos
Mouq

Ohh, el $! ayudaría a deshacerse de 'mi'! Gracias @xfix
Mouq

14

Mathematica 30- (10 + 50) = -30

Acortado por 4 caracteres gracias a ybeltukov.

Range@ndevuelve los números del 1 al n.

Integerdigits@n divide cada uno de esos números en sus dígitos.

Total[n,2]suma los dígitos. El 2 es para permitir la suma en diferentes niveles, es decir, listas de listas.

IntegerDigits@Range@#~Total~2&

Pruebas

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

51

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

27000001


Expresiones

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


Debe agregar información sobre los argumentos válidos para obtener todos los puntos brownie: D
Yves Klett

1
No sé si consideraría que no usar eval
Cruncher

3
re: Eval en Mathematica. Es un lenguaje simbólico en el que el front-end siempre intenta resolver matemática de esa manera automáticamente. Tendría que agregar un código adicional (Hold []) para evitar que lo haga.
Michael Stern

1
Tr@Flattense puede reducir a Total[...,2]: IntegerDigits@Range@#~Total~2&.
ybeltukov

1
¿No manejas int arbitrariamente grande y mereces otro -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);}

Robando vergonzosamente la respuesta de @Fors desde aquí para hacer la evaluación de la expresión: https://codegolf.stackexchange.com/a/11423/13877

Uso de la muestra:

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

Nota: la implementación de la expresión no asume ninguna precedencia del operador y consume valores a medida que los recibe; ex, en 1+2*3 = 9lugar de lo típico 7.


1
Esto no trata con la precedencia del operador, pero la pregunta no especifica si se debe aplicar la precedencia estándar del operador ... ping @ ST3, esto probablemente debería aclararse. De todos modos, probablemente debería mencionarse en la respuesta.
FireFly

@FireFly Modifiqué la respuesta para reflejar este hecho.
Josh

@ Josh - por favor proporcione la respuesta para 2 ^ 64 - 5
SergeyS

10

sed, 411283-25 = 258

No puedo molestarme más en jugar golf ahora mismo. :-) No se recomienda su uso incluso con números enteros remotamente grandes, pero técnicamente podría tratar con números enteros arbitrariamente grandes (sin embargo, es probable que se quede sin RAM bastante rápido, ya que (más o menos tengo que) codificar el número en unario).

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 de la muestra

(Líneas de entrada con sangría para facilitar la lectura).

  5
15
  12
51
  33
183

8

pitón, 55- (50 + 25 + 10) = -30

In-eficiente pero más corto y también capaz de manejar expresiones.

EDITAR: Gracias Wolframh y legoStormtroopr por los trucos: D

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

pitón, 149- (25 + 50 + 10) = 64

Mi primera version

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

salida:

265889343871444899381999757086453238874482500000214

Recibo un error de desbordamiento cuando intento ejecutar su xrangesolución en1234567891234567891234564789087414984894900000000
Josh

1
@Josh se deshizo de xrange: D
Wasi

2
Algunas sugerencias: puede reemplazar eval(raw_input())por input(). El whilebucle podría ser while t:s+=sum(map(int,t ));t-=1.
Restablece a Mónica el

2
¡Puede acortar esto simplemente usando en input()lugar de eval(raw_input()), como inputya evales la expresión! ¡Esto significa que puede obtener el binus -10 para el símbolo de poder y el bono -100 por no usarlo eval!

@LegoStormtroopr las reglas dicen evaly similares , así que creo que el -100 no contaría
SztupY

8

Python - 108 caracteres menos 85 bonos, 23 golpes, maneja entradas muy muy muy grandes

La mayoría de estas soluciones parecen estar girando sobre todas las entradas menos que la entrada y sumando todas sus sumas de dígitos. Esto funciona, pero creo que es poco elegante, y cuestionaría si son realmente elegibles para la bonificación de 25 puntos, ya que no creo que puedan manejar la entrada 1234567891234567891234564789087414984894900000000dentro de nuestras vidas. De hecho, en una entrada de ndígitos, estas soluciones toman O(10^n)tiempo. En su lugar, elegí arrojar algunas matemáticas a este 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)

El conjunto de todos los xnúmeros de dígitos es isomorfo al conjunto {0,1,2,3,4,5,6,7,8,9}^x. Para un fijo (n,sig)hay xdiferentes valores para sig, 10^x-1puntos con el sigíndice th establecido en n, y la suma de todos los dígitos 0-9es 45. Todo esto se maneja mediante f.

g es algo con lo que probablemente todos estamos familiarizados

magictoma todos los dígitos del número de entrada y los repite de menor a mayor importancia. Es más fácil rastrear esto con una entrada de ejemplo, por ejemplo 1,234,567.

Para tratar con el rango 1,234,567-1,234,560, debemos sumar todos los dígitos de 1a 7, y sumar 7veces la suma de los otros dígitos, para tratar con todos los números mayores que 1,234,560. Ahora tenemos que lidiar con el resto.

Para lidiar con el rango 1,234,560-1,234,500, agregamos el 6( val) y colocamos el límite superior en 1,234,559. Al hacer el resto de la caída, veremos cada número de un solo dígito 6 veces ( val*f(sig)). Veremos todos los números desde 0hasta 5exactamente 10cada uno ( (10**sig)*g(val-1)). Veremos todos los otros dígitos en este número exactamente 60 veces ( (val*10**sig)*sum(digits[sig+1:])). Ahora hemos tratado con todos los números estrictamente mayores que 1,234,500. La misma lógica se aplicará inductivamente en todos los significados.

Jugar al golf con gracias a WolframH reduce esta solución 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]))

Y la suma de las sumas de dígitos de todos los enteros hasta 1234567891234567891234564789087414984894900000000es265889343871444927857379407666265810009829069029376

El número más grande que he logrado lanzar en la versión de golf es 10 ^ 300, momento en el cual los flotadores comienzan a desbordarse y la inestabilidad numérica comienza a causar problemas. Con una función de exponenciación rápida de cuadrado y multiplicación, este problema desaparecería.

Y el soporte de LaTeX sería realmente útil ...


Agradable. Intenté atacar este problema con las matemáticas hace un tiempo, pero me atasqué. Tendré que repasar esto con cuidado más adelante y pensar cómo funciona.
FireFly

¡Buena respuesta! Es similar a la forma en que conté, eso sería si la entrada es 1000000 :)
ST3

1
+1 por usar las matemáticas. Sin embargo, entiendo 2.65889343871e+50, que es una aproximación de punto flotante de la solución real. Aparentemente imprimiste en int(t)lugar de tcomo en el código que diste. Eso está mal; La verdadera solución es 265889343871444899381999757086453238874482500000214. Simplemente evite usar flotadores, es decir, reemplácelos **(x-1)por los más cortos **x/10.
Reinstale a Mónica el

1
Jugar al golf un poco más. Está claro que la única necesidad global es d(porque se usa dos veces). Eliminando a los demás (y usando algunos trucos) se llega 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 bien en entradas de cualquier tamaño (como int("1"*1000)).
Restablece a Mónica el

1
@ymbritt lo 10**-1es 0.1, y a partir de ahí todo se convierte en flotadores. 1/10es 0(división entera), y todo puede permanecer ints.
Restablece a Mónica el

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

La entrada maneja números hasta 1E100y evalúa automáticamente. Puede manejar expresiones.

Aunque es una matriz increíblemente grande, no estoy desperdiciando recursos informáticos (esto se ejecuta desde una calculadora ).


1
La mejor respuesta para esta pregunta, creo. usando un lenguaje de calculadora para escribir un código de respuesta de golf para sumar números. ¡Muy guay!
Malaquías

1
@Malachi Como siempre digo, cuando code golf = math, es hora de sacar la calculadora.
Timtech

2
Aparentemente, mi versión que permitía números hasta el 9E99 no era lo suficientemente buena, así que no creo que puedas contar esa bonificación. Además, estoy bastante seguro de que tendrá que contar la entrada como "con eval", según la respuesta de Carraher en Mathematica.
FireFly

1
De acuerdo con FireFly, no se evaldebe aprovechar la ventaja de no usar .
ST3

3
¿Cómo es una calculadora no una computadora?
David Conrad el


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

Aquí hay una versión alternativa que técnicamente debería ser elegible para la bonificación de 25 para "cualquier" número entero positivo, pero es prácticamente lenta ya que el algoritmo es de tiempo lineal en su entrada. De todos modos, fue divertido escribir. Resta manualmente un número leído como caracteres ASCII. Esta versión tiene 150 caracteres. (¡Ahora con un código horrible, de discusión y de bucle!)

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

Variación de manejo de expresiones. Implementos de precedencia de los operadores de acuerdo a las reglas típicas: / * - +. Limitado a 97 tokens = 48 términos.

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

Todos los enteros positivos significan que debe manejar incluso más de 99 dígitos.
ST3

¡Algoritmo genial de Firefly para trabajar en números más grandes que los números integrados!
Josh

5

GolfScript 18-50 = -32

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

Explicación: Supongamos que la entrada es "12":

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

Pila es [0,1,2,3,...,12].

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

Pila es "01234...9101112".

' '* # join a space between all characters

Pila es "0 1 2 ... 1 0 1 1 1 2".

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

Pila es [0,1,2,...,9,1,0,1,1,1,2].

{+}* # fold addition across the new array

La pila es 51, según lo deseado.

La entrada aquí podría ser cualquier expresión válida de GolfScript, que puede incluir exponentes. Por ejemplo:

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

Desde 2(5 + 5) - 8 = 12. Creo que esto debería calificar para la bonificación, pero tal vez se esperaba que fuera solo si estaba en forma normal, no la notación polaca inversa de GolfScript.


¿Es compatible ^también?
SztupY

Admite la exponenciación en la sintaxis de GolfScript, que es?
Ben Reich

No obtienes la bonificación 10, porque el programa debe admitir ^, no ?o, powetc.
ST3

@ ST3 ¡Como quieras!
Ben Reich

4

Rubí, 37-50 = -13

¡Doble evaluación, todo el camino a través del cielo! Al igual que con las otras soluciones de Ruby, creo que en teoría esto debería ser capaz de funcionar con números arbitrariamente grandes, pero el tiempo de ejecución sería ... terrible.

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

Versión anterior (49-50 puntos)

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

Suponiendo que la bonificación de 10 caracteres realmente requiere que el carácter de exponenciación sea un símbolo de intercalación, la forma más corta que podría agregar es:

.gsub ?^,'**'

Lo que cuesta más personajes de los que daría la bonificación.


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

@SztupY buena llamada, gracias! No uso &casi lo suficiente en el golf. De hecho, no necesita el espacio entre injecty :+tampoco.
Paul Prestidge

4

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

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

Puede manejar todos los números positivos (sin embargo, los grandes tardarán mucho tiempo, porque actualmente las implementaciones de Perl 6 son lentas, pero Perl 6 admite números enteros grandes de forma nativa). Utiliza eval, para implementar una calculadora simple (la pena de cinco caracteres por cincuenta caracteres vale la pena). Es lento solo porque las implementaciones actuales son lentas, pero en teoría, debería ser lo suficientemente rápido (cuando las implementaciones de Perl 6 mejoran, eso es). Además, sorprendentemente, gano con Mathematica (por ahora).

» en este código en realidad no es necesario, pero lo puse aquí por razones de rendimiento (de lo contrario, el programa asignaría una cadena completa. La razón por la que está aquí es que Perl 6 no tiene cadenas infinitas, pero sí tiene listas infinitas.

De todos modos, puede preguntar cómo funciona este código. Bueno, lo voy a pasar parte por parte.

  • get.eval

    Esto obtiene una línea ( getfunción) y la evalúa ( evalmétodo).

  • 1..get.eval

    Después de eso, Perl 6 prepara un objeto de rango, desde el 1valor evaluado. Este es un rango, por lo que no se asigna nada enorme.

  • ».comb

    .combEl método divide la cadena en caracteres (a menos que se llame con un argumento ). Por ejemplo, 'cat'.combvuelve 'c', 'a', 't'. »asigna los elementos de la lista, por lo que .combse ejecuta en cada elemento, no solo en la lista misma (por ejemplo, (4, 9)».sqrtda 2, 3). Esto tampoco asigna más de lo necesario, porque Perl 6 tiene listas infinitas (como Haskell, por ejemplo).

    »el carácter en realidad no es necesario, ya que .combse puede usar directamente en la lista, pero esto implica una coerción de cadena implícita (y Perl 6 no tiene cadenas infinitas, por lo que desperdiciaría memoria). Por ejemplo, la 1, 2, 3lista después de la conversión a la cadena devuelve 1 2 3. Para Perl 6, un espacio es un número perfectamente fino que significa 0, por lo que el código funcionaría, incluso con dicha conversión. Sin embargo, abusaría de los recursos informáticos.

  • [+]

    Este es un operador reducido. Básicamente, entre [], puede utilizar un operador, en este caso +. La lista después del operador reduce se reduce, así [+] 1, 2, 3es 1 + 2 + 3, cuál es 6. Perl 6 usa operadores separados para números y cadenas, por lo que no se considerará concatenación.

  • say

    Finalmente, saygenera el resultado. Después de todo, quieres ver el resultado final, ¿no?


Hmmm ... [+] 1,2,3,4,5,6,7,8,9,10es 1+2+3+4+5+6+7+8+9+10, ¿estoy en lo cierto?
ST3

@ ST3: Sí Reducir operador se puede utilizar de muchas maneras interesantes en Perl 6. Por ejemplo, >se puede encadenar, por lo que 3 > 2 > 1es cierto. La misma propiedad se aplica para reducir los operadores, por lo que [>] 3, 2, 1sigue siendo cierto, ya que significa que 3 > 2 > 1- [>]se puede utilizar para determinar si los números están en orden descendente.
Konrad Borowski

¿no podrías usar en get.Intlugar de eval? ¿Necesita expresiones matemáticas?
Ven

@ user1737909: "-50 Bonus si su código puede manejar expresiones simples". Además, Perl 6 no necesita fundición por diseño (aparte de algunos casos extremos raros, como sortsin argumento de método de comparación).
Konrad Borowski

4

Perl 31 - Sin bonificaciones

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

Salida de muestra:

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

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

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

Pruébalo en línea!


3

J, 22

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

Explicación

La evaluación procede de derecha a izquierda.

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

>: n -> n+1

": numbers -> 'numbers'

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

+/ -> sum

Downvoter necesita explicar sus objeciones a esta respuesta. Lo acabo de probar y, aunque no gana ningún bono, funciona bien hasta donde puedo ver.
Gareth

En realidad, después de mirar la respuesta superior, esta también parece ganar las expresiones y los bonos de operador de poder por un puntaje de 22-60 = -38.
Gareth

Esto +/,10#.inv>:i.sería más corto. Pero sigue siendo una función y no un programa completo como OP preguntó.
swish

Los bonos de @Gareth no se aplican a esta respuesta, porque solo escribirías expresiones dentro del código y no como entrada.
swish

1
@swish Eso es lo que pensé al principio, pero la respuesta de Mathematica parece funcionar de esta manera.
Gareth

3

R, 64 - (50 + 10) = 4

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

Cuando esto se ejecuta, se le pide al usuario que ingrese.


Versión anterior (no puede manejar expresiones): 46 caracteres:

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

Se me ocurre que codegolf está muy sesgado hacia los idiomas con funciones de un solo símbolo. Esta solución sería considerablemente más corta si la predefiniéramos, u<-function(x) utf8ToInt(x)etc.
Carl Witthoft

@CarlWitthoft Esto es cierto. Pero la predefinición también cuenta para la cantidad de caracteres. Por cierto: es suficiente tener u <- utf8ToIntsin function. Esto puede ser útil para el golf de código si la función se usa varias veces.
Sven Hohenstein

así que si creo un Rcheatcodegolfpaquete, ¿es legal usar las funciones predefinidas en ese paquete? :-)
Carl Witthoft

@CarlWitthoft Sí, se pueden usar paquetes. Por supuesto, el paquete no debe escribirse para la tarea. Pero si incluye nombres cortos solo para funciones, está bien.
Sven Hohenstein

3

Lote - (181-50) - 131

Solo por un poco de diversión.

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

Lo haré un poco más legible:

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

El método anterior usa el bucle para obtener la salida del comando powershell, en lugar de escribir y leer desde un archivo:

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

Establezca la entrada en una variable - v- usando /apara aceptar expresiones aritméticas.
Desafortunadamente, fue necesario habilitar la expansión demorada.
Use un bucle for para contar desde 1 hasta el valor ingresado - v.
Para manejar números mayores que 9, tuve que usar powershell para obtener la longitud de la cadena y luego usar otro bucle for para dividir esa cadena y agregarla a la suma - s.
Usted podría cambiar el nombre de powershell.exea p.exeen C: \ WINDOWS \ System32 \ WindowsPowerShell \ v1.0 \ luego llamar con sólo p "&{'%%a'.length-1}, el ahorro de 9 bytes. Pero eso no está realmente en el espíritu de eso.

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

Dejé el segundo corriendo mientras tomaba mi almuerzo.

Realmente no puedo probarlo con números que son demasiado grandes debido a lo lento que es. Sin embargo, debería funcionar para números bastante grandes. 2147483647es el número más grande que tomará (máximo de 32 bits enteros) antes de dar el siguiente error:

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

Por supuesto, esto me descalifica del desafío.


1
Buena solución! Hay algunas maneras de jugar golf. 1. Puede deshacerse de la variable temporal vy usarla %1directamente. 2. Puede restar 1 dentro de su script de PowerShell en lugar del largo @set /a b=%%b-1que le ahorra un montón. Con esos cambios, lo reduzco a 211 de los 240 originales. :-)
Marque el

Vaya, ahora veo por qué mantuviste tu variable temporal (para los puntos de bonificación). Sin embargo, la sugerencia de PowerShell sigue en pie ...
Mark

Bien visto, gracias. Cambiará eso ahora.
Unclemeat

Batch no funcionará. Está limitado a (2 ^ 31) -1 (entero de 32 bits con signo). El desafío requiere el manejo de entradas de hasta (2 ^ 64) -1 (entero de 64 bits sin signo, pero la salida para ese valor lo desbordaría). Aquí es donde PowerShell tiene una clara ventaja: su [decimal]tipo permite valores de hasta (2 ^ 96) -1.
Iszi

1
Sin embargo, le daré a Batch un buen crédito por el incumplimiento de la división de enteros. Eso es algo que PowerShell falta por completo.
Iszi

3

Dyalog APL , 9-160 * = -151

+/⍎¨∊⍕¨⍳⎕

Pruébalo en línea!

obtener una entrada evaluada,
 por ejemplo, "7+5"da12

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

⍕¨ formatee cada número en cadena
["1","2","3","4","5","6","7","8","9","10","11","12"]

alistarse (aplanar)
"123456789101112"

⍎¨ Ejecuta cada carácter (produce una lista de números de un solo dígito, números)
[1,2,3,4,5,6,7,8,9,1,0,1,1,1,2]

+/ suma  51


* Puntuación

-50 de bonificación ya que incluso acepta expresiones como entrada. La expresión debe ser APL válida, que es aceptable según OP .

-10 bonus porque porque también maneja el ^( *en APL).

-100 bonus porque la entrada de expresión se maneja sin el uso explícito de eval(es decir, en APL).


¿Estás seguro de que aquí se agrega el bono de -100? Debido a que dice " -100 Bono si su código califica para el bono -50 y no usa eval o similar para manejar expresiones " . Dado que ⍎¨parece ejecutar cada carácter uno por uno, es lo mismo que una evaluación (excepto que ejecuta los caracteres uno por uno en lugar de todos al mismo tiempo como lo evalhace).
Kevin Cruijssen

@KevinCruijssen Sí, ya que no utiliza eval o similar para manejar expresiones. ⍎¨solo se usa para convertir dígitos a enteros, no para manejar expresiones.
Adám

Ah, espera, miré tu explicación incorrectamente. Pero, ¿no es un poco una entrada + evaluación incorporada entonces, o la evaluación siempre se realiza implícitamente cuando se introducen expresiones?
Kevin Cruijssen

1
@KevinCruijssen siempre toma una expresión como entrada, la evalúa y devuelve su resultado. Entonces, para ingresar una cadena, tendría que poner comillas alrededor de ella. El hecho de que un incorporado incorporado ( ) devuelva la entrada como texto sin formato no debería importar (especialmente porque los símbolos indican que es el método de entrada principal y es una variante especial), ya que de lo contrario obtener la bonificación requeriría implementar una matemática evaluador: una tarea completamente diferente a la principal. No me gustan los bonos, y el -100 es simplemente tonto o tenía APL en mente, pero en mi opinión, parece un ajuste exacto para el bono.
Adám

Si de hecho es la forma normal de obtener información y maneja automáticamente las expresiones, de hecho veo que también encaja en el bono, por lo que hago un +1. Los bonos son tontos en estos días de todos modos, pero es una buena forma de utilizarlos para minimizar su puntaje.
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)
            );
    }
}

2

Python3 + Bash (78-185 = -107)

python3 -c"print(sum(sum(map(int,str(x+1)))for x in range(int(${1//^/**}))))"
  • puede manejar todos los números positivos
  • puede manejar expresiones con operación + - / *
  • puede manejar ^ (poder) operador.
  • puede manejar expresiones, sin eval o similar¹

Si el resultado de la expresión no es entero, primero se truncará. Si el resultado de la expresión es negativo, el resultado no está definido.

Úselo como:

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

1: a menos que cuentes invocar Python desde Bash como tal, pero no creo que sea así. Si crees que realmente lo es, entonces la puntuación ajustada es -7.


Yo diría que si no escribiste un evaluador de expresiones, entonces estás usando algo equivalente a eval. Pero no soy el OP, ¡así que buena suerte!
Tobia

De acuerdo con @Tobia, no hay bonificación para el evaluador de expresiones.
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);
    }
}

Maneja expresiones. Dale cualquier expresión que desees en el objetivo. Maneja hasta que la longitud larga pueda manejar. Si limpia quitando todos los espacios en una línea, y no hay ninguna declaración para imprimir, cuenta hasta 254 caracteres (considerando la programación Java basada en palabras largas y largas).

PD: Este es un programa completo, no solo lógico. Las palabras cuentan para el programa, no solo la lógica.


2

Java (JDK8), 272

Mi primer desafío en el que estoy, las sugerencias son bienvenidas =)

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

Sangrado:

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 ya que todos los que desafían el código de golf en Java se lo merecen, pero parece que Stream API no te da ventaja mientras juegas. Apuesto a que si reescribe su solución y usará bucles en lugar de secuencias, será más corta.
user902383

2

CJam, 9-25 = -16

CJam es unos meses más joven que este desafío, por lo que no es elegible para la marca de verificación verde. Además, esto no está ganando a Perl en primer lugar. ;) Me gustó bastante el enfoque, así que quería publicarlo de todos modos.

l~),s:~:+

Pruébalo aquí.

La idea es crear un rango de 0 a N. Este rango se convierte en una cadena, que simplemente concatena los enteros de forma consecutiva. Para N = 12, obtendríamos

"0123456789101112"

Luego, cada carácter se convierte en un entero con :~(lo que produce una matriz de enteros), y luego se resume con :+. CJam puede lidiar con enteros arbitrariamente grandes.


2

Python 3 + astor ,1017 1007 bytes - (25 + 50 + 100) = Puntuación: 842 834

ahorró 10 bytes al eliminar tsy cambiarp

editar: no puedo probar el número entero ridículamente largo (1234567891234567891234564789087414984894900000000) [cuelga mi computadora] pero, que yo sepa, Python 3 admite números enteramente largos.

Esta implementacion usosabusa de AST. No consideraría abusar de AST como "eval o 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()))))))

Demasiado perezoso para escribir sin golf, así que te daré una explicación de las clases:

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.

La última línea solo ejecuta estas clases en el orden apropiado en la entrada, para preservar el orden de las operaciones y evitar comportamientos no deseados.

Ejemplo de uso ($ o> significa entrada del usuario) y, por cierto, el programa real solo ingresa una vez:

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

Esto es asombroso, pero a la vez horrible. No estoy seguro de si está permitido (a sabiendas usar una solución larga), pero 10/10 de mí.
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ ¿Por qué no está permitido usar a sabiendas una solución larga? No veo problema Al menos superaré las soluciones con un puntaje de 842+;)

Se supone que son respuestas competitivas , lo que significa mostrar esfuerzo. Además, BORRE ESE COMENTARIO. SE LÍMITE PARA LA EDAD ES 13! Probablemente debería esperar hasta que esté legalmente permitido. Debido a COPPA (google it), debe tener 13 años para usar Internet de esta manera.
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Ahora tengo curiosidad, ¿quién era ese usuario?
gato

1
@cat ¿Un nombre árabe que no pude pronunciar? Probablemente cuenta nuclear.
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();
}

3
No es una respuesta válida, ya que es función y el recuento de caracteres es
bastante

1
No necesitas el ints; en C, todo lo predeterminado es int... Oh, es C #.
wizzwizz4

1

Rubí -> 83-50 = 33

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

Versión "a prueba":

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 de las pruebas

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

Es mi otro intento.

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

¿Es el espacio en blanco entre n--y +necesario? No creo que esté en otros lenguajes de estilo C.
FireFly

1
¿Funciona esto con el rango dado? El resultado para 2^64-1no cabe en 64 bits.
Marinus

2
No es una respuesta válida, ya que es función y el recuento de caracteres es bastante grande.
ST3

@marinus ¿Puede darnos el resultado para 2 ^ 64-1 para que podamos saber con qué rango necesitamos trabajar? No me atrevo a probarlo en mi idioma (PowerShell) ya que el tiempo de procesamiento sería enorme.
Iszi

@Iszi: No voy a ejecutarlo realmente, pero puedes hacer algunos cálculos: 1) el valor promedio de un dígito es 4.5; 2) la suma promedio de 20 dígitos es 90( 2^64tiene 20 dígitos); entonces el valor esperado estará alrededor 90 * 2^64 ≈ 1.66*10^21. Entonces necesitarías al menos 71bits, como máximo 72.
marinus

1

Rubí 69-50 = 19 (o -4)

Esto definitivamente se puede jugar juntos, pero aquí está el primer quinto intento

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

También funciona para todos los números, pero es muy lento para ellos, ya que funciona más lento que O (n), por lo que no agregaría el -25. Si la lentitud está bien, entonces sería -4 aunque

Rubí 133-50-25 = 58

Esta es la versión más rápida, que se ejecuta en menos de O (n) tiempo (¡y usa las matemáticas reales!), Por lo que puede proporcionar resultados para enteros grandes rápidamente, por lo que agregué el -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]

¡Escribimos exactamente el mismo código (jugaste un poco más)!
Beterraba

@Beterraba sí, y casi al mismo tiempo, pero fuiste un poco más rápido, así que tengo que descubrir algo diferente :)
SztupY

1

Haskell, 74-25 = 49

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


El uso interacty el hecho de que >>=para las listas es lo mismo flip concatMap, puede reducir esto a 63 caracteres como este:main=interact$show.sum.map(\c->read[c]). \x->[0..read x]>>=show
Flonk

Un byte más para guardar: \c->read[c]esread.(:[])
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)

Uno de los personajes menos: for(i=eval(prompt(s=""));i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c).join()).length).
Cepillo de dientes

Un poco más pequeño (que no es necesario el .join()): for(i=eval(prompt(s=""));i;s+=i--)alert(s.replace(/\d/g,c=>Array(-~c)).length). 78-50 = 28 !
Cepillo de dientes

1

R (72 puntos)

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

Salida:

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

En estos desafíos, ¿necesita escribir explícitamente "f = function (n)" o simplemente la función con n?
skan

@skan, depende de los requisitos. Por lo general, no se requiere tener una función explícita.
djhurio
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.