From c4dcdff9844e2404e3bc035f4cea9fce2f7770ab Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Sun, 19 May 2019 15:40:23 +0900
Subject: Add HintKeyProducer

---
 src/content/usecases/FollowMasterUseCase.ts |  2 +-
 src/content/usecases/HintKeyProducer.ts     | 38 +++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 src/content/usecases/HintKeyProducer.ts

(limited to 'src')

diff --git a/src/content/usecases/FollowMasterUseCase.ts b/src/content/usecases/FollowMasterUseCase.ts
index c2c6835..9cbb790 100644
--- a/src/content/usecases/FollowMasterUseCase.ts
+++ b/src/content/usecases/FollowMasterUseCase.ts
@@ -4,7 +4,7 @@ import FollowMasterRepository, { FollowMasterRepositoryImpl }
   from '../repositories/FollowMasterRepository';
 import FollowSlaveClient, { FollowSlaveClientImpl }
   from '../client/FollowSlaveClient';
-import HintKeyProducer from '../hint-key-producer';
+import HintKeyProducer from './HintKeyProducer';
 import SettingRepository, { SettingRepositoryImpl }
   from '../repositories/SettingRepository';
 
diff --git a/src/content/usecases/HintKeyProducer.ts b/src/content/usecases/HintKeyProducer.ts
new file mode 100644
index 0000000..241cd56
--- /dev/null
+++ b/src/content/usecases/HintKeyProducer.ts
@@ -0,0 +1,38 @@
+export default class HintKeyProducer {
+  private charset: string;
+
+  private counter: number[];
+
+  constructor(charset: string) {
+    if (charset.length === 0) {
+      throw new TypeError('charset is empty');
+    }
+
+    this.charset = charset;
+    this.counter = [];
+  }
+
+  produce(): string {
+    this.increment();
+
+    return this.counter.map(x => this.charset[x]).join('');
+  }
+
+  private increment(): void {
+    let max = this.charset.length - 1;
+    if (this.counter.every(x => x === max)) {
+      this.counter = new Array(this.counter.length + 1).fill(0);
+      return;
+    }
+
+    this.counter.reverse();
+    let len = this.charset.length;
+    let num = this.counter.reduce((x, y, index) => x + y * len ** index) + 1;
+    for (let i = 0; i < this.counter.length; ++i) {
+      this.counter[i] = num % len;
+      num = ~~(num / len);
+    }
+    this.counter.reverse();
+  }
+}
+
-- 
cgit v1.2.3