डिजिटल रिवर (सबसे छोटा और सबसे तेज़ समाधान)


9

यह मेरा पहला सवाल है, इसलिए मुझे उम्मीद है कि यह अच्छा होगा।

पृष्ठभूमि:

यह ऐसी नदियाँ नहीं हैं जिनके बारे में आप सोच रहे होंगे। सवाल डिजिटल नदियों की अवधारणा के आसपास घूमता है। एक डिजिटल नदी संख्या का एक अनुक्रम जहां संख्या निम्नलिखित है nहै nके साथ साथ अपने अंकों की राशि।

स्पष्टीकरण:

12345 के बाद से 12360 के बाद से 1 + 2 + 3 + 4 + 5 = 15 और इसलिए 12345 + 15 12360 देता है। इसी तरह 145 के बाद 155 है। यदि एक डिजिटल नदी की पहली संख्या है Mतो हम इसे नदी कहेंगे M

उदाहरण के लिए: रिवर 480 अनुक्रम की शुरुआत {480,492,507,519 ....} है, और नदी 483 अनुक्रम {483,498,519, ....} है। सामान्य धाराएँ और नदियाँ मिल सकती हैं, और यही बात डिजिटल नदियों के लिए भी सही है। ऐसा तब होता है जब दो डिजिटल नदियां समान मूल्यों को साझा करती हैं।

उदाहरण:

नदी 480 पर नदी 483 में 519 पर मिलती है। नदी 480 में 507 पर नदी से मिलती है और कभी नदी में 481 से मिलती है। प्रत्येक डिजिटल नदी अंततः नदी 1, नदी 3 या नदी 9 से मिलेंगी।

एक प्रोग्राम लिखें जो किसी दिए गए पूर्णांक nके लिए निर्धारित कर सकता है मान जहां नदी nपहले इन तीन नदियों में से एक से मिलती है।

इनपुट

इनपुट में कई परीक्षण मामले हो सकते हैं। प्रत्येक परीक्षण मामले में एक अलग लाइन होती है और एक पूर्णांक n( 1 <= n <= 16384) होता है। के मूल्य के साथ एक टेस्ट केस 0के लिए nऔर इनपुट समाप्त हो जाता है इस परीक्षण का मामला संसाधित नहीं किया जाना चाहिए।

उत्पादन

इनपुट में प्रत्येक परीक्षण के मामले के लिए नमूना आउटपुट में दिखाए गए अनुसार परीक्षण केस संख्या (1 से शुरू) का उत्पादन होता है। फिर एक अलग लाइन आउटपुट पर लाइन "पहले y पर नदी x से मिलती है"। यहां y सबसे कम मूल्य है जहां नदी nपहले नदी x(x = 1 या 3 या 9) से मिलती है । यदि नदी एक से अधिक मूल्य के लिए nनदी xसे मिलती yहै x, तो सबसे कम मूल्य का उत्पादन होता है। लगातार दो परीक्षण मामलों के बीच एक रिक्त रेखा प्रिंट करें।

परीक्षण का मामला

इनपुट:

86
12345
0

आउटपुट:

Case #1

first meets river 1 at 101

Case #2

first meets river 3 at 12423

स्कोरिंग:

सबसे तेज एल्गोरिथ्म जीतता है। टाई के मामले में। कम कोड वाला जीतेगा।

मेरी त्रुटि को इंगित करने के लिए mbomb007 के लिए धन्यवाद ।

ps: मैं सबसे छोटे वाले के बजाय सबसे तेज समाधान चाहता हूं। मेरे पास मेरा एक हल भी है जो धीमा है। इसके लिए यहां देखें

ध्यान दें:

मैं का उपयोग किया जाएगा इस कोड के परीक्षण के लिए। और प्रदर्शन की जाँच।


