1
0
Fork 0
mirror of https://github.com/mfocko/blog.git synced 2025-05-06 19:32:58 +02:00

deploy: f0d5e17be72cb5853da24c530d98a5e7bc0072e8

This commit is contained in:
github-actions[bot] 2023-09-07 17:53:23 +00:00
commit 66462a1b7d
538 changed files with 63027 additions and 0 deletions
files
blog/leetcode/sort-matrix-diagonally
ib002

View file

@ -0,0 +1,16 @@
CXX=clang++
CXXFLAGS=-std=c++20 -Wall -Wextra -Werror -g -pedantic
test: matrix-sort
./matrix-sort
matrix-sort: format tidy
$(CXX) $(CXXFLAGS) matrix-sort.cpp -o matrix-sort
format:
clang-format -i -style=webkit *.cpp
tidy:
clang-tidy *.cpp -- $(CXXFLAGS)
.PHONY: matrix-sort format tidy

View file

@ -0,0 +1,229 @@
#include <algorithm>
#include <cassert>
#include <vector>
using matrix = std::vector<std::vector<int>>;
template <typename T>
class diagonal {
using matrix_t = std::vector<std::vector<T>>;
matrix_t& matrix;
std::size_t x;
std::size_t y;
class diagonal_iter {
// we need to keep reference to the matrix itself
std::reference_wrapper<matrix_t> m;
// we need to be able to tell our current position
std::size_t x;
std::size_t y;
public:
using difference_type = std::ptrdiff_t;
using value_type = T;
using pointer = T*;
using reference = T&;
using iterator_category = std::random_access_iterator_tag;
diagonal_iter(matrix_t& matrix,
std::size_t x,
std::size_t y)
: m(matrix)
, x(x)
, y(y)
{
}
bool operator==(const diagonal_iter& rhs) const
{
return x == rhs.x && y == rhs.y && m.get() == rhs.m.get();
}
diagonal_iter& operator++()
{
// we are moving along the diagonal, so we increment both x and y
// at the same time
x++;
y++;
return *this;
}
reference operator*() const { return m.get()[y][x]; }
// exactly opposite to the incrementation
diagonal_iter operator--()
{
x--;
y--;
return *this;
}
// moving n steps back is same as calling decrementation n-times, so
// we can just return a new iterator and subtract n from both
// coordinates in the matrix
diagonal_iter operator-(difference_type n) const
{
return diagonal_iter { m, x - n, y - n };
}
// here we assume that we are given two iterators on the same diagonal
difference_type operator-(const diagonal_iter& rhs) const
{
assert(m.get() == rhs.m.get());
return x - rhs.x;
}
// counterpart of moving n steps backwards
diagonal_iter operator+(difference_type n) const
{
return diagonal_iter { m, x + n, y + n };
}
// we compare the coordinates, and also assume that those 2 iterators are
// lying on the same diagonal
bool operator<(const diagonal_iter& rhs) const
{
assert(m.get() == rhs.m.get());
return x < rhs.x && y < rhs.y;
}
};
public:
diagonal(matrix_t& matrix, std::size_t x, std::size_t y)
: matrix(matrix)
, x(x)
, y(y)
{
}
diagonal_iter begin() const { return diagonal_iter { matrix, x, y }; }
diagonal_iter end() const
{
auto max_x = matrix[y].size();
auto max_y = matrix.size();
// we need to find the distance in which we get out of bounds (either in
// column or row)
auto steps = std::min(max_x - x, max_y - y);
return diagonal_iter { matrix, x + steps, y + steps };
}
};
template <typename T>
class diagonals {
using matrix_t = std::vector<std::vector<T>>;
class diagonals_iter {
matrix_t& m;
std::size_t x;
std::size_t y;
public:
diagonals_iter(matrix_t& matrix, std::size_t x, std::size_t y)
: m(matrix)
, x(x)
, y(y)
{
}
bool operator!=(const diagonals_iter& rhs) const
{
// iterators are not equal if they reference different matrices, or
// their positions differ
return x != rhs.x || y != rhs.y || m != rhs.m;
}
diagonals_iter& operator++()
{
if (y != 0) {
// iterating through diagonals down the first column
y++;
return *this;
}
// iterating the diagonals along the first row
x++;
if (x == m.front().size()) {
// switching to diagonals in the first column
x = 0;
y++;
}
return *this;
}
diagonal<T> operator*() const { return diagonal { m, x, y }; }
};
matrix_t& _matrix;
public:
diagonals(matrix_t& m)
: _matrix(m)
{
}
diagonals_iter begin() { return diagonals_iter { _matrix, 0, 0 }; }
diagonals_iter end() { return diagonals_iter { _matrix, 0, _matrix.size() }; }
};
class Solution {
public:
matrix diagonalSort(matrix mat)
{
// we iterate over the diagonals
for (auto d : diagonals(mat)) {
// and we sort each diagonal
std::sort(d.begin(), d.end());
}
// we take the matrix by copy, so we can sort in-situ and return the copy
// that we sorted
return mat;
}
};
static void test_case_1()
{
// Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
// Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]
Solution s;
assert((s.diagonalSort(std::vector { std::vector { 3, 3, 1, 1 },
std::vector { 2, 2, 1, 2 },
std::vector { 1, 1, 1, 2 } })
== std::vector { std::vector { 1, 1, 1, 1 },
std::vector { 1, 2, 2, 2 },
std::vector { 1, 2, 3, 3 } }));
}
static void test_case_2()
{
// Input: mat =
// [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
// Output:
// [[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]
Solution s;
assert((s.diagonalSort(std::vector { std::vector { 11, 25, 66, 1, 69, 7 },
std::vector { 23, 55, 17, 45, 15, 52 },
std::vector { 75, 31, 36, 44, 58, 8 },
std::vector { 22, 27, 33, 25, 68, 4 },
std::vector { 84, 28, 14, 11, 5, 50 } })
== std::vector { std::vector { 5, 17, 4, 1, 52, 7 },
std::vector { 11, 11, 25, 45, 8, 69 },
std::vector { 14, 23, 25, 44, 58, 15 },
std::vector { 22, 27, 31, 36, 50, 66 },
std::vector { 84, 28, 75, 33, 55, 68 } }));
}
int main()
{
test_case_1();
test_case_2();
return 0;
}

View file

