Created with <3 with dartpad.dev.
Last active
October 24, 2022 10:14
-
-
Save halka9000stg/1a1e04aed796e62ab497b75f08c2c854 to your computer and use it in GitHub Desktop.
Radial Number System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "dart:collection"; | |
void main() { | |
final RadialNumber rn = RadialNumber.basic([17, 3, 10], isCyclic: true); | |
rn.of(13592); | |
print(rn.toString()); | |
print(rn()); | |
rn.next(); | |
print(rn.toString()); | |
print(rn()); | |
rn.addDecimal(26); | |
print(rn.toString()); | |
print(rn()); | |
rn.next(); | |
print(rn.toString()); | |
print(rn()); | |
} | |
abstract class RadialNumber { | |
//数値の(繰り上げ処理された)桁リスト | |
final List<int> digits = [0]; | |
//numberに対応する(繰り上げ処理された)桁リストをdigitsへ格納 | |
void setByDecimal(int number); | |
void of(int number) => setByDecimal(number); | |
//記憶している桁リスト(digits)を次の数値へインクリメント(及び繰り上げ処理) | |
void next(); | |
//記憶している桁リスト(digits)をnumber分加算(及び繰り上げ処理) | |
void addDecimal(int number); | |
//与えられた桁リストを繰り上げ処理して返す | |
void moveUp(); | |
@override | |
String toString() => this.digits.toString(); | |
//記憶している数値(桁リスト)を進数文字列にして返す | |
String call(); | |
static RadialNumberBasic basic(List<int> dRadixes, {bool isCyclic = false}) => | |
RadialNumberBasic(dRadixes, isCyclic: isCyclic); | |
static PatternRadialNumber inPatttern(RadixPattern radixPattern) => | |
PatternRadialNumber(radixPattern); | |
} | |
class RadialNumberBasic extends RadialNumber { | |
//各桁の進数のリスト | |
final List<int> dRadixes; | |
//リストで与えられた進数の桁を越した上位桁に循環的にリストの進数を適用するかどうか | |
final bool isCyclic; | |
RadialNumberBasic(this.dRadixes, {this.isCyclic = false}); | |
factory RadialNumberBasic.fromDecimal(int number, List<int> dRadixes) { | |
RadialNumberBasic temp = RadialNumberBasic(dRadixes); | |
temp.of(number); | |
return temp; | |
} | |
//numberに対応する(繰り上げ処理された)桁リストをdigitsへ格納 | |
@override | |
void setByDecimal(int number) { | |
this.digits.clear(); | |
this.digits.addAll([number]); | |
this.moveUp(); | |
} | |
//次の数値へインクリメント(及び繰り上げ処理) | |
@override | |
void next() { | |
this.digits[0]++; | |
this.moveUp(); | |
//List<int> temp = List<int>.of(this.digits); | |
//print("this.digits: ${this.digits.length}, temp: ${temp.length}"); | |
//this.digits.clear(); | |
//print("this.digits: ${this.digits.length}, temp: ${temp.length}"); | |
//temp[0]++; | |
//this.digits.addAll(this.moveUp(temp)); | |
} | |
//記憶している桁リスト(digits)をnumber分加算(及び繰り上げ処理) | |
@override | |
void addDecimal(int number) { | |
//List<int> temp = List<int>.of(this.digits); | |
//print("this.digits: ${this.digits.length}, temp: ${temp.length}"); | |
//this.digits.clear(); | |
//print("this.digits: ${this.digits.length}, temp: ${temp.length}"); | |
this.digits[0] += number; | |
this.moveUp(); | |
//this.digits.addAll(this.moveUp(temp)); | |
} | |
//繰り上げ処理の具体的な処理中身 | |
void _moveUp(final List<int> radixes, int cnt) { | |
// print("> cnt: $cnt"); | |
//循環的に進数リストを適用する場合にも対応出来るよう、現在のカウンタ数の(進数リストの長さを基準とした)剰余を取る | |
final int radCnt = cnt % radixes.length; | |
//現在着目している桁の値を読み出し | |
int pivot = this.digits[cnt]; | |
//print("> pivot: $pivot"); | |
//現在着目している桁の進数を読み出し | |
int radPivot = radixes[radCnt]; | |
//print("> radPivot: $radPivot"); | |
if (pivot < radPivot) { | |
//現在着目している桁の値がその桁の進数よりも小さければ繰り上げる必要はないので再帰を打ち切って値返却 | |
return; | |
} else if ((!this.isCyclic) && (cnt >= radixes.length)) { | |
//循環的に進数リストを適用しない場合で、かつ現在のカウンタ数が進数リストの桁数以上であれば、 | |
//これ以上繰り上げできないので再帰を打ち切って値返却 | |
return; | |
} else { | |
//print(">> in else, digits.length: ${digits.length}"); | |
//繰り上げ処理が必要な場合。以降繰り上げ処理 | |
//現在着目している桁の値の、その桁の進数を基準とした剰余を桁リストの該当桁に格納 | |
this.digits[cnt] = pivot % radPivot; | |
if (this.digits.length <= cnt + 1) { | |
//現在着目している桁が桁リスト上で最上位桁となっている場合、繰り上げのためリストの要素を追加してリストの長さを伸ばす | |
//0はダミー値 | |
this.digits.add(0); | |
} | |
//print(">> in added, digits.length: ${digits.length}"); | |
//現在着目している桁の値の、その桁の進数を基準とした整除を桁リストの一つ上の桁に格納(繰り上げ) | |
this.digits[cnt + 1] += pivot ~/ radPivot; | |
//次の桁(現在着目している桁の一つ上の桁)へ移動して再帰。 | |
return this._moveUp(radixes, cnt + 1); | |
} | |
} | |
//与えられた桁リストを繰り上げ処理して返す | |
@override | |
void moveUp() { | |
final List<int> radixes = this.dRadixes.reversed.toList(); | |
this._moveUp(radixes, 0); | |
} | |
//記憶している数値(桁リスト)を進数文字列にして返す | |
@override | |
String call() { | |
final List<int> radixes = this.dRadixes.reversed.toList(); | |
List<String> rets = this.digits.indexedMap<String>((int ind, int dig) { | |
if (ind >= radixes.length && (!this.isCyclic)) { | |
return ":$dig"; | |
} | |
final int radCnt = ind % radixes.length; | |
int rad = radixes[radCnt]; | |
if (rad < 2 || 32 < rad) { | |
return "'$dig"; | |
} | |
return dig.toRadixString(rad); | |
}); | |
return rets.reversed.join(""); | |
} | |
} | |
class PatternRadialNumber extends RadialNumber { | |
final RadixPattern radixPattern; | |
PatternRadialNumber(this.radixPattern); | |
@override | |
void setByDecimal(int number) {} | |
@override | |
void next() {} | |
@override | |
void addDecimal(int number) {} | |
void _moveUp(final List<int> radixes, int cnt) {} | |
@override | |
void moveUp() {} | |
@override | |
String call() { | |
return ""; | |
} | |
} | |
typedef RGC = RadixGenerateConfigure; | |
class RadixGenerateConfigure { | |
final bool isRandomized; | |
final int maxRunning; | |
const RadixGenerateConfigure._(this.maxRunning, this.isRandomized); | |
factory RadixGenerateConfigure.sequentially(int maxRunning) => | |
RadixGenerateConfigure._(maxRunning, false); | |
factory RadixGenerateConfigure.sequent(int maxRunning) => | |
RadixGenerateConfigure.sequentially(maxRunning); | |
factory RadixGenerateConfigure.random(int maxRunning) => | |
RadixGenerateConfigure._(maxRunning, true); | |
} | |
//RadixPattern | |
//RadixKernel(int radix) | |
//RadixSequence(List<RadixPattern> patList, [bool cyclic = false]) | |
//RadixRangeIterate(RadixPattern pat, {int max, int min}) | |
//RadixOption(RadixPattern pat)=>RadixRangeIterate(pat, max: 1, min: 0) | |
//RadixPositive(RadixPattern pat)=>RadixRangeIterate(pat, max: Infinity, min: 1) | |
//RadixStar(RadixPattern pat)=>RadixRangeIterate(pat, max: Infinity, min: 0) | |
class RadixPattern { | |
RadixPattern._(); | |
factory RadixPattern() => RadixNil(); | |
Symbol get signal => RadixNil().signal; | |
} | |
class RadixNil extends RadixPattern { | |
@override | |
final Symbol signal = #nil; | |
RadixNil() : super._(); | |
} | |
class RadixKernel extends RadixPattern { | |
@override | |
final Symbol signal; | |
final int radix; | |
RadixKernel(Symbol name, this.radix) | |
: this.signal = name, | |
super._(); | |
} | |
class RadixSequence extends RadixPattern with IterableMixin<RadixPattern> { | |
final List<RadixPattern> patList; | |
final bool cyclic; | |
RadixSequence(this.patList, [this.cyclic = false]) : super._(); | |
@override | |
Iterator<RadixPattern> get iterator => this.patList.iterator; | |
} | |
class RadixRangeIteration extends RadixPattern | |
with IterableMixin<RadixPattern> { | |
final RadixPattern pat; | |
final int max; | |
final int min; | |
RadixRangeIteration(this.pat, {required this.max, required this.min}) | |
: super._(); | |
List<RadixPattern> asList() => []; | |
@override | |
Iterator<RadixPattern> get iterator => this.asList().iterator; | |
} | |
class RadixOption extends RadixPattern { | |
final RadixPattern _pat; | |
RadixOption._internal(this._pat) : super._(); | |
RadixRangeIteration toIteration() => | |
RadixRangeIteration(this._pat, max: 1, min: 0); | |
static RadixRangeIteration call(RadixPattern pat) => | |
RadixRangeIteration(pat, max: 1, min: 0); | |
} | |
class RadixPositive extends RadixPattern { | |
final RadixPattern _pat; | |
RadixPositive._internal(this._pat) : super._(); | |
RadixRangeIteration toIteration() => | |
RadixRangeIteration(this._pat, max: -1, min: 1); | |
static RadixRangeIteration call(RadixPattern pat) => | |
RadixRangeIteration(pat, max: -1, min: 1); | |
} | |
class RadixStar extends RadixPattern { | |
final RadixPattern _pat; | |
RadixStar._internal(this._pat) : super._(); | |
RadixRangeIteration toIteration() => | |
RadixRangeIteration(this._pat, max: -1, min: 0); | |
static RadixRangeIteration call(RadixPattern pat) => | |
RadixRangeIteration(pat, max: -1, min: 0); | |
} | |
class RadixAny extends RadixPattern with IterableMixin<RadixPattern> { | |
List<RadixPattern> patList; | |
RadixAny(this.patList) : super._(); | |
@override | |
Iterator<RadixPattern> get iterator => this.patList.iterator; | |
} | |
//RadixOr(a,b)=>RadixAny([a,b]) | |
class RadixOr extends RadixPattern { | |
final RadixPattern _a; | |
final RadixPattern _b; | |
RadixOr._internal(this._a, this._b) : super._(); | |
RadixAny toIteration() => RadixAny([this._a, this._b]); | |
static RadixAny call(RadixPattern a, RadixPattern b) => RadixAny([a, b]); | |
} | |
extension IndexedMapReduce<E> on List<E> { | |
List<R> indexedMap<R>(R Function(int, E) fn) => this | |
.asMap() | |
.map<int, R>((int i, E e) => MapEntry<int, R>(i, fn(i, e))) | |
.values | |
.toList(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment