Skip to content

Commit 7fcf5cd

Browse files
committed
Initial commit
0 parents  commit 7fcf5cd

22 files changed

+1303
-0
lines changed

.clang-format

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Language: Cpp
2+
AccessModifierOffset: -4
3+
AlignAfterOpenBracket: DontAlign
4+
AllowShortCaseLabelsOnASingleLine: true
5+
AllowShortIfStatementsOnASingleLine: true
6+
AlwaysBreakTemplateDeclarations: Yes
7+
BraceWrapping:
8+
AfterFunction: true
9+
BreakBeforeBraces: Custom
10+
ColumnLimit: 0
11+
IncludeBlocks: Regroup
12+
IncludeCategories:
13+
- Regex: '^<.*\.h>'
14+
Priority: 2
15+
- Regex: '^<.*'
16+
Priority: 3
17+
- Regex: '.*'
18+
Priority: 1
19+
IndentCaseLabels: true
20+
IndentWidth: 4
21+
KeepEmptyLinesAtTheStartOfBlocks: false
22+
MaxEmptyLinesToKeep: 2
23+
NamespaceIndentation: All
24+
PointerAlignment: Left
25+
SpaceAfterCStyleCast: true
26+
SpacesBeforeTrailingComments: 2

.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = space
6+
indent_size = 4
7+
tab_width = 8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+

.gitattributes

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.cpp text
2+
*.h text
3+
*.txt text
4+
*.md text
5+
.* text

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.vs/
2+

CMakeLists.txt

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
project(big)
3+
4+
set(
5+
SRC_FILES
6+
src/main.cpp
7+
src/big.h
8+
src/big.arithmetic.h
9+
src/big.cache.h
10+
src/big.expression.h
11+
src/big.literals.h
12+
src/big.negation.h
13+
src/big.operands.h
14+
src/big.operations.h
15+
src/big.options.h
16+
src/big.powers.h
17+
src/big.strategy.h
18+
src/big.utils.h
19+
)
20+
21+
set(
22+
DOC_FILES
23+
README.md
24+
MANUAL.md
25+
LICENSE.txt
26+
)
27+
28+
add_executable(big ${SRC_FILES} ${DOC_FILES})
29+
set_target_properties(big PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED On)
30+
source_group("Doc Files" FILES ${DOC_FILES})

LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 James Holderness
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

