एक साधारण डीएनए सिम्युलेटर


18

आपका कोड हमेशा के लिए डीएनए का एक बहुत ही सरल ASCII- कला प्रतिनिधित्व उत्पन्न करने वाला है। किसी भी प्रारूप में इनपुट के रूप में आपको दो नंबर लेने होंगे: एक सूची के रूप में, एक फ़ंक्शन के तर्क के रूप में, स्टड पर, आदि।

  • एक फ्लोटिंग-पॉइंट अंतराल I0.0 और 1.0 के बीच सेकंड में (सम्मिलित)
  • Z1 से 64 तक पूर्णांक के रूप में एक ज़ूम स्तर (समावेशी)

आपका कोड हर एक Iसेकंड में stdout या उसके समकक्ष एक लाइन प्रिंट करेगा , एक अनंत आउटपुट का उत्पादन करेगा जो कुछ इस तरह दिखता है (ज़ूम 4 के लिए):

    A
 T-----a
G-------c
 G-----c
    g
 t-----A
a-------T
 c-----G
    T
 A-----t
C-------g
...

विशेष रूप से, डीएनए के बारे में हमारी प्रतिनिधित्व, हाइफ़न से जुड़े हुए साइन लहरों की एक जोड़ी है पात्रों में से एक से मिलकर a, c, g, और t, वर्ण के अन्य A, C, G, और T। यदि xहम जिस लाइन को वर्तमान में प्रिंट कर रहे हैं, उसकी 0-अनुक्रमित संख्या है, तो लोअरकेस वेव में वर्ण की 0-आधारित स्थिति द्वारा दी गई है (sin(πx / Z) + 1) * Z, और अपरकेस तरंग में (-sin(πx / Z) + 1) * Z, दोनों को गोल दिया गया है (निकटतम नहीं) पूर्णांक। आगे की जानकारी:

  • ऐसे मामलों में जहां दो तरंगें ओवरलैप होती हैं, आपको वैकल्पिक रूप से यह समझने की जरूरत है कि कौन सी लहर सामने है, जो अपरकेस लहर से शुरू होती है। (लोअरकेस वेव से शुरू होने से हमें एक डबल हेलिक्स मिलेगा जो मौजूद नहीं है !)
  • मामले को नज़रअंदाज़ करते हुए, A हमेशा T और C के साथ हमेशा G के साथ जोड़े, जैसा कि असली डीएनए में होता है। चार संभावनाओं पर एक समान वितरण के साथ जोड़े को खुद बेतरतीब ढंग से चुना जाना चाहिए। इससे कोई फर्क नहीं पड़ता कि जोड़े का विकल्प आपके कोड के क्रमिक रन पर समान या अलग है। जब तक आउटपुट में कोई स्पष्ट पैटर्न न हो और कम से कम अरबों (त्रुटिपूर्ण PRNGs जैसे RANDU ठीक हों) में आपके यादृच्छिक विकल्पों की सांख्यिकीय गुणवत्ता कोई समस्या नहीं है।
  • आपके पास या तो कोई अनुगामी स्थान या हर पंक्ति उस ज़ूम स्तर पर तरंगों की अधिकतम स्थिति के लिए पैड नहीं होनी चाहिए (उदाहरण के लिए, नौ वर्ण।) ज़ूम स्तर 1 में गणितीय कारणों से एक वैकल्पिक अतिरिक्त अनुगामी स्थान हो सकता है।

क्योंकि डीएनए छोटा है, आपके कोड को यथासंभव छोटा होना चाहिए।

और ज्यादा उदाहरण:

ज़ूम स्तर 8:

        T
     C-----g
  A-----------t
 C-------------g
G---------------c
 T-------------a
  T-----------a
     T-----a
        c
     g-----C
  t-----------A
 g-------------C
a---------------T
...

ज़ूम स्तर 2:

  A
T---a
  c
g---C
  G
A---t
  c
a---T
...

ज़ूम स्तर 1 (प्रमुख स्थान पर ध्यान दें):

 G
 a
 C
 t
...


