C, 320 294 byte

3

C, 320 294 byte

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

Tidak Disatukan:

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

Cobalah!

Pada dasarnya, sungai "target" meningkat hingga lebih besar dari sungai yang kami uji melawan, dan setelah itu sungai uji ditingkatkan. Ini diulangi sampai sungai uji sama dengan beberapa sungai lain.

Saya tidak membaca parameter dari baris perintah di program ini, dan saya tidak yakin apakah Anda seharusnya. Sekarang Anda dapat meneruskan parameter ke STDIN. Anda dapat mengakhiri dengan mengirimkan input non-numerik.

Sial, dipukuli setengah jam.


sumber
Saya sedang mengerjakan kasus uji untuk saat ini. Hanya 3 input test case yang tidak cocok.
Kishan Kumar
maukah Anda mengambil input dari stdin.
Kishan Kumar

Jawaban:

3

JavaScript (ES6)

Ini adalah jawaban yang cukup cepat menggunakan bahasa yang cukup lambat. Sungguh, waktu eksekusi seharusnya tidak menjadi masalah menggunakan bahasa apa pun dengan tabel hash. Semua pengujian saya di bawah 100 ms.

Metode anonim dengan daftar kasus uji sebagai parameter input.

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
sumber
1

Java 7, 519 505 byte

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

Ya, ini panjang, jelek, dan tanpa diragukan lagi dapat sepenuhnya diubah menjadi kode-golf lebih. Saya berdua terganggu dan lelah, jadi mungkin saya harus menghapusnya lagi ..
Itu adalah tantangan yang cukup sulit untuk jujur. Tapi setidaknya Anda memiliki jawaban pertama Anda ..;) (Yang mungkin bahkan lebih lama dari program C ++ asli yang tidak di-ungolfed Anda .. xD)

Kasus yang tidak disatukan & uji:

Coba di sini.

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

Keluaran:

first meets river 1 at 101
first meets river 3 at 12423
(empty output)
Kevin Cruijssen
sumber
Saya akan membandingkan program Anda dengan program saya. Saya juga akan memposting solusi saya juga. Mengapa menggunakan bahasa yang lambat. Gunakan bahasa cepat apa pun.
Kishan Kumar
Saya hanya memperhatikan tag algoritme tercepat di kemudian hari. Saya selalu memposting jawaban kode-Java 7 di sini .. Pasti tidak akan menang dalam waktu tersingkat atau tercepat sekalipun. Btw, rextester Anda memberikan kesalahan padahal seharusnya hanya memberikan peringatan karena kekurangan gips / ketik-menginisialisasi .. Ini berfungsi pada ideone (dan di Eclipse IDE).
Kevin Cruijssen
baik. izinkan aku melihat. rextester memberikan waktu kompilasi dan waktu eksekusi. Jadi saya menggunakannya
Kishan Kumar
nah itu masalah di sini. Saya akan mencari kompiler online lainnya yang memberikan waktu kompilasi dan waktu eksekusi
Kishan Kumar
@KishanKumar Saya telah menambahkan gips dalam kode saya, yang seharusnya tidak mempengaruhi waktu afaik Berikut adalah kode rextester yang berfungsi dengan hasilnya: 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 secuntuk saya secara lokal. Jadi ya, ini sangat lambat ..
Kevin Cruijssen
1

Scala, 774 byte

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

Saya tidak ingin bermain golf. Itu menemukan solusi untuk masalah yang diajukan dalam 50ms

Penggunaan mungkin tidak persis seperti yang Anda inginkan:

scala river.scala

