Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
j4james committed Jun 6, 2019
0 parents commit 7fcf5cd
Show file tree
Hide file tree
Showing 22 changed files with 1,303 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BraceWrapping:
AfterFunction: true
BreakBeforeBraces: Custom
ColumnLimit: 0
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
- Regex: '.*'
Priority: 1
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
PointerAlignment: Left
SpaceAfterCStyleCast: true
SpacesBeforeTrailingComments: 2
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 4
tab_width = 8
trim_trailing_whitespace = true
insert_final_newline = true

5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.cpp text
*.h text
*.txt text
*.md text
.* text
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vs/

30 changes: 30 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.10)
project(big)

set(
SRC_FILES
src/main.cpp
src/big.h
src/big.arithmetic.h
src/big.cache.h
src/big.expression.h
src/big.literals.h
src/big.negation.h
src/big.operands.h
src/big.operations.h
src/big.options.h
src/big.powers.h
src/big.strategy.h
src/big.utils.h
)

set(
DOC_FILES
README.md
MANUAL.md
LICENSE.txt
)

add_executable(big ${SRC_FILES} ${DOC_FILES})
set_target_properties(big PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED On)
source_group("Doc Files" FILES ${DOC_FILES})
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2019 James Holderness

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
76 changes: 76 additions & 0 deletions MANUAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
BIG(1)
------

#### NAME ####

**big** - Befunge integer generator

#### SYNOPSIS ####

big [options...] <number>
big [options...] <number>..<number>

#### DESCRIPTION ####

The Befunge Integer Generator attempts to generate the shortest possible
Befunge expression that will evaluate to a given number.

It can accept a list of individual numbers (e.g. `5 10 15`) or a number range
(e.g. `10..20`). The input is interpreted as decimal by default, but can be
marked as hexadecimal with an `h` suffix (e.g. `7Fh`).

The following options are also available:

| Option | Description |
|---------------|-------------------------------------------------------------|
| -h, --help | Display this help |
| -f, --fast | Prefer faster results over shorter string literals |
| -n, --numeric | Only allow numeric expressions (no strings) |
| -s, --safe | Disallow unsafe characters: SPACE, ';' and '@' |
| -a, --all | Show all variants matching the minimal length |
| --93 | Befunge-93 compatible expressions (default) |
| --98 | Befunge-98 compatible expressions |

By default the generator prefers expressions with shorter string literals,
since those can more easily be split when having to change direction in a
piece of Befunge code. If the **fast** option is set, though, the generator
will just return the first minimal-length result it finds.

If the **numeric** option is set, the generator will avoid strings literals
altogether, which can be useful in certain restricted-source scenarios.

The **safe** option will prevent the use of a few characters that are known
to have portability problems. This include the SPACE character (which some
interpreters drop), the `;` character (which can be misinterpreted as a jump
operation), and the `@` character (which can force some implementation to
terminate).

If the **all** option is set, the generator will return every minimal-length
expression it can find for a particular number.

By default, the generated expression are compatible with Befunge-93, but if
the **98** option is set, they may use language extensions specific to the
Befunge-98 standard. This includes hex literals, as well as the one-shot
string mode. Technically these extensions are also supported by Befunge-96
and -97, but those versions of the language are rarely used anymore.

#### LIMITATIONS ####

In most cases the generated expressions should be optimal, but that can't
always be guaranteed. The **numeric** mode in particular is known to produce
results that are less than optimal for some values.

Even when optimal, the **all** option will not be guaranteed to return every
possible expression that matches the best length. There are a limited set of
strategies used by the generator, so those are obviously the only variants
that will be returned.

#### AUTHOR ####

Written by James Holderness.

#### SEE ALSO ####