9
"क्योंकि डीएनए छोटा है, आपके कोड को यथासंभव छोटा होना होगा।" वास्तव में?
तन्माथ

3
@TanMath क्या आपको वास्तव में कोड-गोल्फ के लिए एक कारण की आवश्यकता है? बैकस्टोरी लगभग हमेशा इस तरह से मूर्ख होती हैं, बस इसके साथ जाएं।
पैट्रिक रॉबर्ट्स

@PatrickRoberts मुझे पता है, लेकिन मैं सिर्फ इशारा कर रहा था कि कारण कितना मूर्खतापूर्ण है, कई कोड-गोल्फर करते हैं। इसे बहुत गंभीरता से मत लो! ;)
तन्मय

"बेतरतीब ढंग से चुने गए" का क्या अर्थ है? क्या रांडू ठीक है? एक छोटे से दोहराने के क्रम के बारे में क्या?
केएसएफटी

जवाबों:


4

रूबी, रेव बी 171 161 बाइट्स

Z = 1 लागत 10 बाइट्स के लिए आउटपुट फिक्स करना। यह एक विशेष मामला है: यदि आप इसे 90 डिग्री पर देखते हैं, तो हेलिक्स वास्तव में 3 वर्ण चौड़ा है, लेकिन जैसा कि हम इसे 0 डिग्री पर देखते हैं, यह केवल 1 वर्ण चौड़ा दिखता है। z = 1 पर शून्य अग्रणी स्थान की अब आवश्यकता नहीं है

कोष्ठकों को नष्ट करने से कुछ बचत और ट्रंकेशन से पहले y.abs को 2 से गुणा करके जब आवश्यक वर्णों की संख्या की गणना की जाती है।

अंत में, मैं बचा include Math(के लिए आवश्यक sinऔर PI) नंबर की शक्तियों के साथ जटिल संख्या गणित का उपयोग करके i। जटिल संख्या का काल्पनिक भाग पाप x के बराबर है, सिवाय इसके कि वह 2 * PI की अवधि के बजाय 4 के साथ दोहराता है। इस परिवर्तन के लिए सहेजना 1 या 0 बाइट्स था।

->z,i{x=0
loop{y=z*("i".to_c**x).imag
s=(?-*(y.abs*2)).center z*2+1
s[z-y+0.5]='TGAC'[r=rand(4)]
x!=0&&s[z+y+0.5]='actg'[r]
puts s
sleep i
x+=2.0/z
x>3.99&&x=0}}

रूबी, एक 165 बाइट्स रेव

यह उम्मीद से ज्यादा लंबा रास्ता है। खोज के लिए कुछ संभावित गोल्फ अवसर हैं।

include Math
->z,i{x=0
loop{y=z*sin(x)
s=('--'*(y.abs+h=0.5)).center(z*2+1)
s[z+h-y]='TGAC'[r=rand(4)]
x!=0&&s[z+h+y]='actg'[r]
puts s
sleep(i)
x+=PI/z
x>6.28&&x=0}}

परीक्षण कार्यक्रम में टिप्पणी की

include Math
f=->z,i{x=0
  loop{y=z*sin(x)
    s=('--'*(y.abs+h=0.5)).center(z*2+1)  #make a space-padded string of z*2+1 characters, containing enough - signs
    s[z+h-y]='TGAC'[r=rand(4)]            #insert random capital letter, saving index in r
    x!=0&&s[z+h+y]='actg'[r]              #insert small letter. This will normally go on top of the capital as it is done second, but supress for x=0 to make helix
    puts s
    sleep(i)
    x+=PI/z                               #increment x
    x>6.28&&x=0                           #reset x if equal to 2*PI (this proofs against loss of floating point precision, making correct output truly infinite.)
  }
}

Z=gets.to_i
I=gets.to_f
f[Z,I]

जंच रहे हो! एक छोटी सी समस्या: ज़ूम स्तर 1 के लिए एक प्रमुख स्थान है। इसके अलावा, आपके परीक्षण कार्यक्रम में I=gets.to_iहोना चाहिए I=gets.to_f
ल्यूक