@ -0,0 +1,139 @@
from hypothesis import given, settings
from hypothesis.strategies import integers, lists
import pytest
import itertools
def compare_by_value(pair):
"""
Takes a pair from enumerate in form: `index, value` and returns the value
Args:
pair (Tuple[int, T]): Index and element from the iterator at the index.
Returns:
Element from the pair.
"""
index, value = pair
return value
def maximum(arr, n):
"""
Finds index of maximum element of first n elements in list.
Args:
arr (List): List of values.
n (int): Upper bound of index where to search for maximum (inclusive).
Returns:
Index of a maximum element in `arr[:n]`.
"""
first_n_elements = itertools.islice(enumerate(arr), n)
index, value = max(first_n_elements, key=compare_by_value)
return index
# Precondition: n = |A|
# Loop invariant:
# A[i + 1 : n] is sorted AND
# all elements of A[i + 1 : n] are bigger or equal to the other elements
# Postcondition: A is sorted
def select_sort(arr, n):
"""
Sorts list `arr` using select sort algorithm.
Args:
arr (List): List of values.
n (int): Size of the list.
Returns:
Sorted list `arr`.
"""
assert n == len(arr)
check_loop_invariant(arr, n, n)
for i in reversed(range(1, n)):
j = maximum(arr, i + 1)
arr[i], arr[j] = arr[j], arr[i]
check_loop_invariant(arr, n, i)
return arr
def broken_select_sort(arr, n):
assert n == len(arr)
if not arr:
return
max_value = max(arr)
check_loop_invariant(arr, n, n)
for i in reversed(range(n)):
arr[i] = max_value + i
check_loop_invariant(arr, n, i)
return arr
def check_loop_invariant(arr, n, i):
# A[i + 1 : n] is sorted
for x, y in zip(itertools.islice(arr, i + 1, n), itertools.islice(arr, i + 2, n)):
assert x <= y
# all elements of A[i + 1 : n] are bigger or equal to the other elements
if i + 1 >= n:
# in case there are no elements
return
# otherwise, since the "tail" is sorted, we can assume that it is enough to
# check the other elements to the smallest value of the tail
smallest = arr[i + 1]
for element in itertools.islice(arr, i + 1):
assert smallest >= element
def check_vague_postcondition(original_arr, arr):
if not arr:
return
# check ordering
for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
assert x <= y
def check_postcondition(original_arr, arr):
if not arr:
return
# check ordering
for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
assert x <= y
# get counts from original list
original_counts = {}
for value in original_arr:
original_counts[value] = 1 + original_counts.get(value, 0)
# get counts from resulting list
counts = {}
for value in arr:
counts[value] = 1 + counts.get(value, 0)
# if arr is permutation of original_arr then all counts must be the same
assert counts == original_counts
@given(lists(integers()))
@settings(max_examples=1000)
@pytest.mark.parametrize(
"postcondition", [check_vague_postcondition, check_postcondition]
)
@pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
def test_select_sort(sorting_function, postcondition, numbers):
result = sorting_function(numbers[:], len(numbers))
postcondition(numbers, result)

View file

@ -0,0 +1,17 @@
graph {
a -- c
a -- e
c -- i
c -- b
e -- j
i -- d
b -- h
d -- h
h -- j
}

Binary file not shown.

After

(image error) Size: 26 KiB

Binary file not shown.

After

(image error) Size: 24 KiB

View file

@ -0,0 +1,18 @@
graph {
a -- c
a -- e
c -- i
c -- b
e -- j
e -- h
i -- d
b -- h
d -- h
h -- j
}

Binary file not shown.

After

(image error) Size: 26 KiB

Binary file not shown.

After

(image error) Size: 25 KiB

View file

@ -0,0 +1,13 @@
digraph {
a -> c
a -> e
c -> b
c -> i
e -> j
b -> h
i -> d
}

Binary file not shown.

After

(image error) Size: 16 KiB

Binary file not shown.

After

(image error) Size: 15 KiB

View file

@ -0,0 +1,12 @@
digraph {
a -> c
a -> e
c -> b
c -> i
e -> h
e -> j
i -> d
}

Binary file not shown.

After

(image error) Size: 18 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

View file

@ -0,0 +1,206 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = lf
insert_final_newline = true
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
file_header_template = unset
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:suggestion
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
# Suppression preferences
dotnet_remove_unnecessary_suppression_exclusions = none
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:silent
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_prefer_switch_expression = true:suggestion
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# 'using' directive preferences
csharp_using_directive_placement = inside_namespace:silent
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = false
csharp_new_line_before_members_in_object_initializers = false
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

View file

@ -0,0 +1,448 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*[.json, .xml, .info]
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# Ionide - VsCode extension for F# Support
.ionide/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

View file

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,66 @@
using System.Collections.Generic;
namespace graphs {
class BFS<T> where T : notnull {
private Graph<T> graph;
private Dictionary<T, int> Distance = new Dictionary<T, int>();
private Dictionary<T, T?> Parent = new Dictionary<T, T?>();
private Dictionary<T, Color> State = new Dictionary<T, Color>();
public BFS(Graph<T> graph) {
this.graph = graph;
}
public BFS<T> Run() {
foreach (var vertex in graph.Vertices) {
if (ColorOf(vertex) == Color.White) {
RunFrom(vertex);
}
}
return this;
}
public BFS<T> RunFrom(T start) {
State[start] = Color.Gray;
Distance[start] = 0;
Parent[start] = default(T);
var queue = new Queue<T>();
queue.Enqueue(start);
while (queue.Count > 0) {
var u = queue.Dequeue();
for (var iterator = graph.GetEdgesFrom(u); iterator.MoveNext();) {
var v = iterator.Current;
if (GetOrDefault(State, v, Color.White) == Color.White) {
State[v] = Color.Gray;
Distance[v] = Distance[u] + 1;
Parent[v] = u;
queue.Enqueue(v);
}
}
State[u] = Color.Black;
}
return this;
}
private static V GetOrDefault<U, V>(Dictionary<U, V> flags, U u, V defaultValue)
where U : notnull {
if (flags.TryGetValue(u, out var flag)) {
return flag;
}
return defaultValue;
}
public int DistanceTo(T u) => GetOrDefault(Distance, u, 0);
public T? ParentOf(T u) => GetOrDefault(Parent, u, default(T));
public Color ColorOf(T u) => GetOrDefault(State, u, Color.White);
}
}

View file

@ -0,0 +1,68 @@
using System.Collections.Generic;
namespace graphs {
class DFS<T> where T : notnull {
private Graph<T> graph;
private int time;
private Dictionary<T, int> Discovered = new Dictionary<T, int>();
private Dictionary<T, int> Finished = new Dictionary<T, int>();
private Dictionary<T, Color> State = new Dictionary<T, Color>();
public DFS(Graph<T> graph) {
this.graph = graph;
}
public DFS<T> Run() {
time = 0;
foreach (var vertex in graph.Vertices) {
if (ColorOf(vertex) == Color.White) {
RunFrom(vertex, false);
}
}
return this;
}
public DFS<T> RunFrom(T start, bool reset = true) {
var path = new Stack<(T, IEnumerator<T>)>();
if (reset) {
time = 0;
}
(Discovered[start], State[start]) = (++time, Color.Gray);
path.Push((start, graph.GetEdgesFrom(start)));
while (path.Count > 0) {
var (lastVertex, successors) = path.Peek();
if (!successors.MoveNext()) {
path.Pop();
(Finished[lastVertex], State[lastVertex]) = (++time, Color.Black);
} else if (ColorOf(successors.Current) == Color.White) {
var nextVertex = successors.Current;
(Discovered[nextVertex], State[nextVertex]) = (++time, Color.Gray);
path.Push((nextVertex, graph.GetEdgesFrom(nextVertex)));
}
}
return this;
}
private static V GetOrDefault<U, V>(Dictionary<U, V> flags, U u, V defaultValue)
where U : notnull
where V : notnull {
if (flags.TryGetValue(u, out var flag)) {
return flag;
}
return defaultValue;
}
public int DiscoveredAt(T u) => GetOrDefault(Discovered, u, 0);
public int FinishedAt(T u) => GetOrDefault(Finished, u, 0);
public Color ColorOf(T u) => GetOrDefault(State, u, Color.White);
}
}

View file

