Skip to content

Commit

Permalink
desafio 10 por @flafmg (#1148)
Browse files Browse the repository at this point in the history
* desafio 10 por @flafmg

* Correçao: espaçamento em final de linha

* Aplica modificações sugeridas
  • Loading branch information
flafmg authored Nov 22, 2024
1 parent b0e143f commit 13f2b3f
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 0 deletions.
1 change: 1 addition & 0 deletions desafio-10/flafmg/csharp/.valid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1914c162d0565542762c998011aa08ebc
24 changes: 24 additions & 0 deletions desafio-10/flafmg/csharp/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

# Desafio 10 - Turing Machine!

Este programa simula uma turing machine usando C#. feito por @flafmg

## pré-requisitos

- [.NET SDK 8.0](https://dotnet.microsoft.com/download/dotnet/8.0)

## compilar e executar

1. **Clone o repositório:**
```bash
git clone https://github.com/flafmg/op-desafios.git
cd op-desafios/desafio-10/flafmg/csharp
```
2. **Compile o projeto:**
```bash
dotnet build
```
3. **execute o programa**
```bash
dotnet run
```
164 changes: 164 additions & 0 deletions desafio-10/flafmg/csharp/program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// .--------------------------.
// | desafio 10 por @flafmg. |
// `--------------------------´

public class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("Forneça o arquivo de dados como argumento.");
return;
}

var dataFilePath = args[0];
if (!File.Exists(dataFilePath))
{
Console.WriteLine($"Arquivo de dados não encontrado: {dataFilePath}");
return;
}

var dataLines = File.ReadAllLines(dataFilePath);
var results = new List<string>();

foreach (var line in dataLines)
{
if (string.IsNullOrWhiteSpace(line)) continue;

var parts = line.Split(',');
if (parts.Length != 2)
{
Console.WriteLine($"Linha inválida no arquivo de dados: {line}");
continue;
}

var ruleFilePath = Path.Combine(Path.GetDirectoryName(dataFilePath) ?? string.Empty, parts[0].Trim());
var ruleFileName = Path.GetFileName(parts[0].Trim());
var input = parts[1].Trim();

if (!File.Exists(ruleFilePath))
{
Console.WriteLine($"arquivo de regras não encontrado: {ruleFilePath}");
continue;
}

var rules = ReadRules(ruleFilePath);
if (rules == null)
{
Console.WriteLine($"erro ao ler o arquivo de regras: {ruleFilePath}");
continue;
}

var output = ExecuteTuringMachine(rules, input, ruleFileName);
results.Add($"{ruleFileName},{input},{output}");
}

foreach (var result in results)
{
Console.WriteLine(result);
}
}

static List<Rule> ReadRules(string ruleFilePath)
{
try
{
var lines = File.ReadAllLines(ruleFilePath);
var rules = new List<Rule>();

foreach (var line in lines)
{
var trimmedLine = line.Split(';')[0].Trim();
if (string.IsNullOrWhiteSpace(trimmedLine)) continue;

var parts = trimmedLine.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 5)
{
throw new FormatException("regra com formato invalido");
}

rules.Add(new Rule(parts[0], parts[1], parts[2], parts[3], parts[4]));
}

return rules;
}
catch (Exception ex)
{
Console.WriteLine($"erro ao ler regras: {ex.Message}");
return null;
}
}

static string ExecuteTuringMachine(List<Rule> rules, string tape, string ruleFileName)
{
var tapeList = new List<char>(tape.ToCharArray());
var head = 0;
var state = "0";

while (true)
{
if (head < 0)
{
tapeList.Insert(0, ' ');
head = 0;
}
else if (head >= tapeList.Count)
{
tapeList.Add(' ');
}

var currentSymbol = tapeList[head];
var applicableRule = GetApplicableRule(rules, state, currentSymbol);

if (applicableRule == null)
{
return "ERR";
}

#if DEBUG
Console.WriteLine($"Arquivo: {ruleFileName}, Estado: {state}, Símbolo: {currentSymbol}, Regra: {applicableRule}");
#endif

if (applicableRule.NewSymbol != "*")
{
tapeList[head] = applicableRule.NewSymbol == "_" ? ' ' : applicableRule.NewSymbol[0];
}

head += applicableRule.Direction switch //simplificação dos ifs
{
"l" => -1,
"r" => 1,
"*" => 0,
_ => throw new InvalidOperationException("direção de movimento inesistente")
};

state = applicableRule.NewState;

if (state.StartsWith("halt"))
{
break;
}
}

return new string(tapeList.ToArray()).Trim();
}

static Rule? GetApplicableRule(List<Rule> rules, string currentState, char currentSymbol) //simplificação das rules
{
return rules.Find(r =>
r.CurrentState == currentState &&
(r.CurrentSymbol == currentSymbol.ToString() || (r.CurrentSymbol == "_" && currentSymbol == ' ')))
?? rules.Find(r =>
r.CurrentState == "*" &&
(r.CurrentSymbol == currentSymbol.ToString() || (r.CurrentSymbol == "_" && currentSymbol == ' ')))
?? rules.Find(r =>
r.CurrentState == currentState &&
r.CurrentSymbol == "*")
?? rules.Find(r =>
r.CurrentState == "*" &&
r.CurrentSymbol == "*");
}
}

public record Rule(string CurrentState, string CurrentSymbol, string NewSymbol, string Direction, string NewState);
10 changes: 10 additions & 0 deletions desafio-10/flafmg/csharp/program.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

0 comments on commit 13f2b3f

Please sign in to comment.