C, 320294 bytes

3

C, 320294 bytes

Compilar con -std = c99

#include<stdio.h>
int s(int i){for(int j=i;j;j/=10)i+=j%10;return i;}int main(){int c=0,i;while(scanf("%d",&i)){c++;if(!i)continue;int j,o[]={1,3,9},p[]={1,3,9};Q:for(j=0;j<3;j++){if(o[j]==i)goto D;else if(o[j]<i){o[j]=s(o[j]);goto Q;}}i=s(i);goto Q;D:printf("Case #%d\n\nfirst meets river %d at %d\n\n",c,p[j],o[j]);}}

Sin golf:

#include <stdio.h>

int s(int i)
{
    for(int j = i; j; j /= 10)
        i += j % 10;
    return i;
}

int main()
{
    int c = 0, i;
    while(scanf("%d", &i))
    {
        c++;
        if(!i)
            continue;
        int j,o[]={1,3,9},p[]={1,3,9};
        Q: for(j = 0; j < 3; j++)
        {
            if(o[j] == i)
                goto D;
            else if(o[j] < i)
            {
                o[j] = s(o[j]);
                goto Q;
            }
        }
        i = s(i);
        goto Q;
        D: printf("Case #%d\n\nfirst meets river %d at %d\n\n", c, p[j], o[j]);
    }
}

¡Pruébalo!

Esencialmente, los ríos "objetivo" se incrementan hasta que son mayores que el río contra el que estamos probando, y luego se aumenta el río de prueba. Esto se repite hasta que el río de prueba sea igual a otro río.

No estoy leyendo parámetros desde la línea de comandos en este programa, y ​​no estoy seguro de si se supone que debes hacerlo. Ahora puede pasar parámetros a STDIN. Puede terminar pasando una entrada no numérica.

También maldita sea, golpeado por media hora.


fuente
Estoy trabajando en casos de prueba por ahora. Solo 3 casos de prueba de entrada no serán muy adecuados.
Kishan Kumar
por favor, ¿le importaría recibir información de stdin?
Kishan Kumar

Respuestas:

3

JavaScript (ES6)

Esta es una respuesta bastante rápida usando un lenguaje bastante lento. Realmente, el tiempo de ejecución no debería ser un problema al usar cualquier lenguaje con tablas hash. Todas mis pruebas de menos de 100 ms.

Método anónimo con la lista de casos de prueba como parámetro de entrada.

F=cases=>{
  var t0 = +new Date
  var result = 0
  var spots = []
  var top=[,1,3,,9]
  var rivers=[,1,3,1,9,1,3,1]
  cases.forEach((n,i)=>{
    var found = result = spots[n]
    for (;!found;)
    {
      found = top.some((v,i)=>{
        for(;spots[v] |= i, v<n; top[i] = v)
          [...v+''].forEach(d=>v-=-d)
        return result = v-n ? 0 : i;
      }) || (
        [...n+''].forEach(d=>n-=-d),
        result = spots[n]
      )
    }  
    console.log(`Case #${i+1}\nfirst meets river ${rivers[result]} at ${n}`)
  })  
  return 'Time (ms) ' + (new Date-t0)
}  

console.log(F([86, 12345, 123, 456, 789, 16384]))

edc65
fuente
1

Java 7, 519 505 bytes

import java.util.*;String c(int i){if(i<=0)return"";ArrayList<Long>r=f(1),s=f(3),t=f(9),x=f(i);String z="first meets river ";for(int j=0;j<r.size();j++){long u=r.get(j),v=s.get(j),w=t.get(j);if(x.contains(u))return z+1+" at "+u;if(x.contains(v))return z+3+" at "+v;if(x.contains(w))return z+9+" at "+w;}return"";}ArrayList f(long i){ArrayList<Long>l=new ArrayList();l.add(i);for(long j=0,x;j<9e4;j++){x=l.get(l.size()-1);for(char c:(x+"").toCharArray())x+=new Long(c+"");l.add(x);if(x>16383)return l;}return l;}