MANUAL.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
BIG(1)
2+
------
3+
4+
#### NAME ####
5+
6+
**big** - Befunge integer generator
7+
8+
#### SYNOPSIS ####
9+
10+
big [options...] <number>
11+
big [options...] <number>..<number>
12+
13+
#### DESCRIPTION ####
14+
15+
The Befunge Integer Generator attempts to generate the shortest possible
16+
Befunge expression that will evaluate to a given number.
17+
18+
It can accept a list of individual numbers (e.g. `5 10 15`) or a number range
19+
(e.g. `10..20`). The input is interpreted as decimal by default, but can be
20+
marked as hexadecimal with an `h` suffix (e.g. `7Fh`).
21+
22+
The following options are also available:
23+
24+
| Option | Description |
25+
|---------------|-------------------------------------------------------------|
26+
| -h, --help | Display this help |
27+
| -f, --fast | Prefer faster results over shorter string literals |
28+
| -n, --numeric | Only allow numeric expressions (no strings) |
29+
| -s, --safe | Disallow unsafe characters: SPACE, ';' and '@' |
30+
| -a, --all | Show all variants matching the minimal length |
31+
| --93 | Befunge-93 compatible expressions (default) |
32+
| --98 | Befunge-98 compatible expressions |
33+
34+
By default the generator prefers expressions with shorter string literals,
35+
since those can more easily be split when having to change direction in a
36+
piece of Befunge code. If the **fast** option is set, though, the generator
37+
will just return the first minimal-length result it finds.
38+
39+
If the **numeric** option is set, the generator will avoid strings literals
40+
altogether, which can be useful in certain restricted-source scenarios.
41+
42+
The **safe** option will prevent the use of a few characters that are known
43+
to have portability problems. This include the SPACE character (which some
44+
interpreters drop), the `;` character (which can be misinterpreted as a jump
45+
operation), and the `@` character (which can force some implementation to
46+
terminate).
47+
48+
If the **all** option is set, the generator will return every minimal-length
49+
expression it can find for a particular number.
50+
51+
By default, the generated expression are compatible with Befunge-93, but if
52+
the **98** option is set, they may use language extensions specific to the
53+
Befunge-98 standard. This includes hex literals, as well as the one-shot
54+
string mode. Technically these extensions are also supported by Befunge-96
55+
and -97, but those versions of the language are rarely used anymore.
56+
57+
#### LIMITATIONS ####
58+
59+
In most cases the generated expressions should be optimal, but that can't
60+
always be guaranteed. The **numeric** mode in particular is known to produce
61+
results that are less than optimal for some values.
62+
63+
Even when optimal, the **all** option will not be guaranteed to return every
64+
possible expression that matches the best length. There are a limited set of
65+
strategies used by the generator, so those are obviously the only variants
66+
that will be returned.
67+
68+
#### AUTHOR ####
69+
70+
Written by James Holderness.
71+
72+
#### SEE ALSO ####
73+
74+
[BefunRep](https://github.com/Mikescher/BefunRep),
75+
[Fungify](https://deewiant.iki.fi/projects/fungify),
76+
[Befour](https://codegolf.stackexchange.com/a/78561)

README.md

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
BIG: Befunge Integer Generator
2+
==============================
3+
4+
The Befunge Integer Generator attempts to generate the shortest possible
5+
[Befunge] expression that will evaluate to a given number.
6+
7+
There is only a small range of numbers that can be represented with literal
8+
values in Befunge, so in most cases you'll have to calculate the number you
9+
need using an arithmetic expression. Determining the optimal version of that
10+
expression is a non-trivial task, but that's where this app can help.
11+
12+
[Befunge]: https://github.com/catseye/Befunge-93
13+
14+
15+
Usage
16+
-----
17+
18+
Simply pass the number you want to generate as a command-line argument, e.g.:
19+
20+
$ big 31337
21+
";"3*:*8+
22+
23+
For more advanced queries, and detailed documentation of the available options,
24+
see the [MANUAL] file.
25+
26+
[MANUAL]: MANUAL.md
27+
28+
29+
Download
30+
--------
31+
32+
The latest binaries can be downloaded from GitHub at the following url:
33+
34+
https://github.com/j4james/big/releases/latest
35+
36+
37+
38+
Build Instructions
39+
------------------
40+
41+
If you want to build the program yourself, you'll need [CMake] version 3.10
42+
or later and a C++ compiler supporting C++17 or later (tested with [GCC] 7.4,
43+
[Clang] 6.0.0, and [Visual Studio] 2017 v15.9.12).
44+
45+
The process is slightly different depending on whether you're using a single
46+
configuration generator (like a Makefile) or a multi configuration generator
47+
(like Visual Studio or Xcode).
48+
49+
**Single configuration generators**
50+
51+
1. Download or clone the source:
52+
`git clone https://github.com/j4james/big.git`
53+
54+
2. Change into the build directory:
55+
`cd big/build`
56+
57+
3. Generate the project for your preferred build type:
58+
`cmake -D CMAKE_BUILD_TYPE=Release ..`
59+
60+
4. Start the build:
61+
`cmake --build .`
62+
63+
**Multi configuration generators**
64+
65+
1. Download or clone the source:
66+
`git clone https://github.com/j4james/big.git`
67+
68+
2. Change into the build directory:
69+
`cd big/build`
70+
71+
3. Generate the build project (supporting all build types):
72+
`cmake ..`
73+
74+
4. Start the build for your preferred build type:
75+
`cmake --build . --config Release`
76+
77+
[CMake]: https://cmake.org/
78+
[GCC]: https://gcc.gnu.org/
79+
[Clang]: https://clang.llvm.org/
80+
[Visual Studio]: https://visualstudio.microsoft.com/
81+
82+
83+
License
84+
-------
85+
86+
The BIG source code and binaries are released under the MIT License. See the
87+
[LICENSE] file for full license details.
88+
89+
[LICENSE]: LICENSE.txt

build/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

src/big.arithmetic.h

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// BIG Befunge Integer Generator
2+
// Copyright (c) 2019 James Holderness
3+
// Distributed under the MIT License
4+
5+
#pragma once
6+
7+
#include "big.expression.h"
8+
#include "big.operands.h"
9+
#include "big.utils.h"
10+
11+
#include <optional>
12+
13+
namespace big {
14+
15+
template <typename traits>
16+
struct arithmetic_operation {
17+
static constexpr auto length = utils::symbol_length(traits::symbol) + 1;
18+
static constexpr auto min_target = 10;
19+
static constexpr auto min_rhs = traits::min_rhs;
20+
static constexpr auto operand_order = traits::operand_order;
21+
22+
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
23+
{
24+
return traits::calculate_lhs(target, rhs);
25+
}
26+
27+
static void build_expression(char rhs_symbol, bool rhs_quoted, expression& container) noexcept
28+
{
29+
container.insert_suffix(traits::symbol);
30+
if (rhs_quoted)
31+
container.insert_into_string(rhs_symbol);
32+
else
33+
container.insert_suffix(rhs_symbol);
34+
}
35+
};
36+
37+
38+
using multiplication = arithmetic_operation<struct multiplication_traits>;
39+
struct multiplication_traits {
40+
static constexpr auto symbol = '*';
41+
static constexpr auto min_rhs = 2;
42+
static constexpr auto operand_order = largest_first;
43+
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
44+
{
45+
if (target % rhs == 0)
46+
return target / rhs;
47+
else
48+
return std::nullopt;
49+
}
50+
};
51+
52+
53+
using addition = arithmetic_operation<struct addition_traits>;
54+
struct addition_traits {
55+
static constexpr auto symbol = '+';
56+
static constexpr auto min_rhs = 1;
57+
static constexpr auto operand_order = largest_first;
58+
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
59+
{
60+
if (target > rhs)
61+
return target - rhs;
62+
else
63+
return std::nullopt;
64+
}
65+
};
66+
67+
68+
using subtraction = arithmetic_operation<struct subtraction_traits>;
69+
struct subtraction_traits {
70+
static constexpr auto symbol = '-';
71+
static constexpr auto min_rhs = 1;
72+
static constexpr auto operand_order = smallest_first;
73+
static std::optional<int> calculate_lhs(int target, int rhs) noexcept
74+
{
75+
if (target <= 0x7FFFFFFF - rhs)
76+
return target + rhs;
77+
else
78+
return std::nullopt;
79+
}
80+
};
81+
82+
83+
using reverse_subtraction = arithmetic_operation<struct reverse_subtraction_traits>;
84+
struct reverse_subtraction_traits : subtraction_traits {
85+
static constexpr auto symbol = "\\-";
86+
};
87+
88+
} // namespace big

src/big.cache.h

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// BIG Befunge Integer Generator
2+
// Copyright (c) 2019 James Holderness
3+
// Distributed under the MIT License
4+
5+
#pragma once
6+
7+
#include <unordered_map>
8+
9+
namespace big {
10+
11+
class cache {
12+
public:
13+
using size_type = int16_t;
14+
15+
struct reference {
16+
size_type& value;
17+
bool is_valid;
18+
};
19+
20+
reference lookup(int target, bool using_quotes, int space)
21+
{
22+
auto& entries = using_quotes ? quoted_entries : unquoted_entries;
23+
auto& entry = entries[target];
24+
const auto entry_valid = entry.value != 0 && entry.space >= space;
25+
if (!entry_valid) entry.space = space;
26+
return {entry.value, entry_valid};
27+
}
28+
29+
private:
30+
struct map_entry {
31+
size_type value;
32+
size_type space;
33+
};
34+
using map = std::unordered_map<int, map_entry>;
35+
36+
map quoted_entries;
37+
map unquoted_entries;
38+
};
39+
40+
} // namespace big

0 commit comments

Comments
 (0)