July 04, 2021

Merhaba,

Eski bir yapıyı (-bknz. triBit 2012 Kasımı) hortlatarak bir soru çözümü yayınlıyorum. Bu haliyle sadece 3 satır değiştirerek BitArray'e (-bknz. std.bitmanip) çevirmek mümkün...

Açıklamalar, kod (en alttaki asıl kod) içinde mevcut. Hız ve hafıza iyileştirmesine odaklanmadan basit bir yapının geliştirilmesi için çaba sarfettim. Aslında sorunun çözümü için getURL veya başka bir yöntemle veriyi (dataset)'i elde ettikten sonra şu birkaç satır yeterli:

void main()
{
  with(DNA)
  {            /*** SORU ***/
    auto s = DNAstack([A,A,A,A,C,C,C,G,G,T]);
    s.FIFO_is = true;
    while (!s.empty)
    {
      s.pop.write(" ");
    }
    writeln(": the problem");

               /*** CEVAP ***/
    s.FIFO_is = false;
    s.invertData();
    while (!s.empty)
    {
      s.pop.write(" ");
    }
    writeln(": is solved.");
  }
}

Bool[] dizisi (-bknz. this.data), ilk while() döngüsü ile this.index'i ileriye doğru tükettiğinden (-bknz. FIFO), çözümün 2. bölümünde invertData ile tersindiği için ve foreach()'in yaptığı gibi yapının yedeği alınmadığında bu sefer terse doğru (-bknz. LIFO) bir gezinme, yani çözümün kendisini ekrana yazılır:

/* DNAstack.d
 * 04.07.2021
 *
 * To solve the problem:
 * http://rosalind.info/problems/revc/
 *
 * In Turkish: Bu kod 4'lü bir veri türü enum.DNA
 *             ile LIFO/FIFO türünde erişilebilen
 *             yığıtı meydana getirir, invertData
 *             ile de sorun çözülür!
 *
 *             Özetle basit ve etkili bir yapıdır!
 */

import std.stdio;

enum DNA { A,  // [ 0, 0 ]
           C,  // [ 0, 1 ]
           G,  // [ 1, 0 ]
           T   // [ 1, 1 ]
         }/****** [ L, R ] ******/
void main()
{
  with(DNA)
  {
    auto dataset = [A,A,A,A,C,C,C,G,G,T];/*
    char[] dataset = std.net.curl.get
    (
      "http://rosalind.info/problems/dna/dataset/rosalind_dna.txt"
    );//* Buradan veri çekmek için login ve tür dönüştürme gerekli */

    auto s = DNAstack(dataset);

    //s.invertData();/* <- TOGGLE-MARK
    //* Soruyu çözmek için bu @property'i aç ve şaşır! */
    foreach(n; s) n.write(" ");
    writeln;

    while(!s.empty) s.pop.write(" ");
    writeln;

    s.FIFO_is = true; /* Açıklaması şu başlıkta:
        https://forum.dlang.org/post/sbo1u2$21t1$1@digitalmars.com */

    foreach_reverse(n; s) n.write(" ");
    writeln;

    while(!s.empty) s.pop.write(" ");
    writeln;
  }
}/* dataInvert'li çıktısı:
A C C G G G T T T T
A C C G G G T T T T
T T T T G G G C C A
T T T T G G G C C A
*
*** 4'lü uygulama (foreach'lerde yapı kopyalanır ***
*
T G G C C C A A A A
T G G C C C A A A A
A A A A C C C G G T
A A A A C C C G G T
*
//*/

struct DNAstack {
  private:
    bool FIFO;
    bool[] data;
    size_t index;

  public void FIFO_is (bool FIFO) @property {
    this.FIFO = FIFO;
    if (FIFO) index = 0;
  }
  public void invertData() @property {
    for(size_t n; n < index; n++)
      data[n] = data[n] ? false : true;
  }
  this (DNA[] customData)
  {
    index = customData.length * 2;
    foreach (dna; customData) {
      data ~= this.decode (dna);
    }
  }

  private bool[] decode (DNA n) pure
  {
    bool left, right;
    if(n == DNA.G || n == DNA.T) left = true;
    if(n == DNA.C || n == DNA.T) right = true;

    return [ left, right ];
  }

  private DNA encode (bool[] code) pure
  {
    int result;
    if (code[0]) result += 2;
    if (code[1]) result += 1;

    return cast(DNA)result;
  }

  void push (DNA veri) {
    if(!FIFO) index += 2;
    data ~= this.decode(veri);
  }

  DNA pop () {
    bool left, right;
    if (FIFO) {
      index += 2;
      left = data[index-2];
      right = data[index-1];
    } else {
      index -= 2;
      left = data[index];
      right = data[index+1];
    }
    return encode([ left, right ]);
  }

  bool empty () {
    if (FIFO) {
      return index == data.length;
    } else {
      return index == 0;
    }
  }
  // foreach(s; DNAstack) ise kullanılır (FIFO is False):
  void popFront () { index -= 2; }
  DNA front () { //  for implementing the LIFO
    auto left = data[index-2];
    auto right = data[index-1];
    return encode([ left, right ]);
  }
  // foreach_reverse(s; DNAstack) ise kullanılır (FIFO is True):
  void popBack () { index += 2; }
  DNA back () { // for implementing the FIFO
    auto left = data[index];
    auto right = data[index+1];
    return encode([ left, right ]);
  }
}