3
मुझे यकीन नहीं है कि आप इस तरह से स्कोर कर सकते हैं। यदि किसी का कोड O (लॉग एन (लॉग एन)) है तो क्या होगा? आप उन सभी को कवर नहीं कर सकते हैं, इसलिए आपको केवल यह कहने की आवश्यकता है कि सबसे तेज़ एल्गोरिथ्म जीतता है, लेकिन एक टाई के मामले में, सबसे छोटा कोड जीतता है, और पहले पोस्ट किए गए जीत दोनों एक ही लंबाई के होते हैं।
mbomb007

3
मुझे पुराने ACM-ICPC चुनौतियों के कॉपीराइट या प्रयोज्य पर कुछ भी नहीं मिल रहा है, लेकिन मैं इस चुनौती को संग्रह स्थल पर पा सकता हूं क्या यह यहाँ उपयोग करने की अनुमति है?
15

1
इसका कॉपीराइट से कोई लेना-देना नहीं है। यदि संदेह है, तो सबसे आसान बात यह है कि साइट के मालिक को ईमेल करें और पूछें।
ज्योबिट्स

3
" अगर एक डिजिटल नदी का अंतिम अंक है, Mतो हम इसे नदी कहेंगेM " दो कारणों से कोई मतलब नहीं है: सबसे पहले, यदि एक नदी संख्याओं का एक अनंत अनुक्रम है, तो इसका अंतिम अंक नहीं है; और दूसरी बात, अगले पैराग्राफ में नदी काM मतलब संख्या पर शुरू होने वाली नदी है M
पीटर टेलर

2
लिंक किए गए CR.SE प्रश्न से, ऐसा लगता है कि एक नदी जो भी श्रृंखला में शुरू की संख्या है, लेकिन यहां यह अंतिम अंक है। क्या सही है?
सेलेओ

जवाबों:


3

सी, 320 294 बाइट्स

संकलन -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]);}}

Ungolfed:

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

कोशिश करके देखो!

अनिवार्य रूप से, "लक्ष्य" नदियों को तब तक बढ़ाया जाता है जब तक कि वे उस नदी से अधिक नहीं हो जाते हैं जिसके खिलाफ हम परीक्षण कर रहे हैं, और बाद में परीक्षण नदी को बढ़ा दिया जाता है। यह तब तक दोहराया जाता है जब तक कि परीक्षण नदी किसी अन्य नदी के बराबर न हो जाए।

मैं इस कार्यक्रम में कमांड लाइन से पैरामीटर नहीं पढ़ रहा हूं, और यदि आप मान रहे हैं तो मुझे यकीन नहीं है। अब आप STDIN को पैरामीटर पास कर सकते हैं। आप एक गैर-सांख्यिक इनपुट पास करके समाप्त कर सकते हैं।

इसके अलावा, आधे घंटे तक मार पड़ी।


मैं अभी के लिए परीक्षण मामलों पर काम कर रहा हूं। केवल 3 इनपुट परीक्षण के मामले बहुत उपयुक्त नहीं होंगे।
किशन कुमार

कृपया आप स्टड से इनपुट लेना चाहेंगे।
किशन कुमार

3

जावास्क्रिप्ट (ES6)

यह काफी धीमी भाषा का उपयोग करते हुए काफी तेज उत्तर है। वास्तव में, समय को क्रियान्वित करना हैश टेबल्स के साथ किसी भी भाषा का उपयोग करने में समस्या नहीं होनी चाहिए। 100 एमएस के तहत मेरे सभी परीक्षण।

इनपुट पैरामीटर के रूप में परीक्षण मामले की सूची के साथ अनाम विधि।

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]))


1

जावा 7, 519 505 बाइट्स

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

हां, यह लंबा है, बदसूरत है और बिना किसी संदेह के इसे पूरी तरह से कोड-गोल्फ में बदल दिया जा सकता है .. मैं विचलित और थका हुआ हूँ, इसलिए शायद मुझे इसे फिर से हटा देना चाहिए ..
ईमानदार होना एक बहुत कठिन चुनौती थी। । लेकिन कम से कम आपके पास अपना पहला उत्तर है ..;) (जो कि आपके मूल असम्बद्ध C ++ प्रोग्राम .. xD) से भी अधिक लंबा हो सकता है।