@ -0,0 +1,44 @@
using System.Collections.Generic;
using System.Linq;
namespace graphs {
enum Color {
White, Gray, Black
}
class Graph<T> where T : notnull {
private SortedSet<T> vertices = new SortedSet<T>();
private SortedDictionary<T, SortedSet<T>> edges = new SortedDictionary<T, SortedSet<T>>();
public SortedSet<T> Vertices {
get => vertices;
}
public void AddVertex(T u) {
vertices.Add(u);
edges.Add(u, new SortedSet<T>());
}
public void AddEdge(T u, T v) {
if (edges.TryGetValue(u, out var edgesFromU)) {
edgesFromU.Add(v);
}
}
public bool HasEdge(T u, T v) {
if (edges.TryGetValue(u, out var edgesFromU)) {
return edgesFromU.Contains(v);
}
return false;
}
public IEnumerator<T> GetEdgesFrom(T u) {
if (edges.TryGetValue(u, out var edgesFromU)) {
return edgesFromU.GetEnumerator();
}
return Enumerable.Empty<T>().GetEnumerator();
}
}
}

View file

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
namespace graphs {
class Program {
static Graph<string> CreateExampleGraph() {
var vertices = new List<string>() {
"s", "q", "t", "y", "r", "v", "w", "x", "z", "u"
};
var graph = new Graph<string>();
foreach (var vertex in vertices) {
graph.AddVertex(vertex);
}
graph.AddEdge("s", "v");
graph.AddEdge("q", "s");
graph.AddEdge("q", "w");
graph.AddEdge("q", "t");
graph.AddEdge("t", "y");
graph.AddEdge("t", "x");
graph.AddEdge("y", "q");
graph.AddEdge("r", "y");
graph.AddEdge("r", "u");
graph.AddEdge("v", "w");
graph.AddEdge("w", "s");
graph.AddEdge("x", "w");
graph.AddEdge("x", "z");
graph.AddEdge("z", "x");
graph.AddEdge("u", "y");
return graph;
}
static void Main(string[] args) {
var graph = CreateExampleGraph();
var dfsTraversal = new DFS<string>(graph).Run();
foreach (var vertex in graph.Vertices) {
Console.WriteLine($"{vertex}(d: {dfsTraversal.DiscoveredAt(vertex)}, f: {dfsTraversal.FinishedAt(vertex)})");
}
}
}
}

View file

@ -0,0 +1,47 @@
digraph {
"Node(value=3, rank=2)" [label="3"]; #done
"Node(value=1, rank=1)" [label="1"]; #done
"Node(value=4, rank=0)" [label="4"]; #done
"Node(value=7, rank=1)" [label="7", color="red"]; #done
"Node(value=0, rank=0)" [label="0"]; #done
"Node(value=2, rank=0)" [label="2"]; #done
"Node(value=5, rank=1)" [label="5"]; #done
"Node(value=6, rank=0)" [label="6"]; #done
"Node(value=8, rank=0)" [label="8"]; #done
"nil1" [label="nil"]
"nil2" [label="nil"]
"nil3" [label="nil"]
"nil4" [label="nil"]
"nil5" [label="nil"]
"nil6" [label="nil"]
"nil7" [label="nil"]
"nil8" [label="nil"]
"nil9" [label="nil"]
"nil10" [label="nil"]
"nil11" [label="nil"]
"Node(value=9, rank=0)" [label="9", color="red"]; #done
"Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done
"Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done
"Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done
"Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done
"Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done
"Node(value=5, rank=1)" -> "Node(value=7, rank=1)" [color="red"] #done
"Node(value=7, rank=1)" -> "Node(value=6, rank=0)" #done
"Node(value=7, rank=1)" -> "Node(value=8, rank=0)" #done
"Node(value=8, rank=0)" -> "nil1"
"Node(value=8, rank=0)" -> "Node(value=9, rank=0)" [color="red"] #done
"Node(value=0, rank=0)" -> "nil2"
"Node(value=0, rank=0)" -> "nil3"
"Node(value=2, rank=0)" -> "nil4"
"Node(value=2, rank=0)" -> "nil5"
"Node(value=4, rank=0)" -> "nil6"
"Node(value=4, rank=0)" -> "nil7"
"Node(value=6, rank=0)" -> "nil8"
"Node(value=6, rank=0)" -> "nil9"
"Node(value=9, rank=0)" -> "nil10"
"Node(value=9, rank=0)" -> "nil11"
}

Binary file not shown.

After

(image error) Size: 45 KiB

View file

@ -0,0 +1,47 @@
digraph {
"Node(value=3, rank=2)" [label="3⁽³⁾"]; #done
"Node(value=1, rank=1)" [label="1⁽²⁾"]; #done
"Node(value=4, rank=0)" [label="4⁽¹⁾"]; #done
"Node(value=7, rank=1)" [label="7⁽²⁾", color="red"]; #done
"Node(value=0, rank=0)" [label="0⁽¹⁾"]; #done
"Node(value=2, rank=0)" [label="2⁽¹⁾"]; #done
"Node(value=5, rank=1)" [label="5⁽²⁾"]; #done
"Node(value=6, rank=0)" [label="6⁽¹⁾"]; #done
"Node(value=8, rank=0)" [label="8⁽¹⁾"]; #done
"nil1" [label="nil"]
"nil2" [label="nil"]
"nil3" [label="nil"]
"nil4" [label="nil"]
"nil5" [label="nil"]
"nil6" [label="nil"]
"nil7" [label="nil"]
"nil8" [label="nil"]
"nil9" [label="nil"]
"nil10" [label="nil"]
"nil11" [label="nil"]
"Node(value=9, rank=0)" [label="9⁽¹⁾", color="red"]; #done
"Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done
"Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done
"Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done
"Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done
"Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done
"Node(value=5, rank=1)" -> "Node(value=7, rank=1)" [color="red"] #done
"Node(value=7, rank=1)" -> "Node(value=6, rank=0)" #done
"Node(value=7, rank=1)" -> "Node(value=8, rank=0)" #done
"Node(value=8, rank=0)" -> "nil1"
"Node(value=8, rank=0)" -> "Node(value=9, rank=0)" [color="red"] #done
"Node(value=0, rank=0)" -> "nil2"
"Node(value=0, rank=0)" -> "nil3"
"Node(value=2, rank=0)" -> "nil4"
"Node(value=2, rank=0)" -> "nil5"
"Node(value=4, rank=0)" -> "nil6"
"Node(value=4, rank=0)" -> "nil7"
"Node(value=6, rank=0)" -> "nil8"
"Node(value=6, rank=0)" -> "nil9"
"Node(value=9, rank=0)" -> "nil10"
"Node(value=9, rank=0)" -> "nil11"
}

Binary file not shown.

After

(image error) Size: 56 KiB

Binary file not shown.

After

(image error) Size: 53 KiB

Binary file not shown.

After

(image error) Size: 42 KiB

View file

@ -0,0 +1,34 @@
digraph {
"Node(value=3, rank=2)" [label="3"]; #done
"Node(value=1, rank=1)" [label="1", color="red"]; #done
"Node(value=4, rank=0)" [label="4", color="red"]; #done
"Node(value=7, rank=0)" [label="7", color="red"]; #done
"Node(value=0, rank=0)" [label="0"]; #done
"Node(value=2, rank=0)" [label="2"]; #done
"Node(value=5, rank=1)" [label="5"]; #done
"nil2" [label="", color=none]
"nil3" [label="", color=none]
"nil4" [label="", color=none]
"nil5" [label="", color=none]
"nil6" [label="", color=none]
"nil7" [label="", color=none]
"nil8" [label="", color=none]
"nil9" [label="", color=none]
"Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done
"Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done
"Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done
"Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done
"Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done
"Node(value=5, rank=1)" -> "Node(value=7, rank=0)" [color="red"] #done
"Node(value=0, rank=0)" -> "nil2"
"Node(value=0, rank=0)" -> "nil3"
"Node(value=2, rank=0)" -> "nil4"
"Node(value=2, rank=0)" -> "nil5"
"Node(value=4, rank=0)" -> "nil6"
"Node(value=4, rank=0)" -> "nil7"
"Node(value=7, rank=0)" -> "nil8"
"Node(value=7, rank=0)" -> "nil9"
}

Binary file not shown.

After

(image error) Size: 27 KiB

Binary file not shown.

After

(image error) Size: 25 KiB

View file

@ -0,0 +1,40 @@
digraph {
"Node(value=3, rank=2)" [label="3"]; #done
"Node(value=1, rank=1)" [label="1", color="red"]; #done
"Node(value=4, rank=0)" [label="4", color="red"]; #done
"Node(value=7, rank=0)" [label="7", color="red"]; #done
"Node(value=0, rank=0)" [label="0"]; #done
"Node(value=2, rank=0)" [label="2"]; #done
"Node(value=5, rank=1)" [label="5"]; #done
"nil2" [label="", color=none]
"nil3" [label="", color=none]
"nil4" [label="", color=none]
"nil5" [label="", color=none]
"nil6" [label="", color=none]
"nil7" [label="", color=none]
"nil8" [label="", color=none]
"nil9" [label="", color=none]
"nil10" [label="", color=none]
"8" [label="8", color="red"]
"Node(value=3, rank=2)" -> "Node(value=1, rank=1)" #done
"Node(value=1, rank=1)" -> "Node(value=0, rank=0)" #done
"Node(value=1, rank=1)" -> "Node(value=2, rank=0)" #done
"Node(value=3, rank=2)" -> "Node(value=5, rank=1)" #done
"Node(value=5, rank=1)" -> "Node(value=4, rank=0)" #done
"Node(value=5, rank=1)" -> "Node(value=7, rank=0)" [color="red"] #done
"Node(value=0, rank=0)" -> "nil2"
"Node(value=0, rank=0)" -> "nil3"
"Node(value=2, rank=0)" -> "nil4"
"Node(value=2, rank=0)" -> "nil5"
"Node(value=4, rank=0)" -> "nil6"
"Node(value=4, rank=0)" -> "nil7"
"Node(value=7, rank=0)" -> "nil8"
"Node(value=7, rank=0)" -> "8" [color="red"]
"8" -> "nil9"
"8" -> "nil10"
}

Binary file not shown.

After

(image error) Size: 32 KiB

Binary file not shown.

After

(image error) Size: 30 KiB

View file