Sekarang Anda dapat secara terus-menerus memasukkan angka yang diikuti oleh sebuah entri. Dan hentikan program dengan 0. Hasilnya akan dicetak segera setelah Anda menekan 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
sumber
Saya tidak tahu banyak tentang Scala. Jadi tolong Anda dapat memodifikasi kode yang sesuai dengan rextester.com/l/scala_online_compiler
Kishan Kumar
Saya mencoba untuk meletakkannya di sana tetapi waktunya habis saat mengkompilasi.
AmazingDreams
ok @AmazingDreams
Kishan Kumar
@KishanKumar bahkan default satu kali keluar sehingga situs tersebut tampaknya rusak untuk scala
AmazingDreams
@KisthanKumar Gunakan ini scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b tidak mendukung stdin, jadi saya harus mengubah beberapa hal kecil.
AmazingDreams
1

C, 228 283 300 byte

Ini adalah mod dari kode Yakov untuk mengambil keuntungan dari pola sungai. Ini membuatnya ~ 3x lebih cepat. Juga, bilangan bulat yang tidak ditandatangani menghindari cltodpenalti pada mesin 64-bit, jadi itu beberapa byte lebih lama tetapi lebih cepat.

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

Tidak Disatukan:

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

Penjelasan:

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

Ini memilih sungai yang benar. Sungai 1 bertemu setiap sungai lainnya, jadi kami menggunakan ini sebagai kasing mundur. Jika 3 adalah pembagi umum terbesar dari sungai uji, kami memilih sungai 3 ( 1 + !(i%3)*2). Jika 9 adalah pembagi umum terbesar dari sungai uji, kami menimpa nilai sebelumnya dan memilih sungai 9.

Mengapa ini bekerja? Sungai 9 pergi 9, 18, 27, 36, dll. Ini langkah dengan kelipatan 9 setiap kali sehingga akan selalu menjadi rute terpendek ke sungai saudara. Sungai 3 akan melangkah dengan kelipatan 3 setiap kali: 3, 6, 12, 15, 21, dll. Sementara sungai yang kelipatan 9 juga kelipatan 3, kami memilihnya sebagai sungai 9 terlebih dahulu, hanya menyisakan kelipatan 3. Sisanya akan bertemu sungai 1 pertama: 1, 2, 4, 8, 16, 23, 28, dll.

Setelah kami memilih sungai yang benar, kami melangkah dua sungai sampai mereka bertemu.

Seth
sumber
1

Python 3, 144 byte

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
sumber
0

C

Sangat sederhana, itu hanya terlihat lama karena saya membuka gulungan semua 3 sungai. Pertama-tama menghasilkan 3 sungai hingga RIVER_LENGTH(yang saya harap cukup besar), dan kemudian untuk setiap langkah di Natasnya melakukan pencarian biner pada ketiga aliran untuk melihat apakah ada di salah satu dari mereka. Ini berfungsi karena stream sudah diurutkan, sehingga kita dapat melakukan check-in berisi log(n)waktu.

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

    }
}

Dibutuhkan nomor untuk jumlah kasus terlebih dahulu, daripada menggunakan 0untuk membatasi akhir input, karena Anda tahu, C. Ini hanya untuk kenyamanan dan tidak benar-benar mempengaruhi apa pun, jadi saya harap tidak apa-apa.

Maltysen
sumber
Program ini mencapai batas waktu terlampaui pada ideone pada input 86.12345,0
Kishan Kumar
ideone.com/mHCeef di sini adalah tautannya. Dan itu memberikan output sinyal mematikan pada rextester
Kishan Kumar
@KishanKumar Dibutuhkan nomor untuk jumlah kasus terlebih dahulu, daripada menggunakan 0 untuk membatasi akhir input, karena Anda tahu, C. Ini hanya untuk kenyamanan dan tidak benar-benar mempengaruhi apa pun, jadi saya harap tidak apa-apa.
Maltysen
@KishanKumar coba yang ini sebagai gantinya: rextester.com/XRJK89444
Maltysen
tidak apa-apa. Tidak masalah. Tetapi saya harus menulis skrip tambahan untuk program Anda. Karena saya harus mengambil waktu rata-rata dari semua rentang input.
Kishan Kumar