अनगढ़ और परीक्षण के मामले:

इसे यहाँ आज़माएँ।

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

आउटपुट:

first meets river 1 at 101
first meets river 3 at 12423
(empty output)

मैं तुम्हारा कार्यक्रम मेरे साथ तुलना करूँगा। मैं अपना समाधान भी पोस्ट करने जा रहा हूं। धीमी भाषा का उपयोग क्यों करें। किसी भी तेज भाषा का उपयोग करें।
किशन कुमार

मैंने केवल सबसे तेज़-एल्गोरिथ्म टैग को बाद में देखा .. मैं हमेशा जावा 7 कोड-गोल्फ उत्तर यहाँ पोस्ट करता हूं .. यह रक्षात्मक रूप से सबसे कम या सबसे तेज़ी से जीतने वाला नहीं है .. लेकिन Btw, जब आपका चेतावनियाँ केवल चेतावनी देनी चाहिए, तो वह त्रुटि देता है। जातियों की कमी / टाइप-इनिशियलाइज़ेशन के लिए .. यह ideone पर काम करता है (और ग्रहण आईडीई में)।
केविन क्रूज़सेन

ठीक। मुझे देखने दो। rextester संकलन समय और निष्पादन समय देता है। इसलिए मैंने इसका इस्तेमाल किया
किशन कुमार

अच्छी तरह से यहाँ एक समस्या है। मैं अन्य ऑनलाइन संकलक की तलाश करूंगा जो संकलन समय और निष्पादन का समय देता है
किशन कुमार

@ किशनकुमार ने अपने कोड में उन कास्ट्स को जोड़ा है, जो समय को प्रभावित नहीं कर सकते हैं। यहां रिजल्ट के साथ काम करने वाला रीक्स्टर कोड है : 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 secमेरे लिए स्थानीय स्तर पर। तो हाँ, यह बहुत धीमी है ..
केविन क्रूज़सेन

1

स्काला, 774 बाइट्स

फिडल: http://scalafiddle.net/console/4ec96ef90786e0f2d9f7b61b5ab0209b

मैं इसे गोल्फ की तरह महसूस नहीं करता। यह 50ms के भीतर उत्पन्न समस्या का हल ढूंढता है

उपयोग वैसा नहीं हो सकता जैसा आप चाहते हैं:

scala river.scala

अब आप लगातार इनपुट नंबर दर्ज कर सकते हैं। और प्रोग्राम को 0. के साथ समाप्त करें। जैसे ही आप एंटर करेंगे, परिणाम प्रिंट हो जाएगा।

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

मुझे स्काला के बारे में ज्यादा जानकारी नहीं है। तो कृपया आप उस कोड को संशोधित कर सकते हैं जो rextester.com/l/scala_online_compiler के
किशन कुमार

मैंने इसे वहाँ लगाने की कोशिश की लेकिन यह संकलन करते समय समाप्त हो गया।
अमेज़िंगड्रीम

ok @AmazingDreams
किशन कुमार

@ किशनकुमार ने एक बार भी डिफॉल्ट किया, जिससे लगता है कि साइट स्केला के लिए टूट गई है
अमेजिंगड्रीम

@KisthanKumar इस एक स्केलफैडेल का उपयोग करें ।/console/4ec96ef90786e0f2d9f7b61b5ab0209b यह स्टड का समर्थन नहीं करता है, हालांकि इसलिए मुझे कुछ मामूली चीजों को बदलना पड़ा।
अमेजिंगड्रीम

1

सी, 228 283 300 बाइट्स

यह नदी के पैटर्न का लाभ उठाने के लिए यकोव का कोड है। यह इसे ~ 3x तेज बनाता है। इसके अलावा, अहस्ताक्षरित पूर्णांक cltod64-बिट मशीनों पर जुर्माने से बचते हैं, इसलिए यह कुछ बाइट्स लंबा लेकिन आंशिक रूप से तेज है।

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