Sí, es largo, feo y, sin duda, puede cambiarse por completo para codificarlo más ... Estoy distraído y cansado, así que tal vez debería eliminarlo nuevamente ...
Fue un desafío bastante difícil para ser honesto. Pero al menos tienes tu primera respuesta ...;) (que podría ser incluso más larga que tu programa original de C ++ sin golf ... xD)

Sin golf y casos de prueba:

Pruébalo aquí.

import java.util.*;
class M{
  static String c(int i){
    if(i <= 0){
      return "";
    }
    ArrayList<Long> r = f(1),
                    s = f(3),
                    t = f(9),
                    x = f(i);
    String z = "first meets river ",
           y = " at ";
    for(int j = 0; j < r.size(); j++){
      long u = r.get(j),
           v = s.get(j),
           w = t.get(j);
      if(x.contains(u)){
        return z+1+y+u;
      }
      if(x.contains(v)){
        return z+3+y+v;
      }
      if(x.contains(w)){
        return z+9+y+w;
      }
    }
    return "";
  }

  static ArrayList f(long i){
    ArrayList<Long> l = new ArrayList();
    l.add(i);
    for(long j = 0, x; j < 9e4; j++){
      x = l.get(l.size() - 1);
      for(char c : (x + "").toCharArray()){
        x += new Long(c+"");
      }
      l.add(x);
      if(x > 16383){
        return l;
      }
    }
    return l;
  }

  public static void main(String[] a){
    System.out.println(c(86));
    System.out.println(c(12345));
    System.out.println(c(0));
  }
}

Salida:

first meets river 1 at 101
first meets river 3 at 12423
(empty output)
Kevin Cruijssen
fuente
Compararé tu programa con el mío. También voy a publicar mi solución también. Por qué usar un lenguaje lento. Usa cualquier lenguaje rápido.
Kishan Kumar
Solo noté la etiqueta de algoritmo más rápido más adelante ... Siempre publico respuestas de código de golf Java 7 aquí ... Definitivamente no va a ganar ni en el más corto ni en el más rápido ... Por cierto, su rextester da errores cuando solo debería dar advertencias por falta de conversiones / inicializaciones de tipo. Funciona en ideone (y en Eclipse IDE).
Kevin Cruijssen
Okay. Déjame ver. rextester da tiempo de compilación y tiempo de ejecución. Así que lo usé
Kishan Kumar
Bueno, eso es un problema aquí. Buscaré otro compilador en línea que ofrezca el tiempo de compilación y el tiempo de ejecución
Kishan Kumar
@KishanKumar He agregado los moldes en mi código, lo que no debería afectar el tiempo afaik Aquí está el código rextester que funciona con el resultado: Compilation time: 0.62 sec, absolute running time: 0.14 sec, cpu time: 0.11 sec, memory peak: 22 Mb, absolute service time: 0,77 secpara mí localmente. Así que sí, es bastante lento ...
Kevin Cruijssen
1

Scala, 774 bytes

Violín: http://scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b

No tengo ganas de jugar al golf. Encuentra una solución al problema planteado dentro de los 50 ms

El uso puede no ser exactamente lo que quieres:

scala river.scala

Ahora puede ingresar continuamente números seguidos de una entrada. Y finalice el programa con 0. El resultado se imprimirá tan pronto como presione enter.

io.Source.stdin.getLines.map(_.toInt)
  .takeWhile(_ != 0)
  .map(stream(_).takeWhile(_ < 16383))
  .zipWithIndex
  .map { cur =>
    Seq(1, 3, 9).map { i =>
      val s = stream(i).takeWhile(_ < 16383)
      (cur._2+1, i, s.intersect(cur._1).headOption)
    }
  }.foreach { opts =>
    val options = opts.filterNot(_._3.isEmpty)

    if(options.isEmpty) {
      println("No result")
    } else {
      val opt = options(0)
      println(s"Case #${opt._1}\n\nfirst meets ${opt._2} at ${opt._3.get}\n\n")
    }
  }

def stream(i:Int): Stream[Int] = {
  def sub: Int => Stream[Int] = {
    i => i #:: sub(a(i))
  }
  sub(i)
}

def a(i:Int): Int = i + i.toString.map{_.asDigit}.sum
AmazingDreams
fuente
No sé mucho sobre Scala. Entonces, ¿podría modificar el código, que según rextester.com/l/scala_online_compiler?
Kishan Kumar
Traté de ponerlo allí, pero se agotó el tiempo mientras compilaba.
AmazingDreams
ok @AmazingDreams
Kishan Kumar
@KishanKumar, incluso el valor predeterminado una vez, por lo que el sitio parece estar roto para scala
AmazingDreams
@KisthanKumar Use este scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b aunque no admite stdin, así que tuve que cambiar algunas cosas menores.
AmazingDreams
1

C, 228283 300 bytes

Este es un mod del código de Yakov para aprovechar los patrones del río. Esto lo hace ~ 3 veces más rápido. Además, los enteros sin signo evitan la cltodpenalización en máquinas de 64 bits, por lo que son unos pocos bytes más largos pero fraccionalmente más rápidos.

#define sum(z) for(y=z;y;y/=10)z+=y%10;
n,x;main(){unsigned i,j,y;while(scanf("%d",&i)){if(i){j=x=1+!(i%3)*2+!(i%9)*6;do{while(j<i)sum(j)}while(j^i&&({sum(i)i;}));printf("Case #%u\n\nfirst meets river %u at %u\n\n",++n,x,i);}}}

Sin golf:

#define sum(z) for(y=z;y;y/=10)z+=y%10;
n, x;
main() {
    unsigned i, j, y;
    while(scanf("%d", &i)) {
        if(i){
            j = x = 1 + !(i%3)*2 + !(i%9)*6;
            do{
                while (j < i) sum(j)
            }
            while(j^i&&({sum(i)i;}));
            printf("Case #%u\n\nfirst meets river %u at %u\n\n", ++n, x, i);
        }
    }
}

Explicación:

j = x = 1 + !(i%3)*2 + !(i%9)*6;

Esto selecciona el río correcto. El río 1 se encuentra con cualquier otro río, por lo que usamos esto como el caso alternativo. Si 3 es el máximo divisor común del río de prueba, seleccionamos el río 3 ( 1 + !(i%3)*2). Si 9 es el máximo divisor común del río de prueba, anulamos los valores anteriores y seleccionamos el río 9.

¿Por qué funciona esto? El río 9 va 9, 18, 27, 36, etc. Este paso por un múltiplo de 9 cada vez, por lo que siempre será la ruta más corta a un río hermano. El río 3 pasará por un múltiplo de 3 cada vez: 3, 6, 12, 15, 21, etc. Si bien los ríos que son múltiplos de 9 también son múltiplos de 3, los elegimos primero como río 9, dejando solo el múltiplos de 3. El resto se encontrará primero con el río 1: 1, 2, 4, 8, 16, 23, 28, etc.

Una vez que hemos seleccionado nuestro río correcto, pisamos los dos ríos hasta que se encuentran.

Seth
fuente
1

Python 3, 144 bytes

r,a,b,c,i={int(input())},{1},{3},{9},1
while i:
  for x in r,a,b,c:t=max(x);x|={sum(int(c)for c in str(t))+t}
  if r&(a|b|c):i=print(*r&(a|b|c))
Trelzevir
fuente
0

C

