C, 320 294 bajtów

3

C, 320 294 bajtów

Skompiluj z -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]);}}

Nie golfowany:

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

Wypróbuj to!

Zasadniczo rzeki „docelowe” są zwiększane, dopóki nie będą większe niż rzeka, na której testujemy, a następnie rzeka testowa jest zwiększana. Jest to powtarzane, aż rzeka testowa będzie równa jakiejś innej rzece.

Nie czytam parametrów z wiersza poleceń w tym programie i nie jestem pewien, czy powinieneś. Teraz możesz przekazać parametry do STDIN. Możesz zakończyć, przekazując dane nienumeryczne.

Również cholernie pobity przez pół godziny.


źródło
Na razie pracuję nad testami. Tylko 3 wejściowe przypadki testowe nie będą odpowiednie.
Kishan Kumar
czy mógłbyś wziąć wkład ze standardowego wejścia?
Kishan Kumar

Odpowiedzi:

3

JavaScript (ES6)

To dość szybka odpowiedź przy użyciu dość wolnego języka. Naprawdę, wykonanie czasu nie powinno stanowić problemu przy użyciu dowolnego języka z tabelami skrótów. Wszystkie moje testy poniżej 100 ms.

Metoda anonimowa z listą przypadku testowego jako parametrem wejściowym.

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
źródło
1

Java 7, 519 505 bajtów

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

Tak, jest długi, brzydki i bez wątpienia można go całkowicie zmienić na golfa kodowego. Jestem rozkojarzony i zmęczony, więc może powinienem go po prostu usunąć
. Szczerze mówiąc, było to dość trudne wyzwanie. , Ale przynajmniej masz swoją pierwszą odpowiedź ...;) (która może być nawet dłuższa niż twój oryginalny nieoznakowany program w C ++ .. xD)

Przypadki bez golfa i testy:

Wypróbuj tutaj.

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

Wynik:

first meets river 1 at 101
first meets river 3 at 12423
(empty output)
Kevin Cruijssen
źródło
Porównuję twój program z moim. Zamierzam również opublikować moje rozwiązanie. Dlaczego warto używać wolnego języka? Użyj dowolnego szybkiego języka.
Kishan Kumar
Zauważyłem tylko znacznik najszybszego algorytmu później. Zawsze zamieszczam tutaj odpowiedzi na golfa w Javie 7. Z pewnością nie wygra on ani w najkrótszym, ani najszybszym czasie. Tak przy okazji, twój rextester podaje błędy, gdy powinien podawać tylko ostrzeżenia z powodu braku rzutów / inicjalizacji typu. Działa na ideone (i w Eclipse IDE).
Kevin Cruijssen
ok. daj mi zobaczyć. rextester podaje czas kompilacji i czas wykonania. Więc użyłem go
Kishan Kumar
to jest problem tutaj. Poszukam innego kompilatora online, który podaje czas kompilacji i czas wykonania
Kishan Kumar
@KishanKumar Dodałem castingi do mojego kodu, co nie powinno wpływać na czas afaik Oto działający kod rextester z wynikiem: 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 secdla mnie lokalnie. Więc tak, to dość powolne ..
Kevin Cruijssen
1

Scala, 774 bajty

Fiddle: http://scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b

Nie mam ochoty na golfa. Znajduje rozwiązanie postawionego problemu w ciągu 50 ms

Użycie może nie być dokładnie takie, jak chcesz:

scala river.scala

Teraz możesz w sposób ciągły wprowadzać liczby, a następnie Enter. I zakończ program za pomocą 0. Wynik zostanie wydrukowany, jak tylko naciśniesz 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
źródło
Nie wiem wiele o Scali. Czy mógłbyś więc zmodyfikować kod, który będzie zgodny z rextester.com/l/scala_online_compiler
Kishan Kumar
Próbowałem go tam umieścić, ale upłynął limit czasu podczas kompilacji.
AmazingDreams,
ok @AmazingDreams
Kishan Kumar
@KishanKumar nawet domyślny raz, więc strona wydaje się być zepsuta dla Scala
AmazingDreams
@KisthanKumar Użyj tego scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b , ale nie obsługuje standardowego wejścia, więc musiałem zmienić kilka drobnych rzeczy.
AmazingDreams,
1

C 228 283 300 bajtów

Jest to modyfikacja kodu Jakowa, aby wykorzystać wzorce rzeczne. To sprawia, że ​​~ 3x szybciej. Ponadto liczby całkowite bez znaku unikają cltodkary na komputerach 64-bitowych, więc jest kilka bajtów dłuższych, ale ułamkowo szybszych.

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

Nie golfowany:

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

Wyjaśnienie:

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

To wybiera właściwą rzekę. Rzeka 1 spotyka się z każdą inną rzeką, dlatego używamy tego jako przypadku rezerwowego. Jeśli 3 jest największym wspólnym dzielnikiem testowej rzeki, wybieramy rzekę 3 (1 + !(i%3)*2 ). Jeśli 9 jest największym wspólnym dzielnikiem rzeki testowej, zastępujemy poprzednie wartości i wybieramy rzekę 9.

Dlaczego to działa? Rzeka 9 płynie 9, 18, 27, 36 itd. Za każdym razem jest to wielokrotność 9, więc zawsze będzie to najkrótsza droga do siostrzanej rzeki. Rzeka 3 pokona wielokrotność 3 za każdym razem: 3, 6, 12, 15, 21 itd. Podczas gdy rzeki, które są wielokrotnością 9, są również wielokrotnością 3, najpierw wybieramy je jako rzekę 9, pozostawiając tylko wielokrotności 3. Pozostała część spotka się najpierw z rzeką 1: 1, 2, 4, 8, 16, 23, 28 itd.

Po wybraniu właściwej rzeki przeprawiamy się przez obie rzeki, aż się spotkają.

Seth
źródło
1

Python 3, 144 bajty

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
źródło
0

do

Bardzo proste, wygląda tak długo, ponieważ rozwinąłem wszystkie 3 rzeki. Najpierw generuje 3 rzeki RIVER_LENGTH( do których mam nadzieję, że jest wystarczająco duży), a następnie dla każdego kroku Ndokonuje binarnego przeszukiwania wszystkich trzech strumieni, aby sprawdzić, czy jest w którymkolwiek z nich. Działa to, ponieważ strumienie są już posortowane, dzięki czemu możemy wykonać sprawdzenie w log(n)czasie.

#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:;

    }
}

Najpierw potrzeba liczby dla liczby przypadków, zamiast 0ograniczania końca danych wejściowych, ponieważ wiesz, że C. Jest to tylko dla wygody i tak naprawdę nie wpływa na nic, więc mam nadzieję, że jest w porządku.

Maltysen
źródło
Ten program osiąga limit czasu przekroczony dla ideonu na wejściach 86, 12345,0
Kishan Kumar,
ideone.com/mHCeef tutaj jest link. I daje sygnał zabicia na rextesterze
Kishan Kumar
@KishanKumar Najpierw potrzeba liczby dla liczby przypadków, zamiast 0 do ograniczenia końca danych wejściowych, ponieważ wiesz, że C. Jest to tylko dla wygody i tak naprawdę nie wpływa na nic, więc mam nadzieję, że jest w porządku.
Maltysen
@KishanKumar wypróbuj zamiast tego: rextester.com/XRJK89444
Maltysen
w porządku. Nie ma problemu. Ale będę musiał napisać dodatkowy skrypt dla twojego programu. Ponieważ muszę wziąć średni czas z całego zakresu wejściowego.
Kishan Kumar