プロが教えるわが家の防犯対策術!

HTML の <table> 系に出力するものとして、
0000 から 9999 を作りたいが、
1. 縦軸に各桁の同じ合計値を並べたい。


0010
0019
0028

2. 桁に表示されている数値を最小値でまとめたい

0001 があるなら、次の値は不用。0010 0100 1000

Javascript だとどのようなプログラムになりますか ?

ぜひ、教えてください !

質問者からの補足コメント

  • 縦のラインに、他の合計数のものが並んでいます。
    1 ラインに 1 つの合計値が望ましいです。

      補足日時:2022/09/17 21:03

A 回答 (6件)

こんなふうでしょうか。



<script>
/**
* HTML の <table> 系に出力する (1)
* 0000 から 9999 を作りたい (2)
* 1. 縦軸に各桁の同じ合計値を並べたい (3)
* 2. 桁に表示されている数値を最小値でまとめたい (4)
*/

// (2)
const array = new Array(10000).fill(0).map((_, i) => i.toString().padStart(4, '0'));
// (4)
const array2 = array.filter(v => {
const b = v.split('');
return !(b[0] > b[1] || b[1] > b[2] || b[2] > b[3]);
});
// (3)
const result = [];
array2.forEach(v => {
const sum = v.split('').reduce((p, c) => p * 1 + c * 1);
if(!result[sum]) {
result[sum] = [];
}
result[sum].push(v);
});
console.log(result);
// (4)
const table = document.createElement('table');
const tHead = table.createTHead();
const tBody = table.createTBody();

const headTr = tHead.insertRow(-1);
result.forEach((_, i) => {
headTr.appendChild(Object.assign(
document.createElement('th'),
{
textContent: i.toString().padStart(4, '0'),
style: 'border-bottom: thin solid #333;'
}
));
});

const rowLength = result.reduce((p, c) => Math.max(p, c.length), 0);
for (let i = 0; i < rowLength; i++){
const bodyTr = tBody.insertRow(-1);
result.forEach(v => {
const td = bodyTr.insertCell(-1);
td.textContent = v[i] ?? '';
});
}

document.body.appendChild(table);
</script>
    • good
    • 1
この回答へのお礼

回答ありがとうございます。

お礼日時:2022/09/18 17:37

No2です。



>縦のラインに、他の合計数のものが並んでいます。
>1 ラインに 1 つの合計値が望ましいです。
確認しましたが、同じ数しか並んでいませんね。
(そうなるようにしたはずなので、当然ですが・・)

<確認処理>
tbl.querySelectorAll('td').forEach( e => {
const t = e.textContent;
if(t.length > 3 ){
let s = t * 1;
while(s > 9) s = (s + '').split('').reduce((a, b) => a*1 + b*1, 0);
e.textContent = t + `(${s})`;
}
});


桁の合計を1回しか行わないという意味なら、ご提示の例がミスディレクションなのか、普通では推測できない特殊なルールになっているものと想像します。
(こちらでは、どのようなルールなのか判断できません)

単純に1度しか各桁の加算を行わないという意味なら、分類の数(=列数)を n*9+1 にして、加算を1度だけ行うように修正すればそのような結果になります。
(37列からなる横長の表になります)

とはいえ、もともとのご質問が、
>Javascript だとどのようなプログラムになりますか ?
なので、似たものになっていれば、例示としては十分なのかなとも思いますけれど・・
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2022/09/18 17:36

#3です


訂正
B.forEach (a=> C[a.reduce (sum, 0) % 10].push (a.join``.padStart (4,0)));

今気づく、なんだか Fujillin さんと結果(最後の方)が違う
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2022/09/17 19:30

面白そうだったので。


sort を使わないので速いと思ふ。
短くしたので理解しやすいと思いますが、されることはないでしょう。


<!DOCTYPE html>
<title></title>
<meta charset="utf-8">
<style>
td { text-align: right; width: 6em;}
</style>
<body>
<table border="1" id="T"></table>

<script>
const
//配列を表に
ary2tbody=(a,b=document.createElement('tbody'))=>a.reduce((b,a)=>(a.reduce((c,d)=>(c.insertCell().append(d||''),c),b.insertRow()),b),b),
//配列の転置
transpose=a=>a[0].map((_,i)=>a.map(b=>b[i])),
//組み合わせ
mathematics=((f=(a=[],b=a.length)=>b==1?a.map(c=>[c]):a.flatMap((c,d)=>f(a.slice(d),b-1).map(d=>[c,...d])))=>f)(),
//加算
sum=(a,b)=>a+b;


const A = [1, 2, 3, 4, 5, 6, 7, 8, 9];//0は無視
const B = [[0], ...mathematics (A,1), ...mathematics (A,2), ...mathematics (A,3), ...mathematics (A,4)];//1-4桁の組み合わせ
const C = [...Array(10)].map (()=>[]);//配列の初期化

B.forEach (a=> C[i = a.reduce (sum, 0) % 10].push (a.join``.padStart (4,0)));//桁の合計をインデクスにして4桁の文字列を生成
ary2tbody (transpose(C), T);//転置して表にする

</script>
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2022/09/17 19:30

No1です。



無駄に変数を使ってたのと、誤記があったので訂正しておきます。
 誤 : 結果は 0~9 の9列に~
 正 : 結果は 0~9の10列に~


const n = 4; // 桁数
const pad = '0'.repeat(n);
const T = [...new Array(10)].map(e => new Object());
let i, mx = 0;

for(i = 0; i < Math.pow(10, n); i++){
const v = (pad + i).substr(-n).split('').sort().join('');
let s = v * 1;
while(s > 9) s = (s + '').split('').reduce((a, b) => a*1 + b*1, 0);
T[s][v] = 1;
}
T.forEach((e, i) => {
T[i] = Object.keys(e).sort();
mx = Math.max(mx, T[i].length);
});

const tbl = document.querySelector('body').appendChild(
document.createElement('table')).createTBody();
tbl.parentNode.border = 1;
for(i = 0; i < mx; i++){
const td = T.map( e => `<td>${e[i] || ' '}</td>`).join('');
tbl.insertAdjacentHTML('beforeend', `<tr>${td}</tr>`);
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2022/09/17 19:29

こんばんは



>例
>0010
>0019
>0028
普通に各桁を加算すると、1、10、10となって一致しませんけれど・・
一桁になるまで同じ操作を繰り返して、10→1 と評価するってことでしょうかね。
そう考えるなら、結果は 0~9 の9列に並べればよいということと解釈しました。

以下は、書きっぱなしのままなのであまり効率は良くないかもしれませんが、一応、結果は得られますので、ご参考までに。

const n = 4; // 桁数
const pad = '0'.repeat(n);
const R = [];
const T = [...new Array(10)].map(e => new Object());
let i, mx = 0;

for(i = 0; i < Math.pow(10, n); i++){
const v = (pad + i).substr(-n).split('').sort().join('');
let s = v * 1;
while(s > 9) s = (s + '').split('').reduce((a, b) => a*1 + b*1, 0);
T[s][v] = 1;
}

for(i = 0; i < T.length; i++){
R[i] = Object.keys(T[i]).sort();
mx = mx<R[i].length? R[i].length:mx;
}

const tbl = document.querySelector('body').appendChild(
document.createElement('table')).createTBody();
tbl.parentNode.border = 1;
for(i = 0; i < mx; i++){
const td = R.map( e => `<td>${e[i] || ''}</td>`).join('');
tbl.insertAdjacentHTML('beforeend', '<tr>' + td + '</tr>');
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2022/09/17 19:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!