ओह! आप सही कह रहे हैं कि Z = 1 एक विशेष मामला है। यह जानबूझकर नहीं था और वास्तव में मेरे द्वारा प्रदान किए गए गणित के नियमों में विरोधाभास है। मैं गणित को सुसंगत बनाने के लिए Z = 1 के लिए अग्रणी स्थान जोड़ने जा रहा हूं।
ल्यूक

@ सामान्य नियमों में परिवर्तन नहीं किया जाना चाहिए, लेकिन वास्तव में एक विरोधाभास था। जहाँ तक मैं बता सकता हूँ, अन्य उत्तरों ने भी इस पर विचार नहीं किया है। मैं बाद में अपना जवाब अपडेट करूंगा, क्योंकि यह इस तरह छोटा होगा।
लेवल रिवर सेंट

@Luke अपडेट किया गया, लेकिन इसका मतलब है कि मेरे पास Z = 1 पर एक अग्रणी स्थान और एक अनुगामी स्थान दोनों हैं। मैं समझता हूँ कि आप जो चाहते हैं और इसलिए ठीक है, की भावना के अनुसार, हालांकि इसकी सख्ती से अनुगामी रिक्त स्थान और Z = 1 के लिए उदाहरण के बारे में कथानक के अनुसार नहीं है।
लेवल रिवर सेंट

जो फिर से, हाँ, यह ठीक है। गलतफहमी के लिए खेद है।
लूका

3

सी, 294 289 285 283 281 270 265 237 218 बाइट्स

#include<math.h>
o,i,p,r;char*c="acgtTGCA",d[256]={[0 ...254]='-'};P(w,z)float w;{for(;;poll(0,0,r=w*1e3))p=fabs(sinf(M_PI*i++/z))*z+.5,r=rand()&3,o^=4*!p,printf(p?"%*c%s%c\n":"%*c\n",z-p+1,c[r+o],d+256-p*2,c[r+4-o]);}

या लंबा संस्करण जो मुख्य से इनपुट पार्स करता है:

#include<stdlib.h>
#include<math.h>
o,i,p,r;char*c="acgtTGCA",d[256]={[0 ...254]='-'};main(n,v)char**v;{for(;n=strtod(v[2],0);poll(0,0,n=atof(v[1])*1e3))p=fabs(sinf(M_PI*i++/n))*n+.5,r=rand()&3,o^=4*!p,printf(p?"%*c%s%c\n":"%*c\n",n-p+1,c[r+o],d+256-p*2,c[r+4-o]);}

यह एक बहुत ही विनम्र समग्र कार्यान्वयन है, इसमें कुछ प्रिंटफ ट्रिक डाली गई हैं। इसमें कुछ गायब हैं, जिसमें फ़ंक्शन के लिए K & R सिंटैक्स का उपयोग किया गया है, और GCC की रेंज इनिशियलाइज़र पर निर्भर है, इसलिए यह बहुत मानक नहीं है। फ़ंक्शन संस्करण अभी भी ग्लोबल्स का उपयोग करता है, इसलिए इसे केवल एक बार कहा जा सकता है!

फ़ंक्शन संस्करण 2 पैरामीटर लेता है; प्रतीक्षा करें (सेकंड में) और ज़ूम करें। यहाँ इसके लिए एक कॉलर है:

#include <stdlib.h>
int main( int argc, const char *const *argv ) {
    if( argc != 3 ) {
        printf( "Usage: %s <delay> <zoom>\n", argv[0] );
        return EXIT_FAILURE;
    }
    const float delay = atof( argv[1] );
    const int zoom = strtod( argv[2], 0 );
    if( delay < 0 || zoom <= 0 ) {
        printf( "Invalid input.\nUsage: %s <delay> <zoom>\n", argv[0] );
        return EXIT_FAILURE;
    }
    P( delay, zoom );
    return EXIT_SUCCESS;
}

ऐसे दोड़ो:

./dna <delay> <zoom>
./dna 0.5 8

टूट - फूट:

