Retos - 001: Una suma difícil

Nivel de dificultad aproximado (1 a 5): 2  

Crea un programa capaz de calcular la suma de los números que se indicarán en la entrada estándar, separados por espacios, y mostrar los resultados en pantalla. Los números pueden ser negativos, grandes y las líneas pueden contener espacios adicionales, por lo que el programa debe ser robusto.

(Cuidado: no debe ser "amigable", sino estricto: no debe decir nada como "introduce los datos" ni responder con nada como "la suma es..."; debe tomar cada línea de datos de la entrada estándar, analizarla y mostrar los resultados en la salida estándar).

Ejemplo de entrada
123456789012 1
2 3
4   5 -1

Ejemplo de salida
123456789013
5
8

La principal dificultad de este ejercicio es que no se sabe cuántos números se van a introducir en cada línea, ni cuantas líneas, ni cuantos espacios habrá entre los números, ni cómo de grandes serán los números.

Se debe leer líneas hasta encontrar una vacía (según el lenguaje, puede ser "", null, tener longitud vacía...)

Para cada línea, la forma de analizarla depende del lenguaje: en lenguaje modernos como C# se puede usar "Split" para convertirla a un array de cadenas; en C se puede usar "strtok" para obtener cada fragmento y analizarlo; en Pascal y lenguajes más antiguos se deberá hacer todo de forma artesanal, recorriendo letra a letra para esquivar espacios y reconstruir números.

Como los números pueden ser muy grandes, lo razonable es usar como mínimo datos "long", no bastará con un un "int"

Aportar una solución

Tu nombre (si quieres que aparezca):
Tu web/blog (si quieres que incluyamos un enlace a ella):
Tu e-mail (no se mostrará; si quieres que te avisemos cuando esté publicado):
¿Eres humano? ¿Cuánto es 2 más 3?
Lenguaje
Fuente:

/*      Reto 001
        Antonio Fernández, 27-Jun-2015
        Suma los números introducidos en la entrada estándar y separados por
        espacios.
        Compilación comprobada con
        gcc 4.8:
                gcc reto001.c -o reto001
        clang 3.4:
                clang reto001.c -o reto001
        */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define TAMANO 1000     //Cantidad de caracteres en la entrada de datos
                                        // A tener en cuenta el carácter nulo, con lo que sólo
                                        // admitirá 999 caracteres.
                                        // Modificable a voluntad
 
int main (void)
{
    char cadena[TAMANO];
    char* posicion;
    long long int suma;
 
    // Introducimos la línea
    fgets (cadena, TAMANO, stdin);
 
    while (strlen(cadena) > 1)
    {
 
        suma = 0;
 
        // la función strtok() corta la cadena hasta la primera coincidencia
        // de alguno de los caracteres entrecomillados y devuelve la subcadena
        // obtenida, modificando a su vez la cadena original.
        posicion = strtok (cadena, " \t");
        while (posicion != NULL){
                // atoll() devuelve el valor numérico de la cadena como long long.
                suma +=  atoll(posicion);
                posicion = strtok (NULL, " \t");
        }
 
        printf ("%lld\n", suma);
        // Con MingGW para Windows sería: printf ("%l64d\n", suma);
 
        // Introducimos la línea nuevamente
        fgets (cadena, TAMANO, stdin);
    }   
    return 0;
}
 

// Ejemplo de solución para el reto 001
// (Ejercicio 1 de concurso Tuenti 2011)
// Por Nacho Cabanes (www.nachocabanes.com), 24-04-2012
 
// Recibe (de entrada estándar) líneas de números separadas por espacios
// Escribe en salida estándar la suma de los números de cada línea
 
// Da por sentado que los números son de 20 cifras o menos (Int64)
// Si fueran mayores, habría que usar datos "decimal" o incluso
//   sumar los números como cadenas de texto
 
using System;
 
public class Reto001
{
 
    public static void Main(string[] args)
    {
        string texto = Console.ReadLine();
        while ((texto != null) && (texto.Length > 0))
        {
            texto = texto.Trim();  // Quito espacios iniciales
            while (texto.IndexOf("  ") >= 0)  // Y espacios dobles
            {
                texto = texto.Replace("  ", " ");
            }
 
            // Descompongo en un array
            string[] numeros = texto.Split(new char[] {' '});
 
            // Y recorro el array sumando sus elementos
            long suma = 0;
            foreach (string numero in numeros)
                suma += Convert.ToInt64(numero);
 
            // Escribo la suma
            Console.WriteLine(suma);
 
            // Finalmente, leo la siguiente línea, si existe
            texto = Console.ReadLine(); 
        }
    }
}
 

<?php
 
// Ejemplo de solución para el reto 001
// (Ejercicio 1 de concurso Tuenti 2011)
// Por rubenppg
// Nota: se incluye como ejemplo de aproximación al problema desde PHP
// pero no es una solución totalmente válida al ser interactiva (usa un formulario)
// y mostrar datos adicionales en la salida
 
function formulario()
{
    //Formulario
    echo "<form name='frm' method='post' 
    action='".$_SERVER["SCRIPT_NAME"]."'>
    <textarea name='numeros' rows='10' cols='40' /></textarea>
    <br /><input type='submit' name='enviar' value='Enviar' /></form>";
}
 
function procesa()
{
    $contenido=$_POST["numeros"];
 
    $a_total=array();
 
    $a_cont = explode("\n",$contenido);
 
    for($i=0;$i<count($a_cont);$i++)
    {
        $a_numeros=explode(" ",$a_cont[$i]);
        $n=count($a_numeros);
        $total=0;
        for($j=0;$j<$n;$j++)
        {
            $total+=$a_numeros[$j];
            $todos=$j+1;
            if($todos==$n)
            {
                $a_total[]=$total;
            }
        }
    }
 
    //Resultado
    $html="Ejemplo de Salida: <br />";
    for($i=0;$i<count($a_total);$i++)
    {
        $html.=$a_total[$i]."<br />";
    }
    echo $html;
 
}
 
$haydatos=count($_POST);
if(!$haydatos)
    formulario();
else
    procesa();
?>

<!--
// Ejemplo de solución para el reto 001
// Por Israel Terán Zavala
// 02-May-2o15
// Nota: se incluye como ejemplo de aproximación al problema desde PHP
// pero no es una solución totalmente válida al ser interactiva (usa un formulario)
// y mostrar datos adicionales en la salida
-->
 
<html>
<body>
        <form name="formQuestion" method="POST">
                <input type="text" id="numbers" name="numbers"/><br><br>
                <input type="hidden" id="btn1" name="btn1" />
                <input type="submit" id="button1" name="button1" value="See result" onclick="getNumbers();" />
        </form>
</body>
</html>
<?
if($_POST['button1']){
        $variable=explode("/",$_POST['btn1']);
        $res=0;
        for($i=0;$i<count($variable);$i++){
                $res+=$variable[$i];
        }
        echo "The correct sum is: ".$res;
}
?>
<script>
function getNumbers(){
        document.getElementById("btn1").value=document.getElementById("numbers").value.replace(/ /g,"/");
}
</script>