MTMS main
Modern Turing Machine Simulator
Loading...
Searching...
No Matches
tape.cpp
Go to the documentation of this file.
1
11#include "tape.hpp"
12
13#include <algorithm>
14#include <ranges>
15
27Tape::Tape(String str) noexcept(false) : head_pos_(0)
28{
29 for (auto [idx, symbol] : std::views::enumerate(str))
30 {
31 // Guard against integer overflow on high-cardinality initialization streams
32 if (idx > static_cast<std::size_t>(std::numeric_limits<int>::max()))
33 {
34 throw std::out_of_range(
35 "Input string length exceeds maximum signed integer capacity of the tape."
36 );
37 }
38 this->cells_[static_cast<int>(idx)] = symbol;
39 }
40}
41
48Symbol Tape::read() const noexcept
49{
50 auto it = this->cells_.find(this->head_pos_);
51 if (it == this->cells_.end())
52 {
53 return Symbol(kBlank);
54 }
55 return it->second;
56}
57
63void Tape::print(std::ostream &os) const noexcept
64{
65 os << "Tape: ";
66
67 // To prevent giant memory printing overhead when head is far away,
68 // visible window is clamped around the actual data limits and head position.
69 int min_idx = this->head_pos_;
70 int max_idx = this->head_pos_;
71
72 // If there is data, expand limits to show the whole string
73 if (!this->cells_.empty())
74 {
75 min_idx = std::min(min_idx, this->cells_.begin()->first);
76 max_idx = std::max(max_idx, this->cells_.rbegin()->first);
77 }
78
79 // Optional safety padding to see at least 2 blank cells around boundaries
80 min_idx = std::min(min_idx, this->head_pos_ - 2);
81 max_idx = std::max(max_idx, this->head_pos_ + 2);
82
83 // Row 1: Render structural tape cell elements sequentially
84 for (int i = min_idx; i <= max_idx; ++i)
85 {
86 auto it = this->cells_.find(i);
87 Symbol s = (it != this->cells_.end()) ? it->second : Symbol(kBlank);
88 os << "| " << s << " ";
89 }
90 os << "|\n";
91
92 // Row 2: Render alignment tracks and drop the head tracking marker (^)
93 os << " "; // Absolute padding to sync with the "Tape: " prefix layout
94 for (int i = min_idx; i <= max_idx; ++i)
95 {
96 if (i == this->head_pos_)
97 {
98 os << " ^ ";
99 break; // Break execution early: markers past the head track are non-constructive
100 }
101 os << " "; // Pad alignment spacing proportional to cell size metrics ("| x ")
102 }
103 os << "\n";
104}
105
111std::ostream &operator<<(std::ostream &os, const Tape &tape) noexcept
112{
113 tape.print(os);
114 return os;
115}
Represents a formal string (w) consisting of a finite sequence of Symbols.
Definition string.hpp:29
Represents a single symbol on the Turing Machine's tape.
Definition symbol.hpp:30
void print(std::ostream &os=std::cout) const noexcept
Prints the symbol's character representation to the specified output stream.
Definition symbol.hpp:72
Simulates the bilateral infinite tape layout of a Turing Machine.
Definition tape.hpp:30
std::map< int, Symbol > cells_
Memory cells mapping coordinates to written Symbols.
Definition tape.hpp:106
void print(std::ostream &os=std::cout) const noexcept
Renders the active layout of the tape and the head tracking to an output stream.
Definition tape.cpp:63
Tape() noexcept
Default constructor.
Definition tape.hpp:35
Symbol read() const noexcept
Reads the symbol currently located under the tape head.
Definition tape.cpp:48
int head_pos_
Current mathematical index coordinate of the head.
Definition tape.hpp:105
constexpr char kBlank
Representation of the default blank symbol used to fill the Turing Machine's tape.
Definition symbol.hpp:20
std::ostream & operator<<(std::ostream &os, const Tape &tape) noexcept
Global stream insertion operator overload.
Definition tape.cpp:111
Tape class representing the infinite memory structure of the Turing Machine.