// Globals initialise to 0
o,                                 // Ordering (upper/lower first)
i,                                 // Current iteration
p,                                 // Current indent
r;                                 // Current random value
char*c="acgtTGCA",                 // The valid letters
    d[256]={[0 ...254]='-'};       // Line of dashes (for printing)
main(n,v)char**v;{                 // K&R-style main definition (saves 2 bytes)
    // n will be used for Zoom, random number & casting delay
    for(
        ;n=strtod(v[2],0);         // Store zoom
        poll(0,0,n=atof(v[1])*1e3) // After each loop, use poll to delay
                                   // (Use variable to cast delay to int)
    )
        p=fabs(sinf(M_PI*i++/n))*n+.5,   // Calculate separation / 2
        r=rand()&3,                      // Pick random number [0-4)
        o^=4*!p,                         // Reverse order if crossing
        printf(p                         // Print... if not crossing:
                ?"%*c%s%c\n"             //  indent+character+dashes+character
                :"%*c\n",                //  Else indent+character
                n-p+1,                   // Width of indent + 1 for char
                c[r+o],                  // First character
                d+256-p*2,               // Dashes
                c[r+4-o]                 // Second character
        );
}

आप मुख्य (), जो आप के बाइट्स की बचत होगी बजाय एक समारोह उपयोग करने की अनुमति strtodऔर atof
ल्यूक

@ लुक आह कूल; मैं देखता हूँ कि कितना बचाता है ...
डेव

3

सी, 569 402 361 बाइट्स

#include<stdlib.h>
u,l,r,m,n,Z,I,y=0,x=0;main(c,char**v){Z = atoi(v[1]);I=atof(v[2])*1000000;srand(time(0));char *a="ACGTtgca";while(1){r=rand()%4;usleep(I);double s=sin(3.14*x++/Z);u=floor(((-1*s+1)*Z)+0.5);l=floor(((s+1)*Z)+0.5);m=(u<l)?u:l;n=u<l?l:u;char z[n+1];memset(z,' ',n);z[l]=a[r+4];z[u]=a[r];for(y=m+1;y<n;y++)z[y]='-';z[n+1]='\0';printf("%s\n",z);}}

यह बहुत जल्दी तैयार है, इसलिए मुझे यकीन है कि मेरे स्कोर को कम करने के लिए मैं कुछ अन्य चीजें कर सकता हूं, लेकिन मैं खुश हूं कि मुझे यह कार्यक्रम पहले प्रयास में संकलित करने और ठीक से चलाने के लिए मिला।

डी-गोल्फ संस्करण:

#include<stdio.h>
#include<math.h>
#include<unistd.h>
#include<time.h>
#include<stdlib.h>
u,l,r,m,n,Z,I,y=0,x=0;
main(c,char**v){
   Z = atoi(v[1]);
   I=atof(v[2])*1000000;
   srand(time(0));
   char *a="ACGTtgca";
   while(1){
      r=rand()%4;
      usleep(I);
      double s=sin(3.14*x++/Z);
      u=floor(((-1*s+1)*Z)+0.5);
      l=floor(((s+1)*Z)+0.5);
      m=(u<l)?u:l;
      n=u<l?l:u;
      char z[n+1];
      memset(z,' ',n);
      z[l]=a[r+4];
      z[u]=a[r];
      for(y=m+1;y<n;y++)z[y]='-';
      z[n+1]='\0';
      printf("%s\n",z);
   }
}

अद्यतन: मैंने एक प्रिंट स्टेटमेंट में सब कुछ प्रिंट करने के लिए लूप समायोजित किया और इस तथ्य का उपयोग किया कि कुछ बाइट्स को दाढ़ी बनाने के लिए चर को डिफ़ॉल्ट रूप से परिभाषित किया गया है। UPDATE2: कुछ संस्करण का नामकरण और कुछ तर्क कुछ और बाइट्स को छोटा करने के लिए।


