← Catalogo
PROB
PyJS

Introduction to Random Strings

Probability

Pagina originale su rosalind.info

Descrizione

Una stringa casuale viene costruita scegliendo ogni simbolo successivo in base a una frequenza simbolica fissata, derivata dal GC-content: se il GC-content è x, la probabilità di ciascun simbolo 'C'/'G' è x/2, mentre la probabilità di ciascun simbolo 'A'/'T' è (1-x)/2. Il problema chiede la probabilità (in scala logaritmica in base 10) che una stringa casuale con un dato GC-content corrisponda esattamente a una stringa data.

Given

Una stringa di DNA s di lunghezza massima 100 bp e un array A contenente al massimo 20 numeri tra 0 e 1 (valori di GC-content).

Return

Un array B della stessa lunghezza di A, in cui B[k] rappresenta il logaritmo in base 10 della probabilità che una stringa casuale costruita con il GC-content A[k] corrisponda esattamente a s.

Sample Dataset

ACGATACAA
0.129 0.287 0.423 0.476 0.641 0.742 0.783

Sample Output

-5.737 -5.217 -5.263 -5.360 -5.958 -6.628 -7.009

La mia esecuzione

08/24/2026 11:24:47

Input · dataset.txt

TGCGCCTAACGCCATTTTCAAGTTGGTGCCTAATATGACATGTTGCAATAAGGACGCCGATAGGAACCATGTATCCCATACCTAGTGAGCGTA
0.083 0.146 0.203 0.243 0.280 0.367 0.396 0.437 0.506 0.532 0.584 0.669 0.724 0.748 0.830 0.880 0.902

Output · run_log.txt

OK
-76.357 -67.356 -62.701 -60.46 -58.901 -56.645 -56.243 -55.93 -56.031 -56.269 -57.085 -59.511 -61.982 -63.348 -69.953 -76.424 -80.361

Esegui nel browser · Pyodide

Mostra il codice sorgente (problem.py)
import math

arrotonda = lambda x: round(x * 1000) / 1000

def lettura(filename):
    with open(filename) as f:
         riga = f.readline()
         s = riga.replace("\n", "")
         riga = f.readline()
         A = riga.replace("\n", "").split()
         return s, A 

def elab(s, A):
    result = [] 
    for k in range(len(A)):
        a = float(A[k])
        tot = 0
        for i in range(len(s)):
            if s[i]=="C" or s[i]=="G":
               tot += math.log10(a/2)
            else:
               tot += math.log10((1-a)/2)
        result.append(str(arrotonda(tot)))
    return result

def main():
    s, A = lettura("dataset.txt")
    result = elab(s, A)
    print(" ".join(result))

if __name__ == "__main__":
    # execute only if run as a script
    main()

Soluzione JavaScript

Esegui ora, live

Mostra il codice sorgente
// Introduction to Random Strings (Rosalind ID: PROB) - soluzione
// JavaScript indipendente, non una trascrizione di problem.py: stessa
// logica (per ciascun GC-content candidato, calcola il logaritmo in
// base 10 della probabilità di generare la stringa data, arrotondato a
// 3 decimali), riscritta in modo idiomatico per JS.
//
// Nota sull'arrotondamento: problem.py usa round(x*1000)/1000, e il
// round() nativo di Python arrotonda "al pari" nei casi di parità esatta
// (banker's rounding), mentre Math.round di JS arrotonda sempre verso
// l'alto. La differenza si manifesta solo per un valore esattamente a
// metà tra due millesimi (x*1000 con parte decimale = 0.5 esatto), un
// caso di misura nulla con numeri log10 in virgola mobile - non
// rilevante in pratica per questo problema.
//
// Nota sul formato numero: come in iev.mjs, un valore intero va
// stampato con ".0" finale per coincidere con print() di un float
// Python.
//
// Contratto: riceve il contenuto testuale di dataset.txt, restituisce
// l'output testuale (stessa forma dell'output Python).
function arrotonda(x) {
  const v = Math.round(x * 1000) / 1000;
  // Normalizza -0 a 0 (Python: round(-0.0001*1000)/1000 può dare -0.0,
  // che print() mostra come "-0.0" - comportamento identico, quindi qui
  // NON normalizziamo -0, lo lasciamo passare così com'è per fedeltà.
  return v;
}

function formatta(v) {
  return Number.isInteger(v) ? v.toFixed(1) : String(v);
}

export default function solve(datasetText) {
  const righe = datasetText.split("\n");
  const s = (righe[0] ?? "").trim();
  const A = (righe[1] ?? "").trim().split(/\s+/).map(Number);

  if (!s || A.length === 0 || A.some((a) => Number.isNaN(a))) {
    throw new Error("Input non valido: attese una stringa di DNA e una lista di GC-content");
  }

  const result = A.map((a) => {
    let tot = 0;
    for (const c of s) {
      tot += Math.log10(c === "C" || c === "G" ? a / 2 : (1 - a) / 2);
    }
    return formatta(arrotonda(tot));
  });

  return `${result.join(" ")}\n`;
}