@ -0,0 +1,7 @@
digraph RBTree {
"140399805603280" [label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
R140399805603280 [label="",color=none]
140399805603280 -> R140399805603280
}

Binary file not shown.

After

(image error) Size: 5 KiB

Binary file not shown.

After

(image error) Size: 4.7 KiB

View file

@ -0,0 +1,11 @@
digraph RBTree {
"140399805603280" [label="12"]
"140399805603280" -> "140399804142928" [color="red"]
"140399804142928" [color=red,label="5"]
L140399804142928 [label="",color=none]
140399804142928 -> L140399804142928
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
R140399805603280 [label="",color=none]
140399805603280 -> R140399805603280
}

Binary file not shown.

After

(image error) Size: 9.5 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

View file

@ -0,0 +1,15 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928" [color="red"]
"140399804142928" [color=red,label="5"]
L140399804142928 [label="",color=none]
140399804142928 -> L140399804142928
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805603280" [color="red"]
"140399805603280" [color=red,label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
R140399805603280 [label="",color=none]
140399805603280 -> R140399805603280
}

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

After

(image error) Size: 11 KiB

View file

@ -0,0 +1,19 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928"
"140399804142928" [label="5"]
L140399804142928 [label="",color=none]
140399804142928 -> L140399804142928
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805603280"
"140399805603280" [label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
"140399805603280" -> "140399805700368" [color="red"]
"140399805700368" [color=red,label="18"]
L140399805700368 [label="",color=none]
140399805700368 -> L140399805700368
R140399805700368 [label="",color=none]
140399805700368 -> R140399805700368
}

Binary file not shown.

After

(image error) Size: 17 KiB

Binary file not shown.

After

(image error) Size: 16 KiB

View file

@ -0,0 +1,23 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928"
"140399804142928" [label="5"]
"140399804142928" -> "140399805700304" [color="red"]
"140399805700304" [color=red,label="2"]
L140399805700304 [label="",color=none]
140399805700304 -> L140399805700304
R140399805700304 [label="",color=none]
140399805700304 -> R140399805700304
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805603280"
"140399805603280" [label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
"140399805603280" -> "140399805700368" [color="red"]
"140399805700368" [color=red,label="18"]
L140399805700368 [label="",color=none]
140399805700368 -> L140399805700368
R140399805700368 [label="",color=none]
140399805700368 -> R140399805700368
}

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 18 KiB

View file

@ -0,0 +1,27 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928"
"140399804142928" [label="5"]
"140399804142928" -> "140399805700304" [color="red"]
"140399805700304" [color=red,label="2"]
L140399805700304 [label="",color=none]
140399805700304 -> L140399805700304
R140399805700304 [label="",color=none]
140399805700304 -> R140399805700304
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805605392"
"140399805605392" [label="15"]
"140399805605392" -> "140399805603280" [color="red"]
"140399805603280" [color=red,label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
R140399805603280 [label="",color=none]
140399805603280 -> R140399805603280
"140399805605392" -> "140399805700368" [color="red"]
"140399805700368" [color=red,label="18"]
L140399805700368 [label="",color=none]
140399805700368 -> L140399805700368
R140399805700368 [label="",color=none]
140399805700368 -> R140399805700368
}

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 18 KiB

View file

@ -0,0 +1,31 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928"
"140399804142928" [label="5"]
"140399804142928" -> "140399805700304" [color="red"]
"140399805700304" [color=red,label="2"]
L140399805700304 [label="",color=none]
140399805700304 -> L140399805700304
R140399805700304 [label="",color=none]
140399805700304 -> R140399805700304
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805605392" [color="red"]
"140399805605392" [color=red,label="15"]
"140399805605392" -> "140399805603280"
"140399805603280" [label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
"140399805603280" -> "140399805605456" [color="red"]
"140399805605456" [color=red,label="13"]
L140399805605456 [label="",color=none]
140399805605456 -> L140399805605456
R140399805605456 [label="",color=none]
140399805605456 -> R140399805605456
"140399805605392" -> "140399805700368"
"140399805700368" [label="18"]
L140399805700368 [label="",color=none]
140399805700368 -> L140399805700368
R140399805700368 [label="",color=none]
140399805700368 -> R140399805700368
}

Binary file not shown.

After

(image error) Size: 28 KiB

Binary file not shown.

After

(image error) Size: 26 KiB

View file

@ -0,0 +1,35 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928"
"140399804142928" [label="5"]
"140399804142928" -> "140399805700304" [color="red"]
"140399805700304" [color=red,label="2"]
L140399805700304 [label="",color=none]
140399805700304 -> L140399805700304
R140399805700304 [label="",color=none]
140399805700304 -> R140399805700304
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805605392" [color="red"]
"140399805605392" [color=red,label="15"]
"140399805605392" -> "140399805603280"
"140399805603280" [label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
"140399805603280" -> "140399805605456" [color="red"]
"140399805605456" [color=red,label="13"]
L140399805605456 [label="",color=none]
140399805605456 -> L140399805605456
R140399805605456 [label="",color=none]
140399805605456 -> R140399805605456
"140399805605392" -> "140399805700368"
"140399805700368" [label="18"]
L140399805700368 [label="",color=none]
140399805700368 -> L140399805700368
"140399805700368" -> "140399805605584" [color="red"]
"140399805605584" [color=red,label="19"]
L140399805605584 [label="",color=none]
140399805605584 -> L140399805605584
R140399805605584 [label="",color=none]
140399805605584 -> R140399805605584
}

Binary file not shown.

After

(image error) Size: 30 KiB

Binary file not shown.

After

(image error) Size: 28 KiB

View file

@ -0,0 +1,39 @@
digraph RBTree {
"140399805910672" [label="9"]
"140399805910672" -> "140399804142928"
"140399804142928" [label="5"]
"140399804142928" -> "140399805700304" [color="red"]
"140399805700304" [color=red,label="2"]
L140399805700304 [label="",color=none]
140399805700304 -> L140399805700304
R140399805700304 [label="",color=none]
140399805700304 -> R140399805700304
R140399804142928 [label="",color=none]
140399804142928 -> R140399804142928
"140399805910672" -> "140399805605392" [color="red"]
"140399805605392" [color=red,label="15"]
"140399805605392" -> "140399805603280"
"140399805603280" [label="12"]
L140399805603280 [label="",color=none]
140399805603280 -> L140399805603280
"140399805603280" -> "140399805605456" [color="red"]
"140399805605456" [color=red,label="13"]
L140399805605456 [label="",color=none]
140399805605456 -> L140399805605456
R140399805605456 [label="",color=none]
140399805605456 -> R140399805605456
"140399805605392" -> "140399805700368"
"140399805700368" [label="18"]
"140399805700368" -> "140399804318928" [color="red"]
"140399804318928" [color=red,label="17"]
L140399804318928 [label="",color=none]
140399804318928 -> L140399804318928
R140399804318928 [label="",color=none]
140399804318928 -> R140399804318928
"140399805700368" -> "140399805605584" [color="red"]
"140399805605584" [color=red,label="19"]
L140399805605584 [label="",color=none]
140399805605584 -> L140399805605584
R140399805605584 [label="",color=none]
140399805605584 -> R140399805605584
}

Binary file not shown.

After

(image error) Size: 33 KiB

Binary file not shown.

After

(image error) Size: 31 KiB

View file

@ -0,0 +1,7 @@
digraph RBTree {
"139660435791312" [color=red,label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
R139660435791312 [label="",color=none]
139660435791312 -> R139660435791312
}

Binary file not shown.

After

(image error) Size: 4.9 KiB

Binary file not shown.

After

(image error) Size: 4.3 KiB

View file

@ -0,0 +1,11 @@
digraph RBTree {
"139660435791312" [label="12"]
"139660435791312" -> "139660436098128" [color="red"]
"139660436098128" [color=red,label="5"]
L139660436098128 [label="",color=none]
139660436098128 -> L139660436098128
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
R139660435791312 [label="",color=none]
139660435791312 -> R139660435791312
}

Binary file not shown.

After

(image error) Size: 9.5 KiB

Binary file not shown.

After

(image error) Size: 8.6 KiB

View file

@ -0,0 +1,15 @@
digraph RBTree {
"139660434247376" [label="9"]
"139660434247376" -> "139660436098128" [color="red"]
"139660436098128" [color=red,label="5"]
L139660436098128 [label="",color=none]
139660436098128 -> L139660436098128
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435791312" [color="red"]
"139660435791312" [color=red,label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
R139660435791312 [label="",color=none]
139660435791312 -> R139660435791312
}

Binary file not shown.

After

(image error) Size: 12 KiB

Binary file not shown.

After

(image error) Size: 11 KiB

View file

@ -0,0 +1,19 @@
digraph RBTree {
"139660434247376" [color=red,label="9"]
"139660434247376" -> "139660436098128"
"139660436098128" [label="5"]
L139660436098128 [label="",color=none]
139660436098128 -> L139660436098128
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435791312"
"139660435791312" [label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
"139660435791312" -> "139660435887824" [color="red"]
"139660435887824" [color=red,label="18"]
L139660435887824 [label="",color=none]
139660435887824 -> L139660435887824
R139660435887824 [label="",color=none]
139660435887824 -> R139660435887824
}

Binary file not shown.

After

(image error) Size: 17 KiB

Binary file not shown.

After

(image error) Size: 15 KiB

View file

@ -0,0 +1,23 @@
digraph RBTree {
"139660434247376" [color=red,label="9"]
"139660434247376" -> "139660436098128"
"139660436098128" [label="5"]
"139660436098128" -> "139660435887760" [color="red"]
"139660435887760" [color=red,label="2"]
L139660435887760 [label="",color=none]
139660435887760 -> L139660435887760
R139660435887760 [label="",color=none]
139660435887760 -> R139660435887760
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435791312"
"139660435791312" [label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
"139660435791312" -> "139660435887824" [color="red"]
"139660435887824" [color=red,label="18"]
L139660435887824 [label="",color=none]
139660435887824 -> L139660435887824
R139660435887824 [label="",color=none]
139660435887824 -> R139660435887824
}

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

View file

@ -0,0 +1,27 @@
digraph RBTree {
"139660434247376" [color=red,label="9"]
"139660434247376" -> "139660436098128"
"139660436098128" [label="5"]
"139660436098128" -> "139660435887760" [color="red"]
"139660435887760" [color=red,label="2"]
L139660435887760 [label="",color=none]
139660435887760 -> L139660435887760
R139660435887760 [label="",color=none]
139660435887760 -> R139660435887760
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435793424"
"139660435793424" [label="15"]
"139660435793424" -> "139660435791312" [color="red"]
"139660435791312" [color=red,label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
R139660435791312 [label="",color=none]
139660435791312 -> R139660435791312
"139660435793424" -> "139660435887824" [color="red"]
"139660435887824" [color=red,label="18"]
L139660435887824 [label="",color=none]
139660435887824 -> L139660435887824
R139660435887824 [label="",color=none]
139660435887824 -> R139660435887824
}

Binary file not shown.

After

(image error) Size: 19 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

View file

@ -0,0 +1,31 @@
digraph RBTree {
"139660434247376" [label="9"]
"139660434247376" -> "139660436098128"
"139660436098128" [label="5"]
"139660436098128" -> "139660435887760" [color="red"]
"139660435887760" [color=red,label="2"]
L139660435887760 [label="",color=none]
139660435887760 -> L139660435887760
R139660435887760 [label="",color=none]
139660435887760 -> R139660435887760
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435793424" [color="red"]
"139660435793424" [color=red,label="15"]
"139660435793424" -> "139660435791312"
"139660435791312" [label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
"139660435791312" -> "139660435793488" [color="red"]
"139660435793488" [color=red,label="13"]
L139660435793488 [label="",color=none]
139660435793488 -> L139660435793488
R139660435793488 [label="",color=none]
139660435793488 -> R139660435793488
"139660435793424" -> "139660435887824"
"139660435887824" [label="18"]
L139660435887824 [label="",color=none]
139660435887824 -> L139660435887824
R139660435887824 [label="",color=none]
139660435887824 -> R139660435887824
}

Binary file not shown.

After

(image error) Size: 28 KiB

Binary file not shown.

After

(image error) Size: 26 KiB

View file

@ -0,0 +1,35 @@
digraph RBTree {
"139660434247376" [label="9"]
"139660434247376" -> "139660436098128"
"139660436098128" [label="5"]
"139660436098128" -> "139660435887760" [color="red"]
"139660435887760" [color=red,label="2"]
L139660435887760 [label="",color=none]
139660435887760 -> L139660435887760
R139660435887760 [label="",color=none]
139660435887760 -> R139660435887760
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435793424" [color="red"]
"139660435793424" [color=red,label="15"]
"139660435793424" -> "139660435791312"
"139660435791312" [label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
"139660435791312" -> "139660435793488" [color="red"]
"139660435793488" [color=red,label="13"]
L139660435793488 [label="",color=none]
139660435793488 -> L139660435793488
R139660435793488 [label="",color=none]
139660435793488 -> R139660435793488
"139660435793424" -> "139660435887824"
"139660435887824" [label="18"]
L139660435887824 [label="",color=none]
139660435887824 -> L139660435887824
"139660435887824" -> "139660435793616" [color="red"]
"139660435793616" [color=red,label="19"]
L139660435793616 [label="",color=none]
139660435793616 -> L139660435793616
R139660435793616 [label="",color=none]
139660435793616 -> R139660435793616
}

Binary file not shown.

After

(image error) Size: 30 KiB

Binary file not shown.

After

(image error) Size: 28 KiB

View file

@ -0,0 +1,39 @@
digraph RBTree {
"139660434247376" [label="9"]
"139660434247376" -> "139660436098128"
"139660436098128" [label="5"]
"139660436098128" -> "139660435887760" [color="red"]
"139660435887760" [color=red,label="2"]
L139660435887760 [label="",color=none]
139660435887760 -> L139660435887760
R139660435887760 [label="",color=none]
139660435887760 -> R139660435887760
R139660436098128 [label="",color=none]
139660436098128 -> R139660436098128
"139660434247376" -> "139660435793424" [color="red"]
"139660435793424" [color=red,label="15"]
"139660435793424" -> "139660435791312"
"139660435791312" [label="12"]
L139660435791312 [label="",color=none]
139660435791312 -> L139660435791312
"139660435791312" -> "139660435793488" [color="red"]
"139660435793488" [color=red,label="13"]
L139660435793488 [label="",color=none]
139660435793488 -> L139660435793488
R139660435793488 [label="",color=none]
139660435793488 -> R139660435793488
"139660435793424" -> "139660435887824"
"139660435887824" [label="18"]
"139660435887824" -> "139660434506512" [color="red"]
"139660434506512" [color=red,label="17"]
L139660434506512 [label="",color=none]
139660434506512 -> L139660434506512
R139660434506512 [label="",color=none]
139660434506512 -> R139660434506512
"139660435887824" -> "139660435793616" [color="red"]
"139660435793616" [color=red,label="19"]
L139660435793616 [label="",color=none]
139660435793616 -> L139660435793616
R139660435793616 [label="",color=none]
139660435793616 -> R139660435793616
}

Binary file not shown.

After

(image error) Size: 33 KiB

Binary file not shown.

After

(image error) Size: 31 KiB

View file

View file

@ -0,0 +1,21 @@
#!/usr/bin/env python3
from itertools import product
def generate_map(template: str, st: int, ave: int) -> str:
return template.format(st=st, ave=ave)
def main():
template = None
with open("maze_skel.kw", "r") as f:
template = f.read()
for st, ave in product(range(1, 7), range(1, 7)):
with open("maze{:03d}.kw".format(st * 6 + ave), "w") as out:
print(generate_map(template, st, ave), file=out)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,791 @@
from dataclasses import dataclass
from enum import Enum, IntEnum
from functools import wraps
from itertools import product
from math import radians, sin, cos
from sys import stderr
import tkinter as tk
from typing import Tuple, Union
def check_before(precondition):
"""
Decorator for running methods before executing a method.
Args:
call_before: Function to be called before executing a method.
Returns:
Parametrized decorator that can be used to wrap method with the
`call_before`.
"""
def parametrized(f):
@wraps(f)
def wrapper(self, *args, **kwargs):
if not precondition(self, *args, **kwargs, fn=f):
return
return f(self, *args, **kwargs)
return wrapper
return parametrized
def after(call_after):
"""
Decorator for running methods after executing a method.
Args:
call_after: Function to be called after executing a method.
Returns:
Parametrized decorator that can be used to wrap method with the
`call_after`.
"""
def parametrized(f):
@wraps(f)
def wrapper(self, *args, **kwargs):
result = f(self, *args, **kwargs)
call_after(self, *args, **kwargs, fn=f)
return result
return wrapper
return parametrized
def skip_for_summary(f):
"""
Decorator used for skipping a function call if the Karel is running
in a summary mode.
"""
@wraps(f)
def wrapper(self, *args, **kwargs):
if self.summary_mode:
return
return f(self, *args, **kwargs)
return wrapper
class Block(IntEnum):
"""
Represents a field in the world of the Robot Karel.
It can be either clear or a wall.
"""
Clear = 0
Wall = -1
# Constants for major angles
EAST, NORTH, WEST, SOUTH = 0, 90, 180, 270
# @dataclass(frozen=True, slots=True)
@dataclass(frozen=True)
class _Direction:
"""
angle: Represents heading of the Robot Karel
"""
angle: int
@property
def vector(self) -> Tuple[int, int]:
"""
Get a direction vector in the current direction the robot is heading.
Returns:
Pair of ints, representing a vector of (dx, dy).
"""
angle, x, y = radians(self.angle), 1, 0
return (
x * round(cos(angle)) - y * round(sin(angle)),
x * round(sin(angle)) + y * round(cos(angle)),
)
@property
def in_world(self) -> str:
"""
Get a character that is being put in the graphical representation of
the Robot Karel.
Returns:
Character to be put in the world.
"""
return {
Direction.East.value: ">",
Direction.North.value: "^",
Direction.West.value: "<",
Direction.South.value: "v",
# Direction.East.value: "⮞",
# Direction.North.value: "⮝",
# Direction.West.value: "⮜",
# Direction.South.value: "⮟",
}[self]
@property
def as_string(self) -> str:
"""
Returns a string with a direction for Tk label.
Returns:
Label of the direction
"""
return {
Direction.East.value: "east",
Direction.North.value: "north",
Direction.West.value: "west",
Direction.South.value: "south",
}[self]
def __add__(self, angle: int) -> "_Direction":
return _Direction((360 + self.angle + angle) % 360)
class Direction(Enum):
"""
Provides constants of directions Karel can face.
"""
East = _Direction(EAST)
North = _Direction(NORTH)
West = _Direction(WEST)
South = _Direction(SOUTH)
class KarelWindow:
def __init__(self, karel: "Karel", scale: int, font: str):
self.size = 32 * scale
self.steps = tk.Label(text=karel.steps, anchor="e")
self.steps.grid(row=0, column=0, sticky="e")
self.last_cmd = tk.Label(text=karel.last_command, anchor="w")
self.last_cmd.grid(row=0, column=1, columnspan=3, sticky="w")
tk.Label(text="CORNER").grid(row=1, column=0)
tk.Label(text="FACING").grid(row=1, column=1)
tk.Label(text="BEEP-BAG").grid(row=1, column=2)
tk.Label(text="BEEP-CORNER").grid(row=1, column=3)
self.corner = tk.Label()
self.corner.grid(row=2, column=0)
self.facing = tk.Label()
self.facing.grid(row=2, column=1)
self.beep_bag = tk.Label()
self.beep_bag.grid(row=2, column=2)
self.beep_corner = tk.Label()
self.beep_corner.grid(row=2, column=3)
self.canvas = tk.Canvas(
width=((karel.world.width + 1) // 2 + 2) * self.size,
height=((karel.world.height + 1) // 2 + 2) * self.size,
background="black",
)
self.canvas.grid(column=0, row=3, columnspan=4)
self.font = f"{font} {int(12 * scale)}"
self.__draw_world(karel.world)
self.render(karel)
def __draw_world(self, world: "World"):
m, n = (world.height + 1) // 2, (world.width + 1) // 2
# NUMBERS
self.canvas.create_text(
self.size // 2,
self.size,
text="ST.",
fill="white",
anchor="s",
font=self.font,
)
for i in range(m):
self.canvas.create_text(
self.size - 8,
(i + 2) * self.size - self.size // 2,
text=(m - i),
anchor="e",
fill="white",
font=self.font,
)
y = ((m + 1) * self.size) + 8
self.canvas.create_text(
(n + 1) * self.size + self.size // 2,
y,
text="AVE.",
fill="white",
anchor="n",
font=self.font,
)
for i in range(n):
self.canvas.create_text(
(i + 2) * self.size - self.size // 2,
y,
text=(i + 1),
anchor="n",
fill="white",
font=self.font,
)
# BORDER
self.canvas.create_rectangle(
self.size,
self.size,
self.size * (n + 1),
self.size * (m + 1),
fill="",
outline="white",
)
for row, col in product(range(world.height), range(world.width)):
block = world.data[row][col]
if row % 2 == 0 and col % 2 == 0:
self.__print_beeper(world, block or ".", row // 2, col // 2)
elif block == Block.Wall:
size = self.size
x = size + col // 2 * size
y = (world.width + 1) // 2 * size - row // 2 * size
if row % 2 == 1 and col % 2 == 0:
self.canvas.create_line(x, y, x + size, y, fill="white")
elif row % 2 == 0:
x += size
self.canvas.create_line(x, y, x, y + size, fill="white")
self.canvas.update()
def __print_beeper(
self, world: "World", beeper: Union[str, int], row: int, column: int
):
self.canvas.create_text(
(column + 1) * self.size + self.size // 2,
((world.height + 1) // 2 - row) * self.size + self.size // 2,
text=str(beeper),
anchor="center",
fill="white",
font=self.font,
)
def render(self, karel: "Karel"):
self.facing["text"] = karel.direction.as_string
self.steps["text"] = karel.steps
self.last_cmd["text"] = karel.last_command
self.corner["text"] = f"({(karel.x + 2) // 2}, {(karel.y + 2) // 2})"
self.beep_bag["text"] = karel.beepers
self.beep_corner["text"] = karel.world.data[karel.y][karel.x]
i, j = (karel.y + 2) // 2, (karel.x + 2) // 2
size = self.size
x, y = j * size, ((karel.world.height + 1) // 2 - i + 1) * size
self.canvas.create_rectangle(
x + 1, y + 1, x + size - 1, y + size - 1, fill="black"
)
karel_on_map = karel.direction.in_world
self.canvas.create_text(
x + size // 2,
y + size // 2,
text=karel_on_map,
font=self.font + " bold",
fill="yellow",
anchor="center",
)
self.canvas.update()
self.canvas.after(karel.step_delay)
def update(self, karel: "Karel", dx: int, dy: int):
block = karel.world.data[karel.y - 2 * dy][karel.x - 2 * dx]
i, j = (karel.y - 2 * dy) // 2, (karel.x - 2 * dx) // 2
x, y = (j + 1) * self.size, (
(karel.world.height + 1) // 2 - i
) * self.size
self.canvas.create_rectangle(
x + 1, y + 1, x + self.size - 1, y + self.size - 1, fill="black"
)
self.__print_beeper(karel.world, block or ".", i, j)
def error(self, karel: "Karel", message: str):
self.render(karel)
self.last_cmd["foreground"] = "red"
self.last_cmd["text"] = f"Error Shutoff! ({message})"
class World:
def __init__(self, width, height, data):
self.width = width * 2 - 1
self.height = height * 2 - 1
self.data = [
[0 for _ in range(self.width)] for _ in range(self.height)
]
if self.width > 30 or self.height > 30:
raise ValueError(
"The given world is greater than the max values of [{}x{}]".format(
30, 30
)
)
self._parse_world(data)
def __parse_wall(self, column, row, orientation, line):
column = column * 2 - 2
row = row * 2 - 2
if column % 2 == 1 or row % 2 == 1:
raise ValueError("Wrong position of the wall")
if orientation == "E":
column += 1
elif orientation == "W":
column -= 1
elif orientation == "N":
row += 1
elif orientation == "S":
row -= 1
else:
raise ValueError(
"Unknown wall orientation '{}' on line {} in world file".format(
orientation, line
)
)
self.data[row][column] = Block.Wall
if column % 2 == 1 and row % 2 == 0:
if row + 1 < self.height:
self.data[row + 1][column] = Block.Wall
if row - 1 >= 0:
self.data[row - 1][column] = Block.Wall
else:
if column + 1 < self.width:
self.data[row][column + 1] = Block.Wall
if column - 1 >= 0:
self.data[row][column - 1] = Block.Wall
def __parse_beepers(self, column, row, count):
column = column * 2 - 2
row = row * 2 - 2
self.data[row][column] = count
def _parse_world(self, world_content):
for i, line in enumerate(world_content, 1):
if not line:
continue
block, column, row, arg = [part.upper() for part in line.split()]
if block == "W":
self.__parse_wall(int(column), int(row), arg, i)
elif block == "B":
self.__parse_beepers(int(column), int(row), int(arg))
else:
raise ValueError(
"Unknown block character '{}' on line {} in world file".format(
block, i
)
)
class Karel:
def __init__(
self, filename, summary_mode=False, scale=1, font="monospace"
):
"""
Turn Karel on.
Args:
filename: Path to the file containing Karel's world and initial
settings.
summary_mode: Disable rendering of the Karel's world in the window.
Defaults to `False`.
scale: Change the scaling factor of the font used to render Karel's
world.
Defaults to `1`.
font: Change the default monospace font that is used to render the
world.
Defaults to `"monospace"`.
"""
self.summary_mode = summary_mode
world_content = None
with open(filename) as world_file:
world_content = world_file.read()
first_line, world = world_content.split("\n", maxsplit=1)
width, height, x, y, direction, beepers = first_line.split()
direction = direction.upper()
self.world = World(int(width), int(height), world.split("\n"))
self.x, self.y = int(x) * 2 - 2, int(y) * 2 - 2
if direction == "S":
self.direction = Direction.South.value
elif direction == "W":
self.direction = Direction.West.value
elif direction == "E":
self.direction = Direction.East.value
elif direction == "N":
self.direction = Direction.North.value
else:
raise ValueError("Unknown Karel's direction")
self.beepers = int(beepers)
self.steps = 0
self.step_delay = 1000
self.is_running = True
self.last_command = "turn_on"
self._initialize_window(scale, font)
@skip_for_summary
def _initialize_window(self, scale, font):
"""
Initializes a window where the Karel is drawn.
"""
self._window = KarelWindow(self, scale, font)
@skip_for_summary
def __update(self, dx, dy):
"""
Updates Karel's position in the window.
Args:
dx: Change along the horizontal axis.
dy: Change along the vertical axis.
"""
self._window.update(self, dx, dy)
def __render(self, fn, *args, **kwargs):
"""
Updates step counter and last command for Karel.
If the robot is not running in a summary mode, then the window
is rendered once again.
"""
if not self.is_running:
return
self.steps += 1
self.last_command = fn.__name__
if not self.summary_mode:
self._window.render(self)
def __error(self, message):
"""
Provides error handling.
Args:
message: Error message to be shown.
"""
if not self.summary_mode:
self._window.error(self, message)
self.is_running = False
else:
print(f"Error Shutoff! ({message})", file=stderr)
@skip_for_summary
def __deinit(self):
tk.mainloop()
def __check_state(self, *args, **kwargs):
"""
Assures that commands are not run while the robot is not running.
Robot is not running when error has occurred.
"""
return self.is_running
@check_before(__check_state)
def beepers_in_bag(self):
"""
Check if there are any beepers in the Karel's bag.
Returns:
`True` if there is at least one beeper in Karel's beeper bag,
`False` otherwise.
"""
return self.beepers > 0
def no_beepers_in_bag(self):
"""
Check if there are no beepers in the Karel's bag.
Returns:
`True` if there is no beeper in Karel's beeper bag, `False` otherwise.
"""
return not self.beepers_in_bag()
@check_before(__check_state)
def front_is_clear(self):
"""
Check if there is no wall in front of Karel.
Returns:
`True` if there is no obstacle in front of Karel, `False` otherwise.
"""
dx, dy = self.direction.vector
if not (
0 <= self.x + dx < self.world.width
and 0 <= self.y + dy < self.world.height
):
return False
if self.world.data[self.y + dy][self.x + dx] == Block.Wall:
return False
return True
def front_is_blocked(self):
"""
Check if there is a wall in front of Karel.
Returns:
`True` if there is an obstacle in front of Karel, `False` otherwise.
"""
return not self.front_is_clear()
@check_before(__check_state)
def __side_is_clear(self, d):
"""
Helper function for determining whether the sides of Karel are clear.
Args:
d: Counterclockwise change in angle of Karel's heading.
Returns:
`True` if the side after applying the `d` counterclokwise turn
is clear, `False` otherwise.
"""
original_direction = self.direction
self.direction = self.direction + d
is_clear = self.front_is_clear()
self.direction = original_direction
return is_clear
def left_is_clear(self):
"""
Check if there is no wall to the left side of Karel.
Returns:
`True` if there is no obstacle to the left side of Karel,
`False` otherwise.
"""
return self.__side_is_clear(90)
def left_is_blocked(self):
"""
Check if there is a wall to the left side of Karel.
Returns:
`True` if there is an obstacle to the left side of Karel,
`False` otherwise.
"""
return not self.left_is_clear()
def right_is_clear(self):
"""
Check if there is no wall to the right side of Karel.
Returns:
`True` if there is no obstacle to the right side of Karel,
`False` otherwise.
"""
return self.__side_is_clear(-90)
def right_is_blocked(self):
"""
Check if there is a wall to the right side of Karel.
Returns:
`True` if there is an obstacle to the right side of Karel,
`False` otherwise.
"""
return not self.right_is_clear()
@check_before(__check_state)
def facing_north(self):
"""
Check if Karel is facing north.
Returns:
`True` if Karel is facing north, `False` otherwise.
"""
return self.direction == Direction.North
def not_facing_north(self):
"""
Check if Karel is »not« facing north.
Returns:
`True` if Karel is »not« facing north, `False` otherwise.
"""
return not self.facing_north()
@check_before(__check_state)
def facing_south(self):
"""
Check if Karel is facing south.
Returns:
`True` if Karel is facing south, `False` otherwise.
"""
return self.direction == Direction.South
def not_facing_south(self):
"""
Check if Karel is »not« facing south.
Returns:
`True` if Karel is »not« facing south, `False` otherwise.
"""
return not self.facing_south()
@check_before(__check_state)
def facing_east(self):
"""
Check if Karel is facing east.
Returns:
`True` if Karel is facing east, `False` otherwise.
"""
return self.direction == Direction.East
def not_facing_east(self):
"""
Check if Karel is »not« facing east.
Returns:
`True` if Karel is »not« facing east, `False` otherwise.
"""
return not self.facing_east()
@check_before(__check_state)
def facing_west(self):
"""
Check if Karel is facing west.
Returns:
`True` if Karel is facing west, `False` otherwise.
"""
return self.direction == Direction.West
def not_facing_west(self):
"""
Check if Karel is »not« facing west.
Returns:
`True` if Karel is »not« facing west, `False` otherwise.
"""
return not self.facing_west()
@check_before(__check_state)
def beepers_present(self):
"""
Check whether Karel stands on a position that has any beepers present.
Returns:
`True` if there is at least one beeper present on the current
position, `False` otherwise.
"""
return self.world.data[self.y][self.x] > 0
def no_beepers_present(self):
"""
Check whether Karel stands on a position that has no beepers present.
Returns:
`True` if there is no beeper present on the current position,
`False` otherwise.
"""
return not self.beepers_present()
@check_before(__check_state)
@after(__render)
def step(self):
"""
Move Karel one position in the direction he's facing.
"""
if not self.front_is_clear():
return self.__error("Can't move this way")
dx, dy = self.direction.vector
self.x += 2 * dx
self.y += 2 * dy
self.__update(dx, dy)
@check_before(__check_state)
@after(__render)
def turn_left(self):
"""
Turn Karel counterclockwise, i.e. left, by 90 degrees.
"""
self.direction = self.direction + 90
@after(__render)
def turn_off(self):
"""
Turn Karel off.
"""
self.is_running = False
self.__deinit()
@check_before(__check_state)
@after(__render)
def put_beeper(self):
"""
Take a beeper from Karel's beeper bag and put on the current position.
"""
if self.beepers <= 0:
return self.__error("Karel has no beeper to put at the corner")
self.world.data[self.y][self.x] += 1
self.beepers -= 1
@check_before(__check_state)
@after(__render)
def pick_beeper(self):
"""
Pick a beeper from the current position and put it into Karel's
beeper bag.
"""
if self.world.data[self.y][self.x] <= 0:
return self.__error("There is no beeper at the corner")
self.world.data[self.y][self.x] -= 1
self.beepers += 1
def set_step_delay(self, delay):
"""
Set delay of a Karel's step.
Args:
delay: Delay of one step in milliseconds.
"""
self.step_delay = delay
def get_step_delay(self):
"""
Get current delay of a Karel's step.
Returns:
Current delay in milliseconds.
"""
return self.step_delay

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 1 1 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 1 2 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 1 3 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 1 4 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 1 5 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 1 6 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 2 1 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

View file

@ -0,0 +1,34 @@
6 6 1 1 E 72
B 2 2 1
W 1 1 E
W 1 3 E
W 1 4 E
W 1 5 N
W 2 1 N
W 2 2 E
W 2 2 N
W 2 4 N
W 2 5 E
W 3 2 N
W 3 3 N
W 3 4 E
W 3 5 E
W 4 1 E
W 4 1 N
W 4 3 E
W 4 3 N
W 4 4 E
W 4 5 E
W 5 2 E
W 5 2 N
W 5 4 E
W 5 5 N
W 5 6 E
W 6 4 N

Some files were not shown because too many files have changed in this diff Show more