C, 320 294 octets

3

C, 320 294 octets

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

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

Essaye le!

Essentiellement, les rivières "cibles" sont augmentées jusqu'à ce qu'elles soient plus grandes que la rivière contre laquelle nous testons, puis la rivière test est augmentée. Cette opération est répétée jusqu'à ce que la rivière test soit égale à une autre rivière.

Je ne lis pas les paramètres de la ligne de commande de ce programme et je ne sais pas si vous êtes censé le faire. Vous pouvez maintenant passer des paramètres à STDIN. Vous pouvez terminer en passant une entrée non numérique.

Bon sang, battu d'une demi-heure.


la source
Je travaille sur des cas de test pour l'instant. Seuls 3 cas de test d'entrée ne conviennent pas.
Kishan Kumar
veuillez vous occuper de la saisie de stdin.
Kishan Kumar

Réponses:

3

JavaScript (ES6)

Ceci est une réponse assez rapide en utilisant un langage assez lent. Vraiment, l'exécution du temps ne devrait pas être un problème en utilisant n'importe quelle langue avec des tables de hachage. Tous mes tests sous 100 ms.

Méthode anonyme avec la liste des cas de test comme paramètre d'entrée.

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
la source
1

Java 7, 519 505 octets

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

Oui, c'est long, moche et peut sans aucun doute être complètement changé en code-golf plus .. Je suis à la fois distrait et fatigué, alors je devrais peut-être juste le supprimer à nouveau ..
C'était un défi assez difficile pour être honnête. Mais au moins vous avez votre première réponse ..;) (Ce qui pourrait même être plus long que votre programme C ++ non golfé original .. xD)

Cas non testés et testés:

Essayez-le ici.

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

Production:

first meets river 1 at 101
first meets river 3 at 12423
(empty output)
Kevin Cruijssen
la source
Je comparerai le vôtre avec le mien. Je vais également publier ma solution. Pourquoi utiliser un langage lent. Utilisez n'importe quel langage rapide.
Kishan Kumar
Je ne remarqué que l'étiquette la plus rapide algorithme plus tard .. Je posterai toujours Java 7 réponses code de golf ici .. Il est defintely ne va pas gagner soit le plus court ou le plus rapide mais .. BTW, votre rextester donne des erreurs quand il ne devrait donner des avertissements par manque de transtypages / type-initialise .. Il fonctionne sur ideone (et dans Eclipse IDE).
Kevin Cruijssen
D'accord. laisse moi voir. rextester donne le temps de compilation et le temps d'exécution. Je l'ai donc utilisé
Kishan Kumar
c'est un problème ici. Je vais chercher un autre compilateur en ligne qui donne le temps de compilation et le temps d'exécution
Kishan Kumar
@KishanKumar J'ai ajouté les transtypages dans mon code, ce qui ne devrait pas affecter le temps afaik Voici le code de rextester fonctionnel avec le résultat: 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 secpour moi localement. Alors oui, c'est assez lent ..
Kevin Cruijssen
1

Scala, 774 octets

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

Je n'ai pas envie de jouer au golf. Il trouve une solution au problème posé dans les 50 ms

L'utilisation peut ne pas être exactement ce que vous voulez:

scala river.scala

Vous pouvez maintenant saisir en continu des nombres suivis d'une entrée. Et terminez le programme avec 0. Le résultat sera imprimé dès que vous appuyez sur Entrée.

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
la source
Je ne connais pas grand-chose à Scala. Alors, s'il vous plaît, pourriez-vous modifier le code qui, selon rextester.com/l/scala_online_compiler
Kishan Kumar
J'ai essayé de le mettre là-dedans mais il a expiré pendant la compilation.
AmazingDreams
ok @AmazingDreams
Kishan Kumar
@KishanKumar même la valeur par défaut expire, donc le site semble être cassé pour scala
AmazingDreams
@KisthanKumar Utilisez celui-ci scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b mais il ne prend pas en charge stdin, j'ai donc dû changer quelques petites choses.
AmazingDreams
1

C, 228 283 300 octets

Ceci est un mod du code de Yakov pour profiter des modèles de rivière. Cela le rend environ 3 fois plus rapide. De plus, les entiers non signés évitent la cltodpénalité sur les machines 64 bits, c'est donc quelques octets de plus mais fractionnellement plus rapide.

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

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

Explication:

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

Cela sélectionne la bonne rivière. La rivière 1 rencontre toutes les autres rivières, nous utilisons donc cela comme cas de repli. Si 3 est le plus grand diviseur commun de la rivière test, nous sélectionnons la rivière 3 ( 1 + !(i%3)*2). Si 9 est le plus grand diviseur commun de la rivière test, nous remplaçons les valeurs précédentes et sélectionnons la rivière 9.

Pourquoi ça marche? La rivière 9 passe à 9, 18, 27, 36, etc. Cela fait un multiple de 9 à chaque fois, donc ce sera toujours le chemin le plus court vers une rivière sœur. La rivière 3 progressera par un multiple de 3 à chaque fois: 3, 6, 12, 15, 21, etc. Alors que les rivières qui sont un multiple de 9 sont également un multiple de 3, nous les choisissons comme rivière 9 en premier, ne laissant que le multiples de 3. Le reste rencontrera la rivière 1 en premier: 1, 2, 4, 8, 16, 23, 28, etc.

Une fois que nous avons sélectionné notre bonne rivière, nous marchons les deux rivières jusqu'à ce qu'elles se rencontrent.

Seth
la source
1

Python 3, 144 octets

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
la source
0

C

Très simple, ça a l'air si long car j'ai déroulé les 3 rivières. Il génère d'abord les 3 rivières jusqu'à RIVER_LENGTH(ce qui, je l'espère, est assez grand), puis pour chaque étape, Nil effectue une recherche binaire sur les trois flux pour voir s'il se trouve dans l'un d'eux. Cela fonctionne parce que les flux sont déjà triés, nous pouvons donc faire le check-in de log(n)temps.

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

    }
}

Il faut d'abord un nombre pour le nombre de cas, au lieu d'utiliser 0pour délimiter la fin des entrées, parce que vous savez, C. C'est juste pour plus de commodité et n'affecte vraiment rien, donc j'espère que ça va.

Maltysen
la source
Ce programme atteint une limite de temps dépassée sur ideone sur les entrées 86,12345,0
Kishan Kumar
ideone.com/mHCeef voici le lien. Et il donne une sortie de signal kill sur rextester
Kishan Kumar
@KishanKumar Il faut d'abord un nombre pour le nombre de cas, au lieu d'utiliser 0 pour délimiter la fin des entrées, parce que vous savez, C. C'est juste pour plus de commodité et n'affecte vraiment rien, donc j'espère que ça va.
Maltysen
@KishanKumar essayez celui-ci à la place: rextester.com/XRJK89444
Maltysen
c'est bon. Aucun problème. Mais je devrai écrire un script supplémentaire pour votre programme. Comme je dois prendre le temps moyen de toute la plage d'entrée.
Kishan Kumar