Ungolfed:

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

स्पष्टीकरण:

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

यह सही नदी का चयन करता है। नदी 1 हर दूसरी नदी से मिलती है, इसलिए हम इसे पतन के मामले के रूप में उपयोग करते हैं। यदि 3 परीक्षण नदी का सबसे बड़ा सामान्य विभाजक है, तो हम नदी 3 ( 1 + !(i%3)*2) का चयन करते हैं । यदि 9 परीक्षण नदी का सबसे बड़ा सामान्य विभाजक है, तो हम पिछले मूल्यों को ओवरराइड करते हैं और नदी 9 का चयन करते हैं।

यह काम क्यों करता है? नदी 9 9, 18, 27, 36, आदि जाती है। प्रत्येक समय 9 की एक से अधिक संख्या में कदम इस प्रकार यह हमेशा एक बहन नदी का सबसे छोटा मार्ग होगा। नदी 3 हर बार 3 की एक से कई कदम उठाएगी: 3, 6, 12, 15, 21, आदि। जबकि 9 की एक से अधिक नदियां भी 3 की एक से अधिक हैं, हम उन्हें पहले 9 नदी के रूप में चुनते हैं, केवल छोड़कर 3. के गुणक 3. शेष 1 नदी से पहले मिलेंगे: 1, 2, 4, 8, 16, 23, 28, आदि।

एक बार जब हमने अपनी सही नदी का चयन कर लिया, तो हम दोनों नदियों को मिलने तक रोक देते हैं।


1

पायथन 3, 144 बाइट्स

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

0

सी

बहुत सरल, यह सिर्फ इतना लंबा लगता है क्योंकि मैं सभी 3 नदियों को अनियंत्रित करता हूं। यह पहले 3 नदियों को उत्पन्न करता है RIVER_LENGTH(जो मुझे आशा है कि काफी बड़ा है), और फिर इस पर प्रत्येक चरण के लिए Nसभी तीन धाराओं पर एक द्विआधारी खोज करता है यह देखने के लिए कि क्या यह उनमें से किसी में है। यह काम करता है क्योंकि स्ट्रीम पहले से ही सॉर्ट किए गए हैं, इसलिए हम log(n)समय पर चेक शामिल कर सकते हैं ।

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

    }
}

0इनपुट्स के अंत का उपयोग करने के बजाय पहले मामलों की संख्या के लिए यह एक संख्या लेता है , क्योंकि आप जानते हैं, सी। यह सिर्फ सुविधा के लिए है और वास्तव में कुछ भी प्रभावित नहीं करता है, इसलिए मुझे इसकी ठीक उम्मीद है।


यह कार्यक्रम इनपुट पर विचारधारा से अधिक समय सीमा पार करता है 86,12345,0
किशन कुमार

ideone.com/mHCeef यहाँ लिंक है। और यह रेक्सटेस्टर पर एक किल सिग्नल आउटपुट देता है
किशन कुमार

@ किशनकुमार पहले इनपुट की समाप्ति के लिए 0 का उपयोग करने के बजाय पहले मामलों की संख्या के लिए एक संख्या लेता है, क्योंकि आप जानते हैं, सी। यह सिर्फ सुविधा के लिए है और वास्तव में कुछ भी प्रभावित नहीं करता है, इसलिए मुझे इसके ठीक होने की उम्मीद है।
माल्टीसेन

@ किशनकुमार इसके बजाय एक प्रयास करें: rextester.com/XRJK89444
माल्टीसेन

यह ठीक है। कोई दिक्कत नहीं है। लेकिन मुझे आपके कार्यक्रम के लिए एक अतिरिक्त स्क्रिप्ट लिखनी होगी। जैसा कि मुझे सभी इनपुट रेंज का औसत समय लेना है।
किशन कुमार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.