Muy simple, parece tan largo porque desenrollé los 3 ríos. Primero genera los 3 ríos hasta RIVER_LENGTH(que espero que sea lo suficientemente grande), y luego, para cada paso N, realiza una búsqueda binaria en los tres flujos para ver si está en alguno de ellos. Esto funciona porque las transmisiones ya están ordenadas, por lo que podemos hacer la verificación de contenido a log(n)tiempo.

#include <stdio.h>

#define RIVER_LENGTH 10000

int main() {
    int num_cases;
    scanf("%d", &num_cases);
    int cases[num_cases];
    int N;
    int s1[RIVER_LENGTH] = {1};
    int s3[RIVER_LENGTH] = {3};
    int s9[RIVER_LENGTH] = {9};
    int i;
    int temp;

    for (i = 1; i < RIVER_LENGTH; i++) {
        s1[i] = temp = s1[i-1];
        while (temp) {
            s1[i] += temp % 10;
            temp /= 10;
        }
    }

    for (i = 1; i < RIVER_LENGTH; i++) {
        s3[i] = temp = s3[i-1];
        while (temp) {
            s3[i] += temp % 10;
            temp /= 10;
        }
    }

    for (i = 1; i < RIVER_LENGTH; i++) {
        s9[i] = temp = s9[i-1];
        while (temp) {
            s9[i] += temp % 10;
            temp /= 10;
        }
    }

    int start;
    int end;
    int pivot;

    for (i=1; i <= num_cases; i++) {
        scanf("%d", &cases[i]);
    }

    for (i=1; i <= num_cases; i++) {
        printf("Case #%d\n\n", i);
        N = cases[i];

        while (1) {

            temp = N;
            while (temp) {
                N += temp % 10;
                temp /= 10;
            }

            start = 0;
            end = RIVER_LENGTH;
            pivot = 1;

            while (end != start && pivot != RIVER_LENGTH - 1) {
                pivot = start + ((end - start) >> 1);
                if (s1[pivot] == N) {
                    printf("first meets river 1 at %d\n\n", N);
                    goto case_done;
                } else if (N < s1[pivot]){
                    end = pivot;
                } else {
                    start = pivot+1;
                }
            }

            start = 0;
            end = RIVER_LENGTH;
            pivot = 1;

            while (end != start && pivot != RIVER_LENGTH - 1) {
                pivot = start + ((end - start) >> 1);
                if (s3[pivot] == N) {
                    printf("first meets river 3 at %d\n\n", N);
                    goto case_done;
                } else if (N < s3[pivot]){
                    end = pivot;
                } else {
                    start = pivot+1;
                }
            }

            start = 0;
            end = RIVER_LENGTH;
            pivot = 1;

            while (end != start && pivot != RIVER_LENGTH - 1) {
                pivot = start + ((end - start) >> 1);
                if (s9[pivot] == N) {
                    printf("first meets river 9 at %d\n\n", N);
                    goto case_done;
                } else if (N < s9[pivot]){
                    end = pivot;
                } else {
                    start = pivot+1;
                }
            }
        }

        case_done:;

    }
}

Primero se necesita un número para el número de casos, en lugar de usar 0para delimitar el final de las entradas, porque ya sabes, C. Esto es solo por conveniencia y realmente no afecta nada, así que espero que esté bien.

Maltysen
fuente
Este programa alcanza un límite de tiempo excedido en ideone en las entradas 86,12345,0
Kishan Kumar
ideone.com/mHCeef aquí está el enlace. Y da una salida de señal de muerte en rextester
Kishan Kumar
@KishanKumar Se necesita un número para el número de casos primero, en lugar de usar 0 para delimitar el final de las entradas, porque sabes, C. Esto es solo por conveniencia y realmente no afecta nada, así que espero que esté bien.
Maltysen
@KishanKumar prueba este en su lugar: rextester.com/XRJK89444
Maltysen
está bien. No hay problema. Pero tendré que escribir un script adicional para su programa. Como tengo que tomar el tiempo promedio de todo el rango de entrada.
Kishan Kumar