目次
概要
iCollatz/無限化コラッツの数列を求めることができます。
また、前回公開の「コラッツ予想演算ツール」は、9…9(1000桁)などを指定して演算実行するとフリーズしたように見えていましたが、今回、随時演算状況を表示するようにしました。
今後投稿予定の記事でプログラムソースコードの内容を解説する予定です。
ツール
制限や特徴などは後回しにしてツールから公開します。
iCollatz演算 ブラウザ(BigInt)版
iCCBE:Infinite Collatz Calculator BigInt Editionツールはこちら(別タブが開きます)
ご意見、ご要望、不具合などのご連絡
ご意見、ご要望、不具合などのご連絡は次からお願いします。
- コメント
本投稿へ下部の コメントを書き込む からご連絡ください。
コメントは承認方式となっており、当方が承認しないと公開表示されません。
公開表示を希望されない方はその旨コメントに記述ください。 - Twitter
ご連絡は @dratech2020 https://twitter.com/dratech2020 の該当ツイートに返信するか、ハッシュタグ「#プログラミングの深淵を求めて」を付けてツイートしてください。 (すぐに気が付かない場合がありますので、ご了承ください)
変更来歴
- Rev. 1.0 2023/06/23
新規公開
制限や特徴
- 本ツールは、[演算開始]ボタンを押しても通信は発生せず(サーバーアクセスなし)、 ブラウザ(クライアント)内部だけで演算します。
このため、ご利用の環境(ブラウザの種類、マシンのスペックなど)によって、 処理できる桁数の制限が違います。
非常に大きい数値では処理時間と消費メモリが大きくなる(ただし前ツールより省メモリ化)ため、 正しく動作しない場合がありますのでご了承ください。 - 開始時のnを非常に大きい値にしても、演算実行時に逐次状況を表示し、フリーズしたように見えなくなりました。
- 表示形式を色付きテーブルにしたとき、100STEP毎のページ切り替えにすることにより、メモリ使用量を削減しました。
ex. MS Edgeで、r=2, k=3(コラッツ予想と同じ)で、n=9…9(9を1000桁)で演算すると前回ツールでは完走しませんでしたが、今回は完走可能なことを確認しています。
(注:テキスト(CSVまたはTSV)時はその限りではありません) - r=2~9,11~36までは、r進数の表示をすることで、直感的に数列の変化を見ることが可能です。
- 同じ演算結果が3回(開始時STEP0のnの値は除く)出現したら演算を停止します。
これは、例えばr=2, k=3(コラッツ予想と同じ)のとき、n=3でf(n)=3*3+1=10と、n=20でf(n)=20/2=10で同じ10になるのに2通りの演算があるため、3回の出現を監視することで、確実にループになったことを確認できるようにします。 - 演算式の途中式を表示可能で、値の検証がやりやすくなりました。
関連情報
詳細は、「iCollatzの提案 #1 iCollatzの式」を参照ください。
iCollatzの式
iCollatz[矯正:Correct]の式
関連投稿
実行例
r=2,k=3,n=27の実行例
ソースコード
本ソースコードはオープン(透明性のある)/無料で参照/利用できますが、自由にして良いわけではありません。
It’s open and free source code, but it’s not freedom.
icollatz_bigint.html
<!DOCTYPE html>
<html lang="ja">
<!-- iCollatz演算ブラウザ(BigInt)版(iCCBE) -->
<!-- $Id$ -->
<!-- (C)2021-2023 プログラミングの深淵を求めて https://www.seekabypro.com/ -->
<!-- (C)2021-2023 どらテク(どらぐ~んテクノロジー) https://twitter.com/dratech2020 -->
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex" />
<title>iCollatz演算ブラウザ(BigInt)版</title>
<link rel="stylesheet" type="text/css" href="./css/icollatz.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js" type="text/javascript"></script>
<script src="./js/icollatz.js" type="text/javascript"></script>
</head>
<body>
<div id="icollatz">
<h1>iCollatz演算 ブラウザ(BigInt)版<br />(iCCBE:Infinite Collatz Calculator BigInt Edition)</h1>
<a href="/2023/06/23/icollatz_no2/">ツールの概要などはこちら</a>
<hr />
<span id="ic_sponsor1" class="ic_item_hide_span">
スポンサーリンク[-]
</span>
<span id="ic_sponsor1_content">
<br />
</span>
<hr />
<div class="ic_formula">
<span id="ic_formula" class="ic_item_hide_span">
計算式[-]
</span>
<span id="ic_formula_content">
<!-- 計算式 -->
<br />
<a href="img/icollatz_v05_mid.png">
<img src="img/icollatz_v05_mid.png" alt="iCollatz式" style="width:640px;" />
</a>
<br />
<a href="img/icollatz_v05_cor_mid.png">
<img src="img/icollatz_v05_cor_mid.png" alt="iCollatz式[矯正:Correct]" style="width:540px;" />
</a>
</span>
</div>
<hr />
<div id="ic_start_input">
各入力テキストは、10進数、先頭に 0b を付けると2進数、同様に 0o で8進数、0x で16進数として扱います(他の基数での入力は非対応)。<br />
<span><font color="RED">※10進数は'0'~'9'、2進数は'0','1'、8進数は'0'~'7'、16進数は'0'~'9'と'a'~'f'(大文字小文字は区別なし)以外の文字は削除します。</font></span>
<br />
r:基数(Radix)<br />
<input id="ic_radix" name="ic_radix" type="text" value=2 onkeypress="return HtVw.input_onkeypress();">
<br />
k:係数<br />
<input id="ic_k" name="ic_k" type="text" value=3 onkeypress="return HtVw.input_onkeypress();">
<span>k>rおよびk<r<sup>2</sup>の<font color="RED">範囲以外の場合</font>は警告のみで演算可能です。</span>
<br />
n:開始の数値<br />
<input id="ic_input" name="ic_input" type="text" value=27 onkeypress="return HtVw.input_onkeypress();">
<span id="ic_input_length">0</span>桁
<br />
<input id="ic_start" name="ic_start" type="button" value="演算開始">
<input id="ic_pause" name="ic_pause" type="button" value="一時停止" disabled="">
<input id="ic_stop" name="ic_stop" type="button" value="演算終了" disabled="">
<br />
<span>
<font color="RED">
※同じ数字が<span id="ic_same_after">3</span>回発生したとき、または、[演算終了]ボタンを押すまで実行します。<br />
※[演算開始]ボタンを押しても通信は発生せず(サーバーアクセスなし)、 ブラウザ(クライアント)内部だけで演算します。
</font>
</span>
</div>
<hr />
<div class="ic_status">
<span>
Status :
<span id="ic_status">未実行</span>
</span>
</div>
<div class="ic_goal_step">
<span>
GOAL-STEP :
<span id="ic_goal_step">?</span>
<span>(最初にn=1となったSTEP)</span>
</span>
</div>
<div class="ic_count_mzr">
<span>
COUNT-MZR :
<span id="ic_count_mzr">0</span>
回(Modulo ZeRo:剰余==0:STEP=0分は含まず、最初にn=1なるまで)
</span>
</div>
<div class="ic_count_mnz">
<span>
COUNT-MNZ :
<span id="ic_count_mnz">0</span>
回(Modulo Non Zero:剰余!=0:STEP=0分は含まず、最初にn=1なるまで)
</span>
</div>
<div class="ic_max_n_step">
<span>
<span>MAX-n-STEP :</span>
<span id="ic_max_n_step">0</span>
<span>(最初にn=最大となったSTEP)</span>
</span>
</div>
<div class="ic_max_n">
<span>
<span>MAX-n :</span>
<span id="ic_max_n">0</span>
</span>
</div>
<div class="ic_goal_n_dash">
<span>
GOAL-n' :
<span id="ic_goal_n_dash_radix">r</span><sup id="ic_goal_n_dash_exp">?</sup>=
<span id="ic_goal_n_dash_dec">?</span>
</span>
</div>
<div class="ic_proc_time">
<span>
Processing Time:
<span id="ic_proc_time">0(ms)</span>
<br />
</span>
</div>
<hr />
<div class="ic_display">
<span id="ic_display" class="ic_item_hide_span">
表示指定[-]
</span>
<br />
<span id="ic_display_content">
<font color="RED">
※オフにしたものは必要最低限しか演算しません(消費メモリの節約になります)<br />
※r進数の表示はr=2~9,11~36(10は除く)のときに有効です。
</font>
<br />
<div class="ic_display_icollatz">
<span>iCollatzの列</span>
<input id="ic_display_all_on" name="ic_display_all_on" type="button" value="全表示">
<input id="ic_display_all_of" name="ic_display_all_of" type="button" value="全非表示">
<br />
<label class="ic_label"><input id="ic_view_step" name="ic_view_step" type="checkbox" checked >STEP</label>
<label class="ic_label"><input id="ic_view_n" name="ic_view_n" type="checkbox" checked disabled>n(10進数:解除不可)</label>
<label class="ic_label"><input id="ic_view_n_radix" name="ic_view_n_radix" type="checkbox" checked >n(r進数)</label>
<label class="ic_label"><input id="ic_view_calc" name="ic_view_calc" type="checkbox" >演算式(10進数)</label>
<label class="ic_label"><input id="ic_view_calc_radix" name="ic_view_calc_radix" type="checkbox" >演算式(r進数)</label>
</div>
<div class="ic_display_icollatz_dash">
<span>iCollatz[矯正:Correct]の列</span>
<input id="ic_display_dash_all_on" name="ic_display_dash_all_on" type="button" value="全表示">
<input id="ic_display_dash_all_of" name="ic_display_dash_all_of" type="button" value="全非表示">
<br />
<label class="ic_label"><input id="ic_view_n_dash" name="ic_view_n_dash" type="checkbox" checked>n'(10進数)</label>
<label class="ic_label"><input id="ic_view_d" name="ic_view_d" type="checkbox" checked>d(10進数)</label>
<label class="ic_label"><input id="ic_view_n_dash_radix" name="ic_view_n_dash_radix" type="checkbox" checked>n'(r進数)</label>
<label class="ic_label"><input id="ic_view_d_radix" name="ic_view_d_radix" type="checkbox" checked>d(r進数)</label>
</div>
<div class="ic_display_text_type">
<span>表示形式:</span>
<label class="ic_label"><input id="ic_display_text_color" name="ic_display_text_type" type="radio" value="color" checked>色付きテーブル</label>
<label class="ic_label"><input id="ic_display_text_csv" name="ic_display_text_type" type="radio" value="csv" >テキスト(CSV)</label>
<label class="ic_label"><input id="ic_display_text_tsv" name="ic_display_text_type" type="radio" value="tsv" >テキスト(TSV)</label>
<!-- Rev1.0では見送 <font color="RED">※実行中でも変更を反映</font> -->
</div>
<div class="ic_display_item_width">
<span>列幅指定:</span>
<label class="ic_label"><input id="ic_display_item_width1" name="ic_display_item_width" type="radio" value="all" checked>制限なし</label>
<label class="ic_label"><input id="ic_display_item_width2" name="ic_display_item_width" type="radio" value="scroll" >制限あり(内部スクロール表示)</label>
<font color="RED">※実行中でも変更を反映</font>
</div>
<div class="ic_display_line">
<span>行スクロール指定:</span>
<label class="ic_label"><input id="ic_display_line1" name="ic_display_line" type="radio" value="scroll" checked>内部スクロール表示</label>
<label class="ic_label"><input id="ic_display_line2" name="ic_display_line" type="radio" value="all" >全行表示</label>
<font color="RED">※実行中でも変更を反映</font>
</div>
</span>
</div>
<hr />
<div class="ic_list_header">
<b>演算結果</b>
<input id="ic_text_copy" name="ic_text_copy" type="button" value="テキストをコピー">
<input id="ic_clear" name="ic_clear" type="button" value="結果クリア">
</div>
</div>
<div class="ic_list">
ここに演算結果が入ります。
</div>
<hr />
<span id="ic_sponsor2" class="ic_item_hide_span">
スポンサーリンク[-]
</span>
<span id="ic_sponsor2_content">
<br />
</span>
<hr />
(C)2021-2023 プログラミングの深淵を求めて
<a href="https://www.seekabypro.com/">https://www.seekabypro.com/</a>
<br />
(C)2021-2023 どらテク(どらぐ~んテクノロジー)
Twitter:
<a href="https://twitter.com/dratech2020">@dratech2020</a>
<a href="https://twitter.com/dratech2020">https://twitter.com/dratech2020</a>
<br />
</body>
</html>
icollatz.js
// iCollatz演算ブラウザ(BigInt)版(iCCBE:Infinite Collatz Calculator BigInt Edition)
// $Id$
// (C)2021-2023 プログラミングの深淵を求めて https://www.seekabypro.com/
// (C)2021-2023 どらテク(どらぐ~んテクノロジー) https://twitter.com/dratech2020
// 本ソースはオープン/無料で参照/利用できますが、自由にして良いわけではありません。
// It's open and free source code, but it's not freedom.
//-----------------------------------------------------------------------------
//定数定義
//-----------------------------------------------------------------------------
const IC_DEFAULT_RADIX=2n;
const IC_DEFAULT_K=3n;
const IC_DEFAULT_N=27n;
const IC_DEFAULT_D=1n;
const IC_DEFAULT_SAME_COUNT=3;
const IC_DEFAULT_PAGE_COUNT_MAX=100;
const IC_DEFAULT_PAGER_MAX=5;
const IC_DEFAULT_INTERVAL_CALCULATE_TIME=1; //(ms)
const IC_DEFAULT_INTERVAL_VIEW_TIME=200; //(ms)
const IC_DEFAULT_VIEW_STOP_COUNT=3;
const IC_CLASS_NAME_ICOLLATZ = "iCollatz";
const IC_CLASS_NAME_ICOLLATZCORRECT = "iCollatzCorrect";
const IC_TEXT_MODE_COLOR = "color";
const IC_TEXT_MODE_CSV = ",";
const IC_TEXT_MODE_TSV = "\t";
const IC_STATUS_NO_PROC = "IC_STATUS_NO_PROC"; //未実行
const IC_STATUS_EXEC_PROC = "IC_STATUS_EXEC_PROC"; //実行中
const IC_STATUS_PAUSE = "IC_STATUS_PAUSE"; //一時停止中
const IC_STATUS_COUNT_OVER = "IC_STATUS_COUNT_OVER"; //同じ数値がIC_DEFAULT_SAME_COUNT回発生
const IC_STATUS_USER = "IC_STATUS_USER"; //ユーザーによる停止
const IC_STATUS_FATAL_ERROR= "IC_STATUS_FATAL_ERROR"; //致命的エラー
const IC_MOD_ZERO = "MZR"; //Modulo ZeRo:剰余==0
const IC_MOD_NON_ZERO = "MNZ"; //Modulo Non Zero:剰余!=0
const IC_COLOR_HEAD ="#BDD7EE";
const IC_COLOR_MZR ="#DDEBF7";
const IC_COLOR_MNZ ="#FFF2CC";
const IC_COLOR_N_MAX="#C6E0B4";
const IC_COLOR_GOAL ="#C7A1E3";
const IC_COLOR_SAME ="#FF7F50";
//-----------------------------------------------------------------------------
//グローバル(ファイル内)変数
//-----------------------------------------------------------------------------
let iCRM = undefined;
let HtVw = undefined;
//-----------------------------------------------------------------------------
//クラス定義
//-----------------------------------------------------------------------------
//SuperICollatzクラス
class SuperICollatz {
constructor(radix = IC_DEFAULT_RADIX,k = IC_DEFAULT_K,d = IC_DEFAULT_D) {
this.radix = radix;
this.k = k;
this.d = d;
this.f = undefined;
this.n = 0n;
this.mod = 0n;
}
calculate(number = IC_DEFAULT_N) {}
calculate_zero() {}
calculate_non_zero() {}
clone() {
return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
}
}
//iCollatzクラス
class iCollatz extends SuperICollatz {
calculate(number = IC_DEFAULT_N) {
this.n = number;
let m = this.n % this.radix;
if ( m == 0n ) {
this.calculate_zero();
} else {
this.calculate_non_zero();
}
this.mod = this.f % this.radix;
return this;
}
calculate_zero() {
this.f = this.n / this.radix;
this.d = this.radix * this.d;
return this.f;
}
calculate_non_zero() {
let h = this.k * this.n;
this.f = h + (this.radix - ( h % this.radix));
return this.f;
}
}
//iCollatzCorrectクラス
class iCollatzCorrect extends SuperICollatz {
calculate(number = IC_DEFAULT_N) {
this.n = number;
let m = (this.n/this.d) % this.radix;
if ( m == 0n ) {
this.calculate_zero();
} else {
this.calculate_non_zero();
}
this.mod = (this.f/this.d) % this.radix;
return this;
}
calculate_zero() {
this.f = this.n;
this.d = this.radix * this.d;
return this.f;
}
calculate_non_zero() {
let h = this.k * this.n;
this.f = h + this.d * (this.radix - ( (h/this.d) % this.radix));
return this.f;
}
}
//ResultStoreクラス
class ResultStore {
constructor(key,number,same_count,icollatz) {
let obj = this;
obj.key = key;
obj.store = [];
obj.number_store = [];
obj.same_count = same_count;
icollatz.f = number;
icollatz.mod = number % icollatz.radix;
obj.icollatz = icollatz;
obj.set(0,icollatz);
//
obj.goal_step=0;
obj.count_mzr=0;
obj.count_mnz=0;
obj.max_step=0;
}
set(step,icollatz) {
let obj = this;
obj.store[step] = icollatz;
if ( obj.number_store[icollatz.f] == undefined ) {
obj.number_store[icollatz.f] = {
"icollatz":icollatz,
"step":[],
};
}
if ( step > 0 ) {
obj.number_store[icollatz.f]["step"].push(step);
}
if ( (obj.key == IC_CLASS_NAME_ICOLLATZ) && (obj.number_store[icollatz.f]["step"].length >= obj.same_count) ) {
//同じものがobj.same_count回出現したので停止する
HtVw.set_stop_flag(true);
HtVw.set_status(IC_STATUS_COUNT_OVER);
}
}
}
//iCollatzResultManagerクラス
class iCollatzResultManager {
constructor() {
let obj = this;
obj.store_hash = {};
obj.radix = undefined;
obj.k = undefined;
}
get_store_hash(h = IC_CLASS_NAME_ICOLLATZ) {
let obj = this;
return obj.store_hash[h];
}
init_store(n = IC_DEFAULT_N) {
let obj = this;
let array = [];
//if (
// (HtVw.checked_item_view_step() == true) ||
// (HtVw.checked_item_view_n() == true) || //解除不可
// (HtVw.checked_item_view_n_radix() == true)
//) {
array.push(IC_CLASS_NAME_ICOLLATZ);
//}
if (
(HtVw.checked_item_view_n_dash() == true) ||
(HtVw.checked_item_view_n_dash_radix() == true) ||
(HtVw.checked_item_view_d() == true) ||
(HtVw.checked_item_view_d_radix() == true)
) {
array.push(IC_CLASS_NAME_ICOLLATZCORRECT);
}
array.forEach( //ここではjQuery.eachは使いたくない
function(key) {
//thisはforEachのものに置き換わるためobjと使い分ける
let ic = undefined;
if ( key == IC_CLASS_NAME_ICOLLATZ ) {
ic = new iCollatz(obj.radix,obj.k);
} else if( key == IC_CLASS_NAME_ICOLLATZCORRECT ) {
ic = new iCollatzCorrect(obj.radix,obj.k);
}
obj.store_hash[key] = new ResultStore(key,n,HtVw.get_same_count(),ic);
}
);
}
caluculate_proc() {
let obj = this;
for (let key in obj.store_hash) { //ここではjQuery.eachは使いたくない
let sh = obj.store_hash[key];
let step = sh.store.length;
let n = sh.store[step-1].f;
let icollatz = sh.store[step-1].clone();
icollatz.calculate(n);
sh.set(step,icollatz);
if ( key == IC_CLASS_NAME_ICOLLATZ ) {
if ( sh.store[sh.max_step].f < icollatz.f ) {
sh.max_step = step;
}
if ( sh.goal_step == 0) {
if ( icollatz.mod == 0n ) {
sh.count_mzr++;
} else {
sh.count_mnz++;
}
if (icollatz.f == 1n) {
sh.goal_step = step;
}
}
}
}
}
}
//HtmlViewクラス
class HtmlView {
constructor() {
let obj = this;
obj.item_icollatz = jQuery("#icollatz");
obj.item_radix = jQuery("#ic_radix");
obj.item_k = jQuery("#ic_k");
obj.item_input = jQuery("#ic_input");
obj.item_list = jQuery(".ic_list");
obj.same_count = IC_DEFAULT_SAME_COUNT;
obj.interval_calculate_time = IC_DEFAULT_INTERVAL_CALCULATE_TIME;
obj.interval_calculate_id = undefined;
obj.interval_view_time = IC_DEFAULT_INTERVAL_VIEW_TIME;
obj.interval_view_id = undefined;
obj.view_stop_count = 0;
obj.stop_flag = false;
obj.pause_flag = false;
obj.proc_start_time = 0;
obj.proc_time = 0;
obj.pause_start_time = 0;
obj.pause_time = 0;
obj.view = undefined;
obj.item_view_step = jQuery("#ic_view_step");
obj.item_view_n = jQuery("#ic_view_n");
obj.item_view_n_radix = jQuery("#ic_view_n_radix");
obj.item_view_calc = jQuery("#ic_view_calc");
obj.item_view_calc_radix = jQuery("#ic_view_calc_radix");
obj.item_view_n_dash = jQuery("#ic_view_n_dash");
obj.item_view_n_dash_radix = jQuery("#ic_view_n_dash_radix");
obj.item_view_d = jQuery("#ic_view_d");
obj.item_view_d_radix = jQuery("#ic_view_d_radix");
obj.item_display_text_type = jQuery("input:radio[name = 'ic_display_text_type']");
obj.item_display_item_width = jQuery("input:radio[name = 'ic_display_item_width']");
obj.item_display_line = jQuery("input:radio[name = 'ic_display_line']");
obj.item_status = jQuery("#ic_status");
obj.item_goal_step = jQuery("#ic_goal_step");
obj.item_goal_n_dash_radix = jQuery("#ic_goal_n_dash_radix");
obj.item_goal_n_dash_exp = jQuery("#ic_goal_n_dash_exp");
obj.item_goal_n_dash_dec = jQuery("#ic_goal_n_dash_dec");
obj.item_count_mzr = jQuery("#ic_count_mzr");
obj.item_count_mnz = jQuery("#ic_count_mnz");
obj.item_max_n_step = jQuery("#ic_max_n_step");
obj.item_max_n = jQuery("#ic_max_n");
obj.item_proc_time = jQuery("#ic_proc_time");
obj.item_button_start = jQuery("#ic_start");
obj.item_button_pause = jQuery("#ic_pause");
obj.item_button_stop = jQuery("#ic_stop");
//
obj.status = IC_STATUS_NO_PROC;
obj.status_message = {
IC_STATUS_NO_PROC :"未実行",
IC_STATUS_EXEC_PROC :"実行中",
IC_STATUS_PAUSE :"一時停止中",
IC_STATUS_COUNT_OVER :"同じ数値(n=IC_SAME_COUNT_N)がIC_DEFAULT_SAME_COUNT回発生",
IC_STATUS_USER :"ユーザーによる停止",
IC_STATUS_FATAL_ERROR:"致命的エラーが発生",
};
}
get_status() {
return this.status;
}
set_status(status) {
this.status = status;
return ;
}
set_stop_flag(flag) {
this.stop_flag = flag;
return ;
}
get_same_count() {
return this.same_count;
}
checked_item_view_step() {
return this.item_view_step.is(":checked");
}
checked_item_view_n() {
return this.item_view_n.is(":checked");
}
checked_item_view_n_radix() {
return this.item_view_n_radix.is(":checked");
}
checked_item_view_n_dash() {
return this.item_view_n_dash.is(":checked");
}
checked_item_view_n_dash_radix() {
return this.item_view_n_dash_radix.is(":checked");
}
checked_item_view_d() {
return this.item_view_d.is(":checked");
}
checked_item_view_d_radix() {
return this.item_view_d_radix.is(":checked");
}
//キーコードを応答する
get_keycode(e) {
if (!e) e = window.event;
return e.keyCode;
}
//onkeypress向け
input_onkeypress(obj,value,ev) {
let c = this.get_keycode(ev);
if (c == 13) {
this.ic_start_onclike();
return false;
} else {
return true;
}
}
//入力テキストチェックstr
input_check_str(str) {
if ( (str.indexOf("0b") === 0) || (str.indexOf("0B") === 0) ) {
//2進数
str = "0b"+str.replace(/^0b/i,"").replace(/[^01]/g,"");
} else if ( (str.indexOf("0o") === 0) || (str.indexOf("0O") === 0) ) {
//8進数
str = "0o"+str.replace(/^0o/i,"").replace(/[^0-7]/g,"");
} else if ( (str.indexOf("0x") === 0) || (str.indexOf("0X") === 0) ) {
//16進数
str = "0x"+str.replace(/^0x/i,"").replace(/[^0-9a-f]/ig,"");
} else {
//10進数
str = str.replace(/[^0-9]/g,"");
}
return str;
}
//入力テキストチェック
input_check(hash) {
let obj = this;
let n = 0n;
let str = hash["text"].val();
str = obj.input_check_str(str);
n=BigInt(str);
if ( ( hash["mes"] != undefined ) && ( n == 0n ) ) {
window.alert(hash["mes"]+"が0または数値以外です。");
return 0n;
}
return n;
}
//入力桁数などの表示
ic_oninput() {
let obj = this;
let inp = obj.input_check_str(obj.item_input.val());
let len = inp.replace(/^0[box]/,"").length;
jQuery("#ic_input_length").text(len);
}
//演算開始ボタン
ic_start_onclike() {
let obj = this;
//
let text_hash = { "text":obj.item_input, "mes":"n:開始の数値" };
let n = obj.input_check(text_hash);
if ( n == 0n ) {
return false;
}
//
text_hash = { "text":obj.item_radix, "mes":"r:基数" };
iCRM.radix = obj.input_check(text_hash);
if ( iCRM.radix == 0n ) {
return false;
}
if ( iCRM.radix <= 1n ) {
window.alert("rは2以上の数値を指定してください。");
return false;
}
//
text_hash = { "text":obj.item_k, "mes":"k:係数" };
iCRM.k = obj.input_check(text_hash);
if ( iCRM.k == 0n ) {
return false;
}
if ( iCRM.k <= 1n ) {
window.alert("kは2以上の数値を指定してください。");
return false;
}
//
if ( iCRM.k <= iCRM.radix ) {
window.alert("kがrより大きい数値が指定されました。\n無限ループする場合は[演算停止]ボタンで停止してください。");
}
if ( iCRM.k >= (iCRM.radix*iCRM.radix) ) {
window.alert("kがrの2乗以上の数値が指定されました。\n無限に増大する場合は[演算停止]ボタンで停止してください。");
}
if ( obj.interval_calculate_id != undefined ) {
obj.stop_proc();
}
obj.status = IC_STATUS_EXEC_PROC;
iCRM.init_store(n);
obj.item_button_start.prop("disabled",true);
obj.item_button_stop.prop("disabled",false);
obj.item_button_pause.prop("disabled",false);
obj.ic_view_status();
if ( obj.item_list != undefined ) {
obj.item_list.remove();
obj.item_list = undefined;
}
obj.stop_flag=false;
obj.pause_flag=false;
obj.proc_start_time = performance.now();
obj.pause_time = 0;
obj.set_calculate_interval();
obj.set_view_interval();
}
//一時停止/演算再開ボタン
ic_pause_onclike() {
let obj = this;
if (obj.interval_calculate_id != undefined ) {
//一時停止
if ( obj.pause_flag == false ) {
obj.status = IC_STATUS_PAUSE;
obj.pause_flag=true;
obj.pause_start_time = performance.now();
} else {
obj.status = IC_STATUS_EXEC_PROC;
obj.pause_flag=false;
obj.pause_time += performance.now() - obj.pause_start_time;
}
}
}
//演算中断処理
stop_proc() {
let obj = this;
if ( obj.interval_calculate_id != undefined ) {
clearInterval(obj.interval_calculate_id);
obj.interval_calculate_id = undefined;
obj.proc_time = performance.now() - obj.proc_start_time - obj.pause_time;
}
obj.stop_flag = true
}
//演算中断ボタン
ic_stop_onclike() {
let obj = this;
obj.status = IC_STATUS_USER;
obj.stop_proc();
}
//テキストコピーボタン
ic_text_copy_onclike() {
let obj = this;
let rc = obj.view.text_copy();
if ( rc == true ) {
window.alert("クリップボードにコピーしました。");
}
}
//結果クリアボタン
ic_clear_onclike() {
let obj = this;
obj.ic_oninput();
obj.item_list.remove();
obj.item_list = jQuery("<div>",{ class:"ic_list", text:"ここに演算結果が入ります。", });
obj.item_icollatz.append(obj.item_list);
}
//演算処理(インターバルタイマー用)
ic_calculate(obj) { //インターバルにはthisが渡らないのでarg1=objとして渡す
if ( obj.pause_flag == true ) {
return;
}
try {
iCRM.caluculate_proc();
} catch ( error ) {
window.alert("致命的エラーが発生しました。\n"
+error+"\n"
+error.fileName+":"+error.lineNumber+":"+error.message+"\n"
);
obj.status = IC_STATUS_FATAL_ERROR;
obj.stop_flag = true;
} finally {
if ( obj.stop_flag == true ) {
obj.stop_proc();
}
obj.proc_time = performance.now() - obj.proc_start_time - obj.pause_time;
}
}
//演算処理インターバルタイマー設定
set_calculate_interval() {
let obj = this;
if ( obj.interval_calculate_id != undefined ) {
clearInterval(obj.interval_calculate_id);
obj.interval_calculate_id = undefined;
}
obj.interval_calculate_id = setInterval(obj.ic_calculate, obj.interval_calculate_time,obj);
}
//描画処理(インターバルタイマー用)
ic_view(obj) { //インターバルにはthisが渡らないのでarg1=objとして渡す
try {
if ( obj.stop_flag == false ) {
obj.item_button_start.prop("disabled",true);
obj.item_button_stop.prop("disabled",false);
obj.item_button_pause.prop("disabled",false);
} else {
obj.item_button_start.prop("disabled",false);
obj.item_button_stop.prop("disabled",true);
obj.item_button_pause.prop("disabled",true);
}
if ( obj.pause_flag == false ) {
obj.item_button_pause.val("一時停止");
} else {
obj.item_button_pause.val("実行再開");
}
if ( obj.item_list == undefined ) {
obj.item_list = jQuery("<div>",{ "class":"ic_list", });
obj.item_icollatz.append(obj.item_list);
obj.ic_display_row();
let text_type = obj.item_display_text_type.filter(':checked').val();
if ( text_type == "csv" ) {
obj.view = new ViewText(IC_TEXT_MODE_CSV);
} else if ( text_type == "tsv" ) {
obj.view = new ViewText(IC_TEXT_MODE_TSV);
} else { //text_type == IC_TEXT_MODE_COLOR
obj.view = new ViewColor();
}
}
//#描画処理
obj.view.append();
} catch ( error ) {
if ( obj.status != IC_STATUS_FATAL_ERROR ) {
window.alert("致命的エラーが発生しました。\n"
+error+"\n"
+error.fileName+":"+error.lineNumber+":"+error.message+"\n"
);
}
obj.status = IC_STATUS_FATAL_ERROR;
obj.stop_flag = true;
} finally {
if ( obj.stop_flag == true ) {
if ( obj.view_stop_count >= IC_DEFAULT_VIEW_STOP_COUNT ) {
if ( obj.interval_view_id != undefined ) {
clearInterval(obj.interval_view_id);
obj.interval_view_id = undefined;
}
} else {
obj.view_stop_count++;
}
}
obj.ic_view_status();
}
}
//描画処理インターバルタイマー設定
set_view_interval() {
let obj = this;
if ( obj.interval_view_id != undefined ) {
clearInterval(obj.interval_view_id);
obj.interval_view_id = undefined;
}
obj.interval_view_id = setInterval(obj.ic_view, obj.interval_view_time,obj);
}
//実行状況表示
ic_view_status() {
let obj = this;
let sh_ic = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZ);
let sh_ic_dash = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZCORRECT);
let mes = obj.status_message[obj.status];
if ( obj.status == IC_STATUS_COUNT_OVER ) {
let store_ic = sh_ic.store;
let same_n = store_ic[store_ic.length-1].f;
mes = mes.replace(/IC_DEFAULT_SAME_COUNT/g,IC_DEFAULT_SAME_COUNT)
.replace(/IC_SAME_COUNT_N/g,same_n);
}
obj.item_status.text(mes);
//
let goal_step = sh_ic.goal_step;
let goal_step_str = "?";
if ( goal_step > 0 ) {
goal_step_str = goal_step.toLocaleString();
}
obj.item_goal_step.text(goal_step_str);
obj.item_goal_n_dash_radix.text(sh_ic.store[sh_ic.max_step].radix.toLocaleString());
if ( sh_ic_dash != undefined ) {
let exp_str = "?";
let dec_str = "?";
if ( goal_step > 0 ) {
exp_str = sh_ic.count_mzr.toLocaleString();
dec_str = sh_ic_dash.store[goal_step].f.toLocaleString();
}
obj.item_goal_n_dash_exp.text(exp_str);
obj.item_goal_n_dash_dec.text(dec_str);
}
obj.item_count_mzr.text(sh_ic.count_mzr.toLocaleString());
obj.item_count_mnz.text(sh_ic.count_mnz.toLocaleString());
obj.item_max_n_step.text(sh_ic.max_step.toLocaleString());
obj.item_max_n.text(sh_ic.store[sh_ic.max_step].f.toLocaleString());
obj.item_proc_time.text(obj.proc_time.toLocaleString()+"(ms)");
}
//列幅指定
ic_display_item_width() {
let obj = this;
let val = obj.item_display_item_width.filter(':checked').val();
let span = obj.item_list.find("span");
if ( val == "all" ) {
span.removeClass("ic_item_width_scroll");
} else {
span.addClass("ic_item_width_scroll");
}
}
//行スクロール指定
ic_display_row() {
let obj = this;
let val = obj.item_display_line.filter(':checked').val();
if ( val == "all" ) {
obj.item_list.css("max-height","");
} else {
obj.item_list.css("max-height","480px");
}
}
//全表示/全非表示
ic_display_checkbox(obj,flag) {
let chk = jQuery(obj).closest("div").find("input:checkbox");
chk.each(function(index) {
let item = jQuery(this);
if ( item.is(":disabled") == false ) {
item.prop("checked",flag);
}
});
}
ic_display_redraw(text_type=IC_TEXT_MODE_COLOR,pg=undefined) {
let obj = this;
let mode = text_type;
if ( mode == "csv" ) {
mede = IC_TEXT_MODE_CSV;
} else if ( mode == "tsv" ) {
mede = IC_TEXT_MODE_TSV;
}
if ( (obj.view.mode == mode) && (mode != IC_TEXT_MODE_COLOR) ) {
return;
}
let taget_page = undefined;
if ( mode == IC_TEXT_MODE_COLOR ) {
if ( pg != undefined ) {
let pager = jQuery(pg);
let cls = pager.attr("class");
if ( cls == "ic_list_pager_sel" ) {
taget_page = pager.val();
} else {
//ic_list_pager_a_start,ic_list_pager_a_previos,ic_list_pager_a_content,
//ic_list_pager_a_next,ic_list_pager_a_end
taget_page = pager.data("page");
}
if ( obj.view.page == taget_page ) {
return;
}
}
}
obj.view.redraw(taget_page);
}
//表示を隠す
ic_hide(obj,target) {
let span = jQuery(obj);
let text = span.text();
let content = jQuery(target);
if ( text.indexOf("[-]") >= 0 ) {
text = text.replace(/-/g,"+");
span.text(text);
content.addClass("ic_item_hide_display");
} else {
text = text.replace(/\+/g,"-");
span.text(text);
content.removeClass("ic_item_hide_display");
}
}
}
//SuperViewクラス
class SuperView {
constructor() {
let obj = this;
obj.count = 0;
obj.step = HtVw.item_view_step.is(":checked");
obj.n = HtVw.item_view_n.is(":checked");
obj.n_radix = HtVw.item_view_n_radix.is(":checked");
obj.calc = HtVw.item_view_calc.is(":checked");
obj.calc_radix = HtVw.item_view_calc_radix.is(":checked");
obj.n_dash = HtVw.item_view_n_dash.is(":checked");
obj.n_dash_radix = HtVw.item_view_n_dash_radix.is(":checked");
obj.d = HtVw.item_view_d.is(":checked");
obj.d_radix = HtVw.item_view_d_radix.is(":checked");
obj.inner = undefined;
}
append() {
let obj = this;
let sh_ic = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZ);
let calculate_length = sh_ic.store.length;
if ( obj.count <= calculate_length ) {
obj.append_line(calculate_length);
}
}
make_header(store_ic,store_ic_dash) {
let obj = this;
let ic = store_ic[0];
let ic_dash = undefined;
if ( store_ic_dash != undefined ) {
ic_dash = store_ic_dash[0];
}
let radix = Number(ic.radix);
let td_array = [];
let item_array = [];
let class_array = [];
if ( obj.step == true ) {
td_array.push("ic_th");
item_array.push("STEP");
class_array.push("ic_item_step");
}
if ( obj.n == true ) {
td_array.push("ic_th");
item_array.push("n(10進数)");
class_array.push("ic_item_n");
}
if ( (obj.n_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_th");
item_array.push("n("+radix+"進数)");
class_array.push("ic_item_n_radix");
}
if ( obj.calc == true ) {
td_array.push("ic_th");
item_array.push("演算式(10進数)");
class_array.push("ic_item_calc");
}
if ( (obj.calc_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_th");
item_array.push("演算式("+radix+"進数)");
class_array.push("ic_item_calc_radix");
}
if ( ic_dash != undefined ) {
//以下のradixは正しくはic_dash.radixなのだが同じなので処理を省く
if ( obj.n_dash == true ) {
td_array.push("ic_th_dash");
item_array.push("n'(10進数)");
class_array.push("ic_item_n_dash");
}
if ( (obj.n_dash_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_th_dash");
item_array.push("n'("+radix+"進数)");
class_array.push("ic_item_n_dash_radix");
}
if ( obj.d == true ) {
td_array.push("ic_th_dash");
item_array.push("d(10進数)");
class_array.push("ic_item_d");
}
if ( (obj.d_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_th_dash");
item_array.push("d("+radix+"進数)");
class_array.push("ic_item_d_radix");
}
}
return {"mod":"HEAD","td":td_array,"item":item_array,"class":class_array};
}
make_line(count,store_ic,store_ic_dash) {
let obj = this;
let ic = store_ic[count];
let ic_dash = undefined;
if ( store_ic_dash != undefined ) {
ic_dash = store_ic_dash[count];
}
let radix = Number(ic.radix);
let td_array = [];
let item_array = [];
let class_array = [];
let add_class = "";
let width_val = HtVw.item_display_item_width.filter(':checked').val();
if ( width_val != "all" ) {
add_class = " ic_item_width_scroll";
}
if ( obj.step == true ) {
td_array.push("ic_td");
item_array.push(count);
class_array.push("ic_item_step"+add_class);
}
if ( obj.n == true ) {
td_array.push("ic_td");
item_array.push(ic.f.toString(10));
class_array.push("ic_item_n"+add_class);
}
if ( (obj.n_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_td");
item_array.push(ic.f.toString(radix));
class_array.push("ic_item_n_radix"+add_class);
}
let mod = IC_MOD_ZERO;
if ( ic.mod != 0n ) {
mod = IC_MOD_NON_ZERO;
}
let h = undefined;
let m = undefined;
let f = undefined;
if ( (obj.calc == true) ||
((obj.calc_radix == true) &&
((2 <= radix) && (radix <= 36) && (radix != 10)) ) ) {
if ( mod == IC_MOD_ZERO ) {
f = ic.f / BigInt(radix);
} else {
h = ic.k * ic.f;
m = BigInt(radix) - (h % BigInt(radix));
f = h + m;
}
}
if ( obj.calc == true ) {
td_array.push("ic_td");
if ( mod == IC_MOD_ZERO ) {
item_array.push(
mod+":f="+ic.f.toString(10)+"/"+radix+"="+f.toString(10)+
"");
} else {
item_array.push(
mod+
":h="+ic.k.toString(10)+"*"+ic.f.toString(10)+"="+h.toString(10)+
":m="+radix+"-("+h.toString(10)+" mod "+radix+")="+m.toString(10)+
":f="+h.toString(10)+"+"+m.toString(10)+"="+f.toString(10)+
"");
}
class_array.push("ic_item_calc"+add_class);
}
if ( (obj.calc_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_td");
if ( mod == IC_MOD_ZERO ) {
item_array.push(
mod+":f="+ic.f.toString(radix)+"/"+radix.toString(radix)+"="+f.toString(radix)+
"");
} else {
item_array.push(
mod+
":h="+ic.k.toString(radix)+"*"+ic.f.toString(radix)+"="+h.toString(radix)+
":m="+radix.toString(radix)+"-("+h.toString(radix)+" mod "+radix.toString(radix)+")="+m.toString(radix)+
":f="+h.toString(radix)+"+"+m.toString(radix)+"="+f.toString(radix)
);
}
class_array.push("ic_item_calc_radix"+add_class);
}
if ( ic_dash != undefined ) {
//以下のradixは正しくはic_dash.radixなのだが同じなので処理を省く
if ( obj.n_dash == true ) {
td_array.push("ic_td_dash");
item_array.push(ic_dash.f.toString(10));
class_array.push("ic_item_n_dash"+add_class);
}
if ( (obj.n_dash_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_td_dash");
item_array.push(ic_dash.f.toString(radix));
class_array.push("ic_item_n_dash_radix"+add_class);
}
if ( obj.d == true ) {
td_array.push("ic_td_dash");
item_array.push(ic_dash.d.toString(10));
class_array.push("ic_item_d"+add_class);
}
if ( (obj.d_radix == true) &&
( (2 <= radix) && (radix <= 36) && (radix != 10) ) ) {
td_array.push("ic_td_dash");
item_array.push(ic_dash.d.toString(radix));
class_array.push("ic_item_d_radix"+add_class);
}
}
return {"mod":mod,"td":td_array,"item":item_array,"class":class_array};
}
append_line(calculate_length = 0) {}
redraw(taget_page = undefined) {}
text_copy() {};
}
//ViewColorクラス
class ViewColor extends SuperView {
constructor(mode = IC_TEXT_MODE_COLOR, page = 1) {
super();
let obj = this;
obj.mode = mode;
obj.page = page;
obj.page_count = 0;
obj.page_count_max = IC_DEFAULT_PAGE_COUNT_MAX;
obj.pager_up = jQuery("<table>",{ "class":"ic_list_pager", });
obj.pager_dw = jQuery("<table>",{ "class":"ic_list_pager", });
obj.inner = jQuery("<table>",{ "id":"ic_list_table","class":"ic_list_table", });
obj.before_max_step = 0;
HtVw.item_list.append(obj.pager_up);
HtVw.item_list.append(obj.inner);
HtVw.item_list.append(obj.pager_dw);
//
obj.pager = jQuery(".ic_list_pager");
obj.pager_max = IC_DEFAULT_PAGER_MAX;
let tr = jQuery("<tr>",{ "class":"ic_list_pager_tr", });
let td_pg = jQuery("<td>",{ "class":"ic_list_pager_td", "text":"ページ:", });
tr.append(td_pg);
//
let td_st = jQuery("<td>",{ "class":"ic_list_pager_td", });
let a_st = jQuery("<a>" ,{
"class":"ic_list_pager_a_start" ,
"onclick":"HtVw.ic_display_redraw('color',this); return false;",
"text":"0<<最初",
"data-page":"start",
}, );
td_st.append(a_st);
tr.append(td_st);
let td_pv = jQuery("<td>",{ "class":"ic_list_pager_td", });
let a_pv = jQuery("<a>" ,{
"class":"ic_list_pager_a_previos",
"onclick":"HtVw.ic_display_redraw('color',this); return false;",
"text":"<前",
"data-page":"previos",
}, );
td_pv.append(a_pv);
tr.append(td_pv);
//
for(let i=0; i<obj.pager_max; i++) {
let td = jQuery("<td>",{ "class":"ic_list_pager_td", });
let a = jQuery("<a>" ,{
"class":"ic_list_pager_a_content",
"onclick":"HtVw.ic_display_redraw('color',this); return false;",
"text":(i*obj.page_count_max)+"-"+(((i+1)*obj.page_count_max)-1),
"data-page":(i+1),
}, );
td.append(a);
tr.append(td);
}
//
let td_nx = jQuery("<td>",{ "class":"ic_list_pager_td", });
let a_nx = jQuery("<a>" ,{
"class":"ic_list_pager_a_next",
"onclick":"HtVw.ic_display_redraw('color',this); return false;",
"text":"次>",
"data-page":"next",
}, );
td_nx.append(a_nx);
tr.append(td_nx);
let td_ed = jQuery("<td>",{ "class":"ic_list_pager_td", });
let a_ed = jQuery("<a>" ,{
"class":"ic_list_pager_a_end" ,
"onclick":"HtVw.ic_display_redraw('color',this); return false;",
"text":"最後>>n",
"data-page":"end",
}, );
td_ed.append(a_ed);
tr.append(td_ed);
//
let td_sel_text = jQuery("<td>",{ "class":"ic_list_pager_td", "text":"指定ページ:", });
tr.append(td_sel_text);
let select = jQuery("<select>",{
"class":"ic_list_pager_sel",
"onchange":"HtVw.ic_display_redraw('color',this); return false;",
}, );
let option = jQuery("<option>" ,{
"class":"ic_list_pager_opt",
"text":"0-0",
"value":1,
"data-page":1,
}, );
select.append(option);
let td_sel = jQuery("<td>",{ "class":"ic_list_pager_td", });
td_sel.append(select);
tr.append(td_sel);
//
obj.pager.append(tr);
//
obj.pager_st = jQuery(".ic_list_pager_a_start");
obj.pager_pv = jQuery(".ic_list_pager_a_previos");
obj.pager_ct = jQuery(".ic_list_pager_a_content");
obj.pager_nx = jQuery(".ic_list_pager_a_next");
obj.pager_ed = jQuery(".ic_list_pager_a_end");
obj.pager_sl = jQuery(".ic_list_pager_sel");
}
append_td(item_hash,tdh) {
let obj = this;
let tr = jQuery("<tr>",{ "class":"ic_tr", });
jQuery.each(item_hash["item"], function(index,column) {
let td = jQuery("<"+tdh+">",{ "class":item_hash["td"][index]+"_"+item_hash["mod"], });
let cls = item_hash["class"][index];
let item = jQuery("<span>",{
"text" :column,
"class":cls,
});
if ( cls.match(/ic_item_n/) && !cls.match(/_radix/) && (column == "1") ) {
item.addClass("ic_item_GOAL");
}
td.append(item);
tr.append(td);
});
obj.inner.append(tr);
}
append_line(calculate_length) {
let obj = this;
let sh = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZ);
let store_ic = sh.store;
let store_ic_dash = undefined;
if (
( obj.n_dash == true ) ||
( obj.n_dash_radix == true ) ||
( obj.d == true ) ||
( obj.d_radix == true )
) {
store_ic_dash = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZCORRECT).store;
}
let count_start = (obj.page-1) * obj.page_count_max;
let page_end = obj.page_count_max;
let count_end = calculate_length - ((obj.page-1) * obj.page_count_max);
if ( count_end < page_end ) {
page_end = count_end;
}
for ( obj.page_count; obj.page_count<page_end; obj.page_count++) {
if ( obj.page_count == 0 ) {
let item_hash = obj.make_header(store_ic,store_ic_dash);
if ( item_hash["item"].length > 0 ) {
obj.append_td(item_hash,"th")
}
}
//
let item_hash = obj.make_line( count_start + obj.page_count, store_ic, store_ic_dash);
if ( item_hash["item"].length > 0 ) {
obj.append_td(item_hash,"td")
}
}
//ページャーの表示
obj.append_pager(calculate_length);
//最大値の背景色の更新(max値は変化するのでappend_tdではできない)
if ( (obj.before_max_step != sh.max_step) ) {
let n_max = jQuery(".ic_item_MAX");
if ( n_max.length > 0 ) {
n_max.removeClass("ic_item_MAX");
obj.before_max_step = 0;
}
if ( (count_start<=sh.max_step) && (sh.max_step<count_end) ) {
let item_n = jQuery(".ic_item_n");
jQuery.each(item_n, function(index) {
let item = jQuery(item_n[index]);
if ( item.text() == store_ic[sh.max_step].f ) {
item.addClass("ic_item_MAX");
obj.before_max_step = sh.max_step;
}
});
}
}
//同じ数値(IC_SAME_COUNT_N)がIC_DEFAULT_SAME_COUNT回発生 時の背景色更新
if ( HtVw.get_status() == IC_STATUS_COUNT_OVER ) {
let number_store_ic = sh.number_store;
let same_n = store_ic[store_ic.length-1].f;
let item_n = jQuery(".ic_item_n");
item_n.removeClass("ic_item_SAME");
jQuery.each(item_n, function(index) {
let item = jQuery(item_n[index]);
if ( item.text() == same_n ) {
item.addClass("ic_item_SAME");
}
});
}
}
append_pager(calculate_length = 0) {
let obj = this;
let pager_half = Math. floor(obj.pager_max/2);
let pager_last = Math. floor(calculate_length / obj.page_count_max);
if ( (calculate_length % obj.page_count_max) > 0 ) {
pager_last++;
}
let page_now = undefined;
if ( pager_last <= obj.pager_max ) {
page_now = 1;
} else {
page_now = obj.page - pager_half;
if ( page_now < 1 ) {
page_now = 1;
}
if ( (obj.page + pager_half) > pager_last ) {
page_now = (pager_last - obj.pager_max) +1;
}
}
obj.pager_ct.parent().addClass("ic_list_pager_hide");
obj.pager_ct.removeClass("ic_list_pager_select");
for ( let pager_count=0; pager_count<obj.pager_max; pager_count++) {
let count_start = (page_now-1)*obj.page_count_max;
let count_end = page_now*obj.page_count_max-1;
if ( count_end > calculate_length ) {
count_end = calculate_length-1;
}
let content_ct_up = jQuery(obj.pager_ct[pager_count]);
let content_ct_dw = jQuery(obj.pager_ct[pager_count+obj.pager_max]);
content_ct_up.text(count_start+"-"+count_end);
content_ct_dw.text(count_start+"-"+count_end);
content_ct_up.data("page",page_now);
content_ct_dw.data("page",page_now);
if ( page_now == obj.page ) {
content_ct_up.addClass("ic_list_pager_select");
content_ct_dw.addClass("ic_list_pager_select");
}
content_ct_up.parent().removeClass("ic_list_pager_hide");
content_ct_dw.parent().removeClass("ic_list_pager_hide");
//
page_now++;
if ( page_now > pager_last ) {
break;
}
}
if ( pager_last > obj.page ) {
obj.pager_ed.text("最後>>"+(calculate_length-1));
}
//
for ( let pager_count=1; pager_count<=pager_last; pager_count++) {
obj.pager_sl.each(function(index) {
let count_start = (pager_count-1)*obj.page_count_max;
let count_end = pager_count*obj.page_count_max-1;
if ( count_end > calculate_length ) {
count_end = calculate_length-1;
}
let sel = jQuery(obj.pager_sl[index]);
let opt = sel.children();
let content_opt = undefined;
if ( opt[pager_count-1] == undefined ) {
let option = jQuery("<option>" ,{
"class":"ic_list_pager_opt",
"text":count_start+"-"+count_end,
"value":pager_count,
"data-page":pager_count,
}, );
sel.append(option);
} else {
content_opt = jQuery(opt[pager_count-1]);
content_opt.text(count_start+"-"+count_end);
content_opt.data("page",pager_count);
}
});
//
}
}
redraw(taeget_page = 1) {
let obj = this;
//"start","previos","next","end"
let calculate_length = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZ).store.length;
let pager_last = Math. floor(calculate_length / obj.page_count_max);
if ( (calculate_length % obj.page_count_max) > 0 ) {
pager_last++;
}
let page = obj.page;
if ( taeget_page == "start" ) {
page = 1;
} else if ( taeget_page == "previos" ) {
page--;
if ( page < 1 ) {
page = 1;
}
} else if ( taeget_page == "next" ) {
page++;
if ( page > pager_last ) {
page = pager_last;
}
} else if ( taeget_page == "end" ) {
page = pager_last;
} else {
page = taeget_page;
}
if ( page == obj.page ) {
return;
}
obj.page = page;
obj.page_count = 0;
obj.before_max_step = 0;
//
obj.pager_sl.val(page);
//テーブルを消して再度追加
let tr = jQuery(".ic_tr");
tr.remove();
obj.append(); //インターバルタイマー経由のic_view使っても変わらないので簡単な処理とする
}
text_copy() {
let exec_flag = false;
let supportsDOMRanges = document.implementation.hasFeature("Range", "2.0");
if ( supportsDOMRanges == true ) {
let range = document.createRange();
let table = document.getElementById("ic_list_table");
if ( table != null ) {
window.getSelection().removeAllRanges(); //既に選択済みのものがあれば消す
range.selectNodeContents(table);
window.getSelection().addRange(range);
document.execCommand("copy");
window.getSelection().removeRange(range);
exec_flag = true;
}
} else {
window.alert("ブラウザが未対応のためコピーできませんでした。");
}
return exec_flag;
}
}
//ViewTextクラス
class ViewText extends SuperView {
constructor(mode = IC_TEXT_MODE_CSV, page = undefined) {
super();
let obj = this;
obj.mode = mode;
obj.inner = jQuery("<pre>",{ "id":"ic_list_inner","class":"ic_list_inner", });
HtVw.item_list.append(obj.inner);
}
append_line(calculate_length) {
let obj = this;
let store_ic = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZ).store;
let store_ic_dash = undefined;
if (
( obj.n_dash == true ) ||
( obj.n_dash_radix == true ) ||
( obj.d == true ) ||
( obj.d_radix == true )
) {
store_ic_dash = iCRM.get_store_hash(IC_CLASS_NAME_ICOLLATZCORRECT).store;
}
let count = undefined;
for ( count=obj.count; count<calculate_length; count++ ) {
if ( count == 0 ) {
obj.inner.append(
"r="+store_ic[count].radix.toString(10)+obj.mode+
"k="+store_ic[count].k.toString(10)+"\n");
let hash = obj.make_header(store_ic,store_ic_dash);
if ( hash["item"].length > 0 ) {
let str = hash["item"].join(obj.mode);
obj.inner.append(str+"\n");
}
}
//
let hash = obj.make_line(count,store_ic,store_ic_dash);
if ( hash["item"].length > 0 ) {
let str = hash["item"].join(obj.mode);
obj.inner.append(str+"\n");
}
}
obj.count = count;
}
redraw(taget_page = undefined) {
//インターバルタイマーにしたところで、
//全部描画するまで待つことになるので
//Rev1.0では実装見送り(呼び出すところも作ってない)
}
text_copy() {
if( !navigator.clipboard ) {
window.alert("クリップボードにコピーできませんでした。");
} else {
let copyText = document.querySelector(".ic_list_inner").textContent;
//非同期処理のため、成功失敗はこの時点ではわからない
navigator.clipboard.writeText(copyText).then(
function() {
window.alert("クリップボードにコピーしました。");
},
function() {
window.alert("クリップボードにコピーできませんでした。");
}
);
}
return false; //falseを返してメッセージを複数出さない
}
}
//-----------------------------------------------------------------------------
//function定義
//-----------------------------------------------------------------------------
jQuery(document).ready(function() {
//初期化
iCRM = new iCollatzResultManager();
HtVw = new HtmlView();
HtVw.ic_oninput();
//
jQuery("#ic_same_count").text(IC_DEFAULT_SAME_COUNT.toString(10));
jQuery("#ic_input").on("input", function() {
HtVw.ic_oninput();
});
jQuery("#ic_start").on("click", function() {
HtVw.ic_start_onclike();
});
jQuery("#ic_pause").on("click", function() {
HtVw.ic_pause_onclike();
});
jQuery("#ic_stop").on("click", function() {
HtVw.ic_stop_onclike();
});
jQuery("#ic_text_copy").on("click", function() {
HtVw.ic_text_copy_onclike();
});
jQuery("#ic_clear").on("click", function() {
HtVw.ic_clear_onclike();
});
//
jQuery("#ic_sponsor1").on("click", function() {
HtVw.ic_hide(this,"#ic_sponsor1_content");
});
jQuery("#ic_sponsor2").on("click", function() {
HtVw.ic_hide(this,"#ic_sponsor2_content");
});
jQuery("#ic_formula").on("click", function() {
HtVw.ic_hide(this,"#ic_formula_content");
});
jQuery("#ic_display").on("click", function() {
HtVw.ic_hide(this,"#ic_display_content");
});
//
jQuery("#ic_display_all_on").on("click", function() {
HtVw.ic_display_checkbox(this,true);
});
jQuery("#ic_display_all_of").on("click", function() {
HtVw.ic_display_checkbox(this,false);
});
jQuery("#ic_display_dash_all_on").on("click", function() {
HtVw.ic_display_checkbox(this,true);
});
jQuery("#ic_display_dash_all_of").on("click", function() {
HtVw.ic_display_checkbox(this,false);
});
//
jQuery("input:radio[id ^= 'ic_display_item_width']").on("change", function() {
HtVw.ic_display_item_width();
});
jQuery("input:radio[id ^= 'ic_display_line']").on("change", function() {
HtVw.ic_display_row();
});
});
//-----------------------------------------------------------------------------
icollatz.css
/* iCollatz演算ブラウザ(BigInt)版(iCCBE:Infinite Collatz Calculator BigInt Edition) */
/* $Id$ */
/* (C)2021-2023 プログラミングの深淵を求めて https://www.seekabypro.com/ */
/* (C)2021-2023 どらテク(どらぐ~んテクノロジー) https://twitter.com/dratech2020 */
body,
select,
#icollatz {
margin: 0px;
padding: 2px;
font-family: "MS ゴシック",monospace,Helvetica;
font-size: 12pt;
color: black;
background-color: white;
}
.ic_label {
line-height: 1.75em;
padding: 0.1em;
cursor: pointer;
border: 1px solid #CCCCCC;
border-radius: 0.25em;
user-select: none;
}
.ic_label:has(> input:checked) {
color: white;
text-shadow: 1px 1px 1px black;
background-color: #80A0FF;
}
.ic_label:hover {
border:1px solid #FF6600;
background-color:#FFFFCC;
border-radius: 0.25em;
}
#ic_radix,
#ic_k {
font-family: "MS ゴシック",monospace,Helvetica;
text-align: right;
width: 100px;
font-size: 12pt;
}
#ic_input {
font-family: "MS ゴシック",monospace,Helvetica;
text-align: right;
width: 400px;
font-size: 12pt;
}
#ic_start_input {
white-space: nowrap;
overflow: auto;
scrollbar-width: thin;
display: block;
}
#ic_start,
#ic_stop,
#ic_pause,
#ic_clear,
#ic_text_copy,
#ic_display_all_on,
#ic_display_dash_all_on {
border: 1px solid #606060;
border-radius: 0.25em;
}
#ic_start,
#ic_display_all_on,
#ic_display_dash_all_on {
color: #0000AA;
}
#ic_clear,
#ic_display_all_of,
#ic_display_dash_all_of {
color: #FF0000;
}
#ic_start:disabled,
#ic_stop:disabled,
#ic_pause:disabled {
background-color: #A0A0A0;
}
.ic_status,
.ic_goal_step,
.ic_goal_n_dash,
.ic_max_n ,
.ic_max_n_step ,
.ic_time,
.ic_display,
.ic_display_item_width,
.ic_display_line {
font-size: 12pt;
white-space: nowrap;
overflow: auto;
scrollbar-width: thin;
display: block;
}
.ic_display_icollatz,
.ic_display_icollatz_dash,
.ic_display_text_type,
.ic_display_item_width {
margin-bottom: 4px;
overflow: auto;
scrollbar-width: thin;
}
.ic_display_icollatz {
border:2px solid #000000;
}
.ic_display_icollatz_dash {
border:2px solid #008000;
}
.ic_display_text_type {
border:2px solid #CC00CC;
}
.ic_display_item_width {
border:2px solid #000000;
}
.ic_display_line {
border:2px solid #0000FF;
}
#ic_status {
text-shadow: 1px 1px 1px gray;
font-weight: bold;
}
#ic_count_mzr,
#ic_count_mnz,
#ic_goal_step,
#ic_max_n_step,
#ic_max_n {
text-shadow: 1px 1px 1px black;
font-weight: bold;
}
#ic_count_mzr {
color: #DDEBF7;
}
#ic_count_mnz {
color: #FFF2CC;
}
#ic_goal_step {
color: #C7A1E3;
}
#ic_max_n_step,
#ic_max_n {
color: #C6E0B4;
}
.ic_list {
margin: 0px;
padding: 2px;
font-size: 9pt;
border:2px solid #0000FF;
white-space: nowrap;
width: auto;
/* max-height: 480px; //js側 */
overflow: auto;
scrollbar-width: thin;
display: block;
}
.ic_list_table {
border-collapse: collapse;
border-spacing: 0;
border: none;
padding: 0px;
margin: 0px;
/* width: 100%; */
}
.ic_text_MZR {
color: #DDEBF7; /* IC_COLOR_MZR */
}
.ic_text_MNZ {
color: #DDEBF7; /* IC_COLOR_MZR */
}
.ic_text_OPERATOR {
color: #000080;
}
.ic_item,
.ic_head {
padding: 0px;
vertical-align: top;
}
.ic_tr,
.ic_th_HEAD,
.ic_td_MZR,
.ic_td_MNZ,
.ic_th_dash_HEAD,
.ic_td_dash_MZR,
.ic_td_dash_MNZ {
border:2px solid #000000;
vertical-align: top;
font-weight: normal;
text-align: right;
padding: 0px;
}
.ic_th_HEAD,
.ic_th_dash_HEAD {
text-align: center;
background-color: #BDD7EE; /* IC_COLOR_HEAD */
}
.ic_th_dash_HEAD,
.ic_td_dash {
border:2px solid #008000;
}
.ic_td_MZR,
.ic_td_dash_MZR {
background-color: #DDEBF7; /* IC_COLOR_MZR */
}
.ic_td_MNZ,
.ic_td_dash_MNZ {
background-color: #FFF2CC; /* IC_COLOR_MNZ */
}
.ic_item_step,
.ic_item_n,
.ic_item_n_radix,
.ic_item_calc,
.ic_item_calc_radix,
.ic_item_n_dash,
.ic_item_d,
.ic_item_n_dash_radix,
.ic_item_d_radix,
.ic_item_GOAL,
.ic_item_MAX,
.ic_item_SAME {
padding: 1px;
display: block;
vertical-align: top;
}
.ic_item_GOAL {
background-color: #C7A1E3; /* IC_COLOR_GOAL */
}
.ic_item_MAX {
background-color: #C6E0B4; /* IC_COLOR_N_MAX */
}
.ic_item_SAME {
background-color: #FF7F50; /* IC_COLOR_SAME */
}
.ic_item_width_scroll {
max-width: 140px;
overflow: auto;
scrollbar-width: thin;
}
.ic_item_hide_span {
cursor: pointer;
user-select: none;
}
.ic_item_hide_display {
display: none;
}
/*
.ic_list_pager_tr,
}
*/
.ic_list_pager_td {
padding:0.1em 0.4em 0.1em 0;
vertical-align: middle;
text-align: left;
white-space: nowrap;
}
.ic_list_pager_a_start,
.ic_list_pager_a_previos,
.ic_list_pager_a_content,
.ic_list_pager_a_next,
.ic_list_pager_a_end {
text-align:center;
margin:0 0.1em;
padding:0.1em 0.2em 0.08em 0.2em;
text-decoration:none;
box-shadow: none;
color:#555555;
border:1px solid #CCCCCC;
border-radius: 0.25em;
background-color:#FFFFFF;
user-select: none;
cursor: pointer;
}
.ic_list_pager_td a:hover {background-color:#FFCC99;}
.ic_list_pager_select {
color:#000000;
border:1px solid #000000;
background-color: #80A0FF;
}
.ic_list_pager_hide {
display: none;
}
.ic_list_pager_sel {
font-size: 9pt;
border: 1px solid #00AA00;
background-color: #FFFFFF;
text-align: right;
}
.ic_list_pager_opt {
direction: rtl;
}
#ic_formula_content img {
border: 2px solid blue;
}
#ic_formula_content>a:visited img{
border: 2px solid purple;
}
コメント