[BefunRep](https://github.com/Mikescher/BefunRep),
[Fungify](https://deewiant.iki.fi/projects/fungify),
[Befour](https://codegolf.stackexchange.com/a/78561)
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
BIG: Befunge Integer Generator
==============================

The Befunge Integer Generator attempts to generate the shortest possible
[Befunge] expression that will evaluate to a given number.

There is only a small range of numbers that can be represented with literal
values in Befunge, so in most cases you'll have to calculate the number you
need using an arithmetic expression. Determining the optimal version of that
expression is a non-trivial task, but that's where this app can help.

[Befunge]: https://github.com/catseye/Befunge-93


Usage
-----

Simply pass the number you want to generate as a command-line argument, e.g.:

$ big 31337
";"3*:*8+

For more advanced queries, and detailed documentation of the available options,
see the [MANUAL] file.

[MANUAL]: MANUAL.md


Download
--------

The latest binaries can be downloaded from GitHub at the following url:

https://github.com/j4james/big/releases/latest



Build Instructions
------------------

If you want to build the program yourself, you'll need [CMake] version 3.10
or later and a C++ compiler supporting C++17 or later (tested with [GCC] 7.4,
[Clang] 6.0.0, and [Visual Studio] 2017 v15.9.12).

The process is slightly different depending on whether you're using a single
configuration generator (like a Makefile) or a multi configuration generator
(like Visual Studio or Xcode).

**Single configuration generators**

1. Download or clone the source:
`git clone https://github.com/j4james/big.git`

2. Change into the build directory:
`cd big/build`

3. Generate the project for your preferred build type:
`cmake -D CMAKE_BUILD_TYPE=Release ..`

4. Start the build:
`cmake --build .`

**Multi configuration generators**

1. Download or clone the source:
`git clone https://github.com/j4james/big.git`

2. Change into the build directory:
`cd big/build`

3. Generate the build project (supporting all build types):
`cmake ..`

4. Start the build for your preferred build type:
`cmake --build . --config Release`

[CMake]: https://cmake.org/
[GCC]: https://gcc.gnu.org/
[Clang]: https://clang.llvm.org/
[Visual Studio]: https://visualstudio.microsoft.com/


License
-------

The BIG source code and binaries are released under the MIT License. See the
[LICENSE] file for full license details.

[LICENSE]: LICENSE.txt
2 changes: 2 additions & 0 deletions build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
88 changes: 88 additions & 0 deletions src/big.arithmetic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// BIG Befunge Integer Generator
// Copyright (c) 2019 James Holderness
// Distributed under the MIT License

#pragma once

#include "big.expression.h"
#include "big.operands.h"
#include "big.utils.h"

#include <optional>

namespace big {

template <typename traits>
struct arithmetic_operation {
static constexpr auto length = utils::symbol_length(traits::symbol) + 1;
static constexpr auto min_target = 10;
static constexpr auto min_rhs = traits::min_rhs;
static constexpr auto operand_order = traits::operand_order;

static std::optional<int> calculate_lhs(int target, int rhs) noexcept
{
return traits::calculate_lhs(target, rhs);
}

static void build_expression(char rhs_symbol, bool rhs_quoted, expression& container) noexcept
{
container.insert_suffix(traits::symbol);
if (rhs_quoted)
container.insert_into_string(rhs_symbol);
else
container.insert_suffix(rhs_symbol);
}
};


using multiplication = arithmetic_operation<struct multiplication_traits>;
struct multiplication_traits {
static constexpr auto symbol = '*';
static constexpr auto min_rhs = 2;
static constexpr auto operand_order = largest_first;
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
{
if (target % rhs == 0)
return target / rhs;
else
return std::nullopt;
}
};


using addition = arithmetic_operation<struct addition_traits>;
struct addition_traits {
static constexpr auto symbol = '+';
static constexpr auto min_rhs = 1;
static constexpr auto operand_order = largest_first;
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
{
if (target > rhs)
return target - rhs;
else
return std::nullopt;
}
};


using subtraction = arithmetic_operation<struct subtraction_traits>;
struct subtraction_traits {
static constexpr auto symbol = '-';
static constexpr auto min_rhs = 1;
static constexpr auto operand_order = smallest_first;
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
{
if (target <= 0x7FFFFFFF - rhs)
return target + rhs;
else
return std::nullopt;
}
};


using reverse_subtraction = arithmetic_operation<struct reverse_subtraction_traits>;
struct reverse_subtraction_traits : subtraction_traits {
static constexpr auto symbol = "\\-";
};

} // namespace big
40 changes: 40 additions & 0 deletions src/big.cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// BIG Befunge Integer Generator
// Copyright (c) 2019 James Holderness
// Distributed under the MIT License

#pragma once

#include <unordered_map>

namespace big {

class cache {
public:
using size_type = int16_t;

struct reference {
size_type& value;
bool is_valid;
};

reference lookup(int target, bool using_quotes, int space)
{
auto& entries = using_quotes ? quoted_entries : unquoted_entries;
auto& entry = entries[target];
const auto entry_valid = entry.value != 0 && entry.space >= space;
if (!entry_valid) entry.space = space;
return {entry.value, entry_valid};
}

private:
struct map_entry {
size_type value;
size_type space;
};
using map = std::unordered_map<int, map_entry>;

map quoted_entries;
map unquoted_entries;
};

} // namespace big
Loading

0 comments on commit 7fcf5cd

Please sign in to comment.