using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Knjiznica;
namespace StevilskeDomine
{
class Program
{
/// <summary>
/// Iz tabele ducatih števil najde najdaljšo verigo in vrne niz z rešitvijo
/// </summary>
/// <param name="tab">Tabela števil</param>
/// <returns>Vrne najdaljše zaporedje netujih števil</returns>
static string StevilskeDomine(int[] tab)
/*V tekstovni datoteki je zapisanih ducat pozitivnih celih števil. Poišči najdaljša zaporedje, ki ga lahko
sestavimo iz teh števil. Dve števili v zaporedju sta lahko sosednji, če si nista tuji. Tako sta lahko
zaporedni števili 12 in 18, ne pa tudi 15 in 22.*/
{
if (tab.Length == 0)
throw new Exception("Tabela je prazna");
// seznama, ki hranita trenutno najboljšo kačo in trenutno kačo
List<int> trenutni = new List<int>() { };
List<int> najboljsi = new List<int>() { };
for (int i = 0; i < tab.Length; i++)
{
// element tabele damo v seznam trenutne kače
trenutni.Add(tab[i]);
// od zadnjega elementa, ki smo ga dali v trenutni seznam pogledamo nadaljne elemente
for (int j = i + 1; j < tab.Length; j++)
{
// če sta zadnji v trenutnem in tekoči element tabele tuji, damo tekoči element na zadnje mesto trenutnega rezultata
if (!Knj.TujiStevili(tab[j], trenutni[trenutni.Count - 1]))
trenutni.Add(tab[j]);
}
// če je trenutna kača daljša od do sedaj najboljše, potem jo damo v seznam najboljšij
if (trenutni.Count > najboljsi.Count)
{
najboljsi.Clear();
najboljsi.AddRange(trenutni);
}
// trenutni seznam izpraznemo
trenutni.Clear();
}
// iz seznama naredimo niz, ki ga potem vrnemo
string niz = "";
foreach (int el in najboljsi)
{
if (niz.Length > 0)
niz += ", ";
niz += el;
}
return niz;
}
/// <summary>
/// Iz datoteke prebere ducat števil in vrne niz najdaljše verige ne tujih si števil
/// </summary>
/// <param name="imeDatoteke">Ime datoteke, v kateri je shranjenih 12 celih pozitivnih števil</param>
/// <returns>Vrne niz, najdaljšo verigo ne tujih si števil</returns>
static string StevilskeDomine(string imeDatoteke)
{
// preberi iz datoteke
// tabela, kamor bomo iz datoteke shranili stevila
int[] tab = new int[12];
// preverimo, ce datoteka obstaja
if (!File.Exists(imeDatoteke)) throw new Exception("Ta datoteka ne obstaja");
StreamReader branje = File.OpenText(imeDatoteke);
string vrstica; // prebrana vrstica datoteke
string[] vrs; // tabela ločenih podatkov v vrstici
int stevilo = 0; // ko poskušamo število pretvoriti iz niza
int indeks = 0; // indeks elementa v tabeli (po vrsti)
while ((vrstica = branje.ReadLine()) != null)
{
vrs = vrstica.Split(); // ločimo podatke
foreach (string element in vrs)
{
// če je prazen
if (element.Length == 0)
continue;
// če je element število, ga dodamo v tabelo in povečamo indeks
else if (int.TryParse(element, out stevilo))
{
if (indeks >= 12)
throw new Exception("Preveč podatkov na datoteki");
tab[indeks] = stevilo;
indeks++;
}
else
throw new Exception("Napačni podatki v datoteki");
}
}
if (indeks != 12)
throw new Exception("Premalo podatkov na datoteki");
// zapri datoteko
branje.Close();
return StevilskeDomine(tab);
}
public static Random generator = new Random();
static void Main(string[] args)
{
#region Nakljucni podatki
Console.WriteLine("************ Naključna tabela ************");
Console.WriteLine();
int[] nak = new int[12];
int st;
for (int i = 0; i < 12; i++)
{
st = generator.Next(1, 50);
nak[i] = st;
}
Console.Write("Naključna tabela : ");
Console.WriteLine(Knj.TabelaVNiz(nak));
Console.WriteLine();
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(nak));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
#endregion
Console.WriteLine();
Console.WriteLine("************ Še nekaj tabel ************");
Console.WriteLine();
#region Primeri nekaj tabel
// ce so vsi elementi enaki
int[] tab1 = new int[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
Console.WriteLine("Tabela : " + Knj.TabelaVNiz(tab1));
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(tab1));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
// ce je v seznamu 1
int[] tab2 = new int[] { 1, 15, 21, 7, 1, 2, 13, 18, 9, 3, 7, 5 };
Console.WriteLine("Tabela : " + Knj.TabelaVNiz(tab2));
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(tab2));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
// ce so sama tuja stevila
int[] tab3 = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 };
Console.WriteLine("Tabela : " + Knj.TabelaVNiz(tab3));
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(tab3));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
// izmišljen primer
int[] tab4 = new int[] { 12, 32, 23, 12, 4, 7, 56, 9, 3, 10, 3, 5 };
Console.WriteLine("Tabela : " + Knj.TabelaVNiz(tab4));
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(tab4));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
// Prazna tabela
int[] tab5 = new int[] { };
Console.WriteLine("Tabela : " + Knj.TabelaVNiz(tab5));
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(tab5));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
#endregion
Console.WriteLine();
Console.WriteLine("************ Datoteke ************");
Console.WriteLine();
#region Napake na datotekah
Console.WriteLine("Prva datoteka");
try
{
string dat1 = Environment.CurrentDirectory + "\\d1.txt";
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(dat1));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
// premalo podatkov
Console.WriteLine("Druga datoteka");
try
{
string dat2 = Environment.CurrentDirectory + "\\d2.txt";
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(dat2));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
// preveč podatkov
Console.WriteLine("Tretja datoteka");
try
{
string dat3 = Environment.CurrentDirectory + "\\d3.txt";
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(dat3));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
//napačni podatki
Console.WriteLine("Četrta datoteka");
try
{
string dat4 = Environment.CurrentDirectory + "\\d4.txt";
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(dat4));
}
catch (Exception e)
{
Console.WriteLine("Napaka: " + e.Message);
}
Console.WriteLine();
#endregion
Console.WriteLine();
Console.WriteLine("************ Vnos datoteke ************");
Console.WriteLine();
#region Primer v navodilih - vnašanje datoteke
Console.Write("Vnesi ime datoteke : ");
string dat = Console.ReadLine();
try
{
Console.WriteLine("Najdaljšo kačo sestavljajo števila : " + StevilskeDomine(dat));
}
catch (Exception ee)
{
Console.WriteLine(ee.Message);
}
#endregion
Console.ReadKey();
}
}
}
Pomožne funkcije
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Knjiznica
{
public class Knj
{
/// <summary>
/// Vrne najvecji skupni delitelj stevil a in b
/// </summary>
/// <param name="a">prvo stevilo</param>
/// <param name="b">drugo stevilo</param>
/// <returns></returns>
public static int GCD(int a, int b)
/* Evklidov algoritem*/
{
// a mora biti vecji ali enak b
if (a < b)
{
int pom = a;
a = b;
b = pom;
}
if (b == 0) return a;
return GCD(b, a % b);
}
/// <summary>
/// Vrne true, ce sta stevili a in b tuji, sicer vrne false
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool TujiStevili(int a, int b)
/*najvecji skupni delitelj je 1*/
{
return GCD(a, b)==1;
}
/// <summary>
/// Iz tabele celih števil naredi in vrne niz
/// </summary>
/// <param name="tab">Tabela celih števil</param>
/// <returns>Vrne tabelo izpisano v nizu</returns>
public static string TabelaVNiz(int[] tab)
{
string niz = "";
for (int i = 0; i < tab.Length; i++)
{
if (i != 0)
niz += ", ";
niz += tab[i].ToString();
}
return niz;
}
}
}