आपको GCC को पकड़ना होगा। यह लिनक्स है, लेकिन आप इसे सिगविन के साथ खिड़कियों पर भी चला सकते हैं। चर (यदि प्रोग्राम की शुरुआत में या फ़ंक्शन तर्कों के रूप में घोषित किए गए हैं) को एक प्रकार की आवश्यकता नहीं है, तो उन्हें इंट माना जाता है। कार्यों के साथ भी ऐसा ही है। और मुझे पूरा यकीन है कि आपको उन लोगों की आवश्यकता नहीं होगी।
लेवल रिवर सेंट

1
इसके अलावा आपके पास बहुत से प्रिंटआउट हैं :- डी। या तो 1. एक समय में एक चरित्र को प्रिंट करने के लिए पुचकार का उपयोग करें या 2. जो आप प्रिंट करना चाहते हैं उसे काम करें और फिर पुट के साथ इसे प्रिंट करें। 3. इसमें एक बड़ी जटिल अभिव्यक्ति के साथ एक ही प्रिंटफ का उपयोग कैसे करें, इस पर काम करें। वैसे भी, +1।
लेवल रिवर सेंट

सुझाव के लिए ठीक है धन्यवाद! मैं कोशिश करूंगा और एक सिंगल प्रिंट स्टेटमेंट बनाऊंगा। यह एक अच्छा विचार है और मुझे यकीन है कि यह मेरे स्कोर में सुधार करेगा। जब मैं आज कुछ समय लूंगा तो मैं इसे पुनः प्राप्त करूंगा। धन्यवाद @steveverrill
14

2

जावास्क्रिप्ट (ईएस 6) 241 244 227 222 231 बाइट्स

यह दिलचस्प लग रहा था - मुझे ASCII कला पसंद है!
अभी शुरू हुआ है, अभी भी इसे गोल्फ की प्रक्रिया में ...

(I,Z)=>{c=i=0,setInterval(_=>{with(Math)m=sin(PI*i++/Z),a=round(++m*Z),b=round((2-m)*Z),r=random()*4|0,D="TGAC"[r],d="actg"[r],e=a-b,c^=!e,p=" ".repeat(a>b?b:a)+(c?D:d)+"-".repeat(e?abs(e)-1:0)+(e?a>b?d:D:""),console.log(p)},I*1e3)

--- संपादित करें: यह पता चलता है कि मैं वास्तव में इसे eval में नहीं डाल सकता () - अन्यथा यह var I और Z तक नहीं पहुँच सकता (इसलिए इसे बाइट्स कहा जाता है)

- user81655 के लिए 6 बाइट्स धन्यवाद बचाया
- डेव के लिए 5 बाइट्स बचाए

व्याख्या

(I,Z)=>{
  c=i=0,                                // clear vars
  setInterval(_=>{                      // repeat

    with(Math)                         
      m=sin(PI*i++ / Z),                // calculate waves
      a=round(++m * Z),
      b=round((2-m) * Z),
      r=random()*4|0,                   // get random amino-acids
      D="TGAC"[r],
      d="actg"[r],
      e=a-b,
      c^=!e,                            // alternate upper/lowercase
      p=                                // prepare output
        " ".repeat(
          a>b ? b : a
        )+(
          c ? D : d
        )+

        "-".repeat(
          e ? abs(e)-1 : 0
        )+(
          e ? a>b ? d : D : ""
        ),

      console.log(p)                    // return output
  },I*1e3)                              // repeat for every 'I' seconds
}

1
आप c^=!eइसके बजाय का उपयोग करके एक और 4 बाइट्स बचा सकते हैं c+=a==b(आपको %2बाद में चेक को हटाने की अनुमति देता है )। भी -m+2हो सकता है 2-m!
डेव

@Dave - धन्यवाद! क्या आप यह बताना चाहेंगे कि वास्तव में क्या होता है? मैंने इससे पहले कभी नहीं देखा :)
A

यह वैसा ही है c=c^(e==0); यह उसी तरह एक XOR लागू करता है जिस तरह से आपके पास पहले जोड़ था। यदि आप XOR से अपरिचित हैं, तो यह एक बिटवाइस ऑपरेशन है: eXclusive OR (विकिपीडिया इसे ठीक से समझा सकता है)
डेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.