1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| function run(m){
//m(i,j), i représente la ligne et j la colonne
function M(i,j){
return m[i][j]
}
function P(i,j,v){
m[i][j]=v;
}
var nbGroupes=0;
var id=0;//le premier id que nous allouerons vaudra 1
for(var i = 0;i<m.length; ++i){
for(var j = 0;j<m[i].length; ++j){
if(M(i,j)==0)continue;
if(i==0){
if(j==0){
nbGroupes++;
id++
P(i,j,id)
}else{
//si i==0 on regarde pas les cases adjacentes du dessus... donc seul check sur case de gauche
if(M(i,j-1)){
P(i,j,M(i,j-1));
}else{
nbGroupes++;
id++
P(i,j,id)
}
}
}else{
if(j==0){
var oneOrOther = M(i-1,j)||M(i-1,j+1)
//si j==0 il y a au maximum une chaine
if(oneOrOther){
P(i,j,oneOrOther)
}else{
nbGroupes++;
id++
P(i,j,id)
}
}else{
//trois cas: nouvelle chaine, existe 1 chaine, existent deux chaines distinctes
var c1 = null;//représente la valeur de la première chaine
var c2 = null;
var candidates = [M(i,j-1), M(i-1,j-1), M(i-1,j), M(i-1,j+1)]; //resp à gauche et les trois du haut
candidates.forEach(x=>{
if(x==0)return;
if(c1==null||x==c1){
c1 = x;
}else{
c2=x;
}
})
if(c2){
//la chaine "c1" prend les coeffs de la chaine c2
//on ne considere que les coeff de la ligne courante avant lel courant
//ainsi que ceux depuis la colonne "à droite" de lel courant sur la ligne précédente
//car c'est le seul cas ou on peut avoir deux chaines distinctes
//0 0 2
//1 <- ^
nbGroupes--;
for(var j1 = 0; j1<=j; ++j1){
if(M(i,j1)==c1){
P(i,j1,c2)
}
}
for(var j1 = j+1; j1<m[i].length; ++j1){
if(M(i-1,j1)==c1){
P(i-1,j1)=c2
}
}
}else{
if(c1){
P(i,j,c1)
}else{
nbGroupes++
id++
P(i,j,id)
}
}
}
}
}
}
return nbGroupes;
}
//useless below
var assert = require('assert');
function test(s,exp){
var m = s.split('\n').map(x=>x.trim()).filter(x=>x.length).map(x=>x.split(/\s+/).map(y=>parseInt(y)));
assert.equal(run(m), exp);
return m;
}
/*
var m;
s = `
1 0 1
1 0 1
1 1 1
`;
test(s, 1)
s = `
1 0 1
0 1 1
0 1 0
`;
test(s, 1)
s = `
1 0 1
0 0 0
0 1 0
`;
test(s, 3)
s = `
1 0 1
0 0 0
0 1 0
`;
test(s, 3)
s =`
1 0 0 1
1 1 1 0
0 0 1 0
1 0 0 0
`
test(m,2)
s =`
1 0 0 1
1 0 1 0
0 0 1 0
1 0 0 0
`
test(s,3)*/
s = `
1 1 0 1
1 1 0 1
0 0 1 0
1 0 0 0
`
console.log(test(s, 2))//merge deux chaines |
Partager