Порахуйте, скільки послідовностей відстань далекі від усіх інших


13

Відстань Хеммінга між двома струнами однакової довжини - це кількість позицій, на яких відповідні символи різні.

Дозвольте Pбути двійковим рядком довжини nі Tбути двійковим рядком довжини 2n-1. Ми можемо обчислити nвідстані Хеммінга між підрядками Pі nдовжиною кожної довжини, Tщоб перейти зліва направо і скласти їх у масив (або список).

Приклад послідовності дистанції Хеммінга

Нехай P = 101і T = 01100. Послідовність відстаней Хеммінга, яку ви отримуєте від цієї пари, становить 2,2,1.

Визначення близькості

Тепер розглянемо дві такі послідовності відстаней Хеммінга. Скажіть x = (0, 2, 2, 3, 0)і y = (2, 1, 4, 4, 2)як приклади. Ми це кажемо xі yє, closeякщо y <= x <= 2*yчи якщо x <= y <= 2*x. Тут скалярне множення та нерівність взяті елементарно. Тобто для двох послідовностей Aі B, A <= B iff A[i] <= B[i]за всіма показниками i.

Зауважимо, що послідовності відстаней Хеммінга утворюють частковий порядок при такому способі їх порівняння. Іншими словами, багато пар послідовностей не є ні більшими, ні рівними, ні меншими або рівними один одному. Наприклад (1,2)і (2,1).

Отже, використовуючи приклад вище, (0, 2, 2, 3, 0) <= 2*(2, 1, 4, 4, 2) = (4, 2, 8, 8, 4)але (0, 2, 2, 3, 0)не більший за (2, 1, 4, 4, 2). Також (2, 1, 4, 4, 2)не менше або дорівнює 2*(0, 2, 2, 3, 0) = (0, 4, 4, 6, 0). В результаті xі yне наближаються один до одного.

Завдання

Для збільшення nпочинаючи з початку n=1, розглянемо всі можливі пари двійкових рядків Pдовжини nта Tдовжини 2n-1. Є 2^(n+2n-1)такі пари і, отже, багато послідовностей дистанцій Хеммінга. Однак багато з цих послідовностей будуть ідентичними. Завдання полягає в тому, щоб знайти розмір найбільшого набору послідовностей дистанцій Хеммінга, щоб жодна дві послідовності не були близькими одна до одної.

Ваш код повинен виводити одне число на значення n.

Оцінка

Ваш результат загалом відповідає найвищому nкоду, який ви досягаєте на моїй машині за 5 хвилин (але читайте далі). Час призначений для загального часу роботи, а не часу лише для цього n.

Для того, щоб дати бали за неоптимальні відповіді, оскільки знайти оптимальні відповіді, ймовірно, буде важко, нам знадобиться трохи тонка система балів. Ваш бал - це найвище значення, nза яке ніхто більше не опублікував більш правильну відповідь будь-якого розміру, меншого, ніж рівний цьому. Наприклад, якщо ви виходите, 2, 4, 21а хтось інший виходить, 2, 5, 15ви б набрали результат лише тоді, 1коли хтось має кращу відповідь n = 2. Якщо ви виходите з 2, 5, 21цього результату, ви б оцінювали 3незалежно від того, що хтось ще виводить, тому що всі відповіді оптимальні. Зрозуміло, що якщо у вас є всі оптимальні відповіді, ви отримаєте бал за найвищу nпосаду. Однак, навіть якщо ваша відповідь не є оптимальною, ви все одно можете отримати бал, якщо ніхто більше не може його перемогти.

Приклад відповідей та відпрацьований приклад

(Ця відповідь поки не перевірена. Незалежна перевірка буде вдячна.)

Завдяки ETHproductions:

  • n = 1 дає 2.
  • n = 2 дає 5.
  • n = 3 дає 21.

Розглянемо n = 2докладніше. У цьому випадку повний перелік послідовностей дистанцій Хеммінга (представлений тут кортежами):

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

Ми можемо бачити, що (0,0)це не близько до жодного іншого кортежу. Справді , якщо ми візьмемо (0, 0), (0, 1), (1, 0), (2, 1), (1,2)то жоден з цих кортежів не близькі до якої - небудь з інших. Це дає бал 5за n = 2.

Для n = 3отримання повного списку різних послідовностей відстані Хеммінга є:

 [(0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 1), (0, 2, 2), (0, 2, 3), (0, 3, 0), (0, 3, 1), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 3, 0), (1, 3, 1), (1, 3, 2), (2, 0, 1), (2, 0, 2), (2, 0, 3), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 2, 0), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 3, 1), (2, 3, 2), (2, 3, 3), (3, 0, 2), (3, 0, 3), (3, 1, 0), (3, 1, 1), (3, 1, 2), (3, 2, 0), (3, 2, 1), (3, 2, 2), (3, 3, 2), (3, 3, 3)]

З цих 48послідовностей ми можемо вибрати набір розмірів, 21щоб жодна пара в цьому наборі не була близько одна до одної.

Мови та бібліотеки

Ви можете використовувати будь-яку доступну мову та бібліотеки, які вам подобаються. Там, де це можливо, було б добре запустити свій код, тому, будь-ласка, включіть повне пояснення, як запустити / скомпілювати свій код в Linux, якщо це можливо.

Моя машина Часи синхронізації будуть працювати на моїй 64-розрядної машини. Це стандартна установка ubuntu з 8 ГБ оперативної пам’яті, AMD FX-8350 восьмиядерний процесор та Radeon HD 4250. Це також означає, що мені потрібно мати можливість запускати ваш код.

Провідна відповідь

  • Оцінка 4 для 2, 5, 21, 83, 361 Крістіан Сіверс. C ++
  • Оцінка 5 за 2, 5, 21, 83, 372 від fəˈnɛtɪk. Javascript

Переглянувши ваше запитання, він показує деякі схожість із шпигунами, переглянутіми на hackerrank, що є повною проблемою
fəˈnɛtɪk

@ fəˈnɛtɪk Чудово! Зауважте, що моє запитання не потребує оптимальних рішень, щоб отримати хороший бал.

@ fəˈnɛtɪk Чи можете ви також підтвердити відповіді на 1,2,3 у запитанні?

@ fəˈnɛtɪk Я дуже сумніваюся, що це NP-важко. Вам доведеться кодувати Set Packing або іншу задачу, повну NP-одиницю, в одне ціле число з лише поліноміальною зміною розміру проблеми.

297 унікальних масивів
забивання

Відповіді:


5

C ++ за допомогою бібліотеки igraph

Дякуємо за приємну можливість дізнатися нову бібліотеку!

Зараз ця програма 2, 5, 21, 83, 361швидко обчислює . Ви можете керувати друком вузлів PRINTNODESпостійною.

Використовуваний графік має додаткові ребра між вузлами, що відповідають векторам відстані, де один знаходиться поблизу (але не дорівнює) другому зворотному. Це прискорює обчислення, і будь-який знайдений незалежний набір, звичайно, також є одним з оригінальних графіків. Крім того, навіть якщо воно не виконане повністю, обчислений незалежний набір закривається під час реверсії. Я вважаю, що завжди існує максимальний незалежний набір з цією властивістю. Принаймні, є один для n<=4. (Я впевнений, що можу показати 83, це оптимально.)

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<igraph.h>

using vect = std::vector<int>;

constexpr int MAXDIRECT=100;
constexpr int PRINTNODES=1;

std::set<int> avoid{};
igraph_t graph;
std::vector<vect> distance_vectors{};
int count;

int close_h(const vect &a, const vect &b ){
  // check one direction of the closeness condition
  for(auto i=a.begin(), j=b.begin(); i!=a.end(); i++,j++)
    if ( (*i > *j) || (*j > 2 * *i))
      return 0;
  return 1;
}

int close(const vect &a, const vect &b ){
  return close_h(a,b) || close_h(b,a);
}

vect distances(int n, int p, int t){
  vect res{};
  for (int i=0; i<n; ++i){
    int count = 0;
    for (int j=0; j<n; ++j)
      count += 1 & ((p>>j)^(t>>j));
    res.push_back(count);
    t >>= 1;
  }
  return res;
}

void print_vect( vect &v ){
  std::cout << "(";
  auto i=v.begin();
  std::cout << *i++;
  for( ; i!=v.end(); ++i)
    std::cout << "," << *i ;
  std::cout << ")\n";
}

void use_node( int n ){
  if(PRINTNODES)
    print_vect( distance_vectors[n] );
  ++count;
  avoid.insert( n );
  igraph_vector_t neighs;
  igraph_vector_init( &neighs, 0 );
  igraph_neighbors( &graph , &neighs, n, IGRAPH_OUT );
  for(int i=0; i<igraph_vector_size( &neighs ); ++i)
    avoid.insert( VECTOR(neighs)[i] );
  igraph_vector_destroy( &neighs );
}

void construct(int n){
  std::set<vect> dist_vects;
  for(int p=0; p>>n == 0; ++p)
    for(int t=0; t>>(2*n-2) == 0; ++t)   // sic! (because 0/1-symmetry)
      dist_vects.insert(distances(n,p,t));
  int nodes = dist_vects.size();
  std::cout << "distinct distance vectors: " << nodes << "\n";

  distance_vectors.clear();
  distance_vectors.reserve(nodes);
  std::copy(dist_vects.begin(), dist_vects.end(),
            back_inserter(distance_vectors));

  igraph_vector_t edges;
  igraph_vector_init( &edges, 0 );
  igraph_vector_t reversed;
  igraph_vector_init_seq( &reversed, 0, nodes-1 );
  for (int i=0; i<nodes-1; ++i){
    vect &x = distance_vectors[i];
    vect xr ( x.rbegin(), x.rend() );
    for(int j=i+1; j<nodes; ++j){
      vect &y = distance_vectors[j];
      if( xr==y ){
        VECTOR(reversed)[i] = j;
        VECTOR(reversed)[j] = i;
      }else if( close( x, y ) || close( xr, y) ){
        igraph_vector_push_back(&edges,i);
        igraph_vector_push_back(&edges,j);
      }
    }
  }
  std::cout << "edges: " << igraph_vector_size(&edges)/2 << "\n";

  igraph_create( &graph, &edges, nodes, IGRAPH_UNDIRECTED);
  igraph_vector_destroy( &edges );

  igraph_cattribute_VAN_setv( &graph, "r", &reversed );
  igraph_vector_destroy( &reversed );

  igraph_vector_t names;
  igraph_vector_init_seq( &names, 0, nodes-1 );
  igraph_cattribute_VAN_setv( &graph, "n", &names );
  igraph_vector_destroy( &names );

}

void max_independent( igraph_t *g ){
  igraph_vector_ptr_t livs;
  igraph_vector_ptr_init( &livs , 0 );
  igraph_largest_independent_vertex_sets( g, &livs );

  igraph_vector_t *nodes = (igraph_vector_t *) VECTOR(livs)[0];
  igraph_vector_t names;
  igraph_vector_init( &names, 0 );
  igraph_cattribute_VANV( g, "n", igraph_vss_vector( nodes ), &names );

  for(int i=0; i<igraph_vector_size(&names); ++i)
    use_node( VECTOR(names)[i] );
  igraph_vector_destroy( &names );
  igraph_vector_ptr_destroy_all( &livs );
}

void independent_comp( igraph_t *g );

void independent( igraph_t *g ){
  if(igraph_vcount( g ) < MAXDIRECT){
    max_independent( g );
    return;
  }
  igraph_vector_ptr_t components;
  igraph_vector_ptr_init( &components, 0 );
  igraph_decompose( g, &components, IGRAPH_WEAK, -1, 1);
  for(int i=0; i<igraph_vector_ptr_size( &components ); ++i)
    independent_comp( (igraph_t *) VECTOR(components)[i] );
  igraph_decompose_destroy( &components );
}

void independent_comp( igraph_t *g ){
  if (igraph_vcount( g ) < MAXDIRECT){
    max_independent( g );
    return;
  }
  igraph_vector_t degs;
  igraph_vector_init( &degs, 0 );
  igraph_degree( g, &degs, igraph_vss_all(), IGRAPH_OUT, 1 );
  int maxpos = igraph_vector_which_max( &degs );
  igraph_vector_destroy( &degs );  

  int name = igraph_cattribute_VAN( g, "n", maxpos );
  int revname = igraph_cattribute_VAN( g, "r", maxpos );
  int rev = -1;
  if(name!=revname){
    igraph_vector_ptr_t reversed_candidates_singleton;
    igraph_vector_ptr_init( &reversed_candidates_singleton, 0 );
    igraph_neighborhood( g, &reversed_candidates_singleton,
                         igraph_vss_1(maxpos), 2, IGRAPH_OUT );
    igraph_vector_t * reversed_candidates =
      (igraph_vector_t *) VECTOR(reversed_candidates_singleton)[0];
    igraph_vector_t names;
    igraph_vector_init( &names, 0 );
    igraph_cattribute_VANV( g, "n", igraph_vss_vector( reversed_candidates ),
                        &names );
    long int pos;
    igraph_vector_search( &names, 0, revname, &pos );
    rev = VECTOR(*reversed_candidates)[pos];
    igraph_vector_destroy( &names );
    igraph_vector_ptr_destroy( &reversed_candidates_singleton );
  }
  igraph_vs_t delnodes;
  igraph_vs_vector_small( &delnodes, maxpos, rev, -1 );
  igraph_delete_vertices( g, delnodes );
  igraph_vs_destroy( &delnodes );

  independent( g );
}

void handle(int n){
  std::cout << "n=" << n << "\n";
  avoid.clear();
  count = 0;
  construct( n );
  independent( &graph );
  // try all nodes again:
  for(int node=0; node<igraph_vcount( &graph ); ++node)
    if(avoid.count(node)==0)
      use_node(node);
  std::cout << "result: " << count << "\n\n";
  igraph_destroy( &graph );
}

int main(){
  igraph_i_set_attribute_table( &igraph_cattribute_table );
  for(int i=1; i<6; ++i)
    handle(i);
}

Для компіляції на debian встановіть libigraph0-devі зробіть g++ -std=c++11 -Wall -O3 -I/usr/include/igraph -o ig ig.cpp -ligraph.

Старий опис:

Бібліотека igraph має функцію для обчислення максимального розміру незалежного набору вершин графа. Він може вирішити цю проблему n=3менше ніж за секунду і не припиняється протягом днів n=4.

Тож, що я роблю, - це розкласти графік на підключені компоненти, і дозволити бібліотеці обробляти невеликі (менше, ніж MAXDIRECTвузли) компоненти. Для інших компонентів я вибираю вершину і видаляю її. У кращому випадку це розбиває графік на кілька компонентів, але зазвичай це не так. У будь-якому випадку компоненти (можливо, лише один) менше, і ми можемо використовувати рекурсію.

Очевидно важливим є вибір вершини. Я просто приймаю максимальну ступінь. Я виявив, що отримую кращий результат (але лише для n=4), коли використовую перевернутий список вузлів. Це пояснює магічну частину constructфункції.

Можливо, варто покращити вибір. Але видається важливішим переглянути вилучені вузли. Зараз я більше ніколи на них не дивлюся. Деякі з них можуть бути не з'єднані з будь-яким із вибраних вузлів. Проблема полягає в тому, що я не знаю, які вузли утворюють незалежний набір. Для одного, видалення вузлів перенумерує інші вузли. З цим можна вирішити, додавши до них атрибути. Але ще гірше, що обчислення числа незалежності якраз і дає це число. Найкращою альтернативою, яку пропонує бібліотека, є обчислення всіх найбільших незалежних наборів, що повільніше (наскільки, здається, залежить від розміру графіка). Але все-таки це здається найближчим шляхом. Набагато невиразніше, я також думаю, що може бути корисним врахувати, чи можемо ми використовувати спеціальний спосіб визначення графіка.

Справа n=6може стати доступною (зовсім не обов'язково за 5 хвилин), якщо я заміню рекурсію циклом, використовуючи чергу для решти компонентів.

Мені було цікаво подивитися на компоненти графіків. Бо n=4їх розміри такі 168, 2*29, 2*28, 3, 4*2, 4*1. Тільки з найбільшою не можна звертатися безпосередньо.

Бо n=5розміри є 1376, 2*128, 2*120, 119, several <=6.

Я очікую, що ці подвійні розміри відповідають графікам ізоморфних, але використовувати це не здається, тому що завжди є один домінуючий найбільший компонент:

Бо n=6найбільший компонент містить 11941вузли (із загальної кількості 15425), наступні два найбільші компоненти мають розмір 596.

Бо n=7ці числа є 107593 (125232), 2647.


Чи можете ви дозволити мені знати, що таке набір для 83, я хочу знати, чому мій алгоритм не набирає такого високого значення для 4, але якось стає вище за 5: P
fəˈnɛtɪk

Це має бути g++ -std=c++11 -Wall -O3 -I/usr/include/igraph -o sievers sievers.cpp -ligraph. Важливо, де -ligraphзнаходиться.

@ChristianSievers Як працює генерація ребер у коді?
fəˈnɛtɪk

@ChristianSievers Мені було цікаво, як він визначає, до чого повинна підключатися кожна вершина. Зворотний масив може бути викруткою.
fəˈnɛtɪk

@ fəˈnɛtɪk Вектори відстані, здається, відсортовані від setя використовую, щоб уникнути дублікатів, але я навіть не думав про їх впорядкування, коли писав цей код. Внутрішня петля, що починається i+1просто, дозволяє уникнути перегляду пари, а також її заміненої версії, яка не потрібна, і це найпростіший спосіб уникнути циклів (ребер (a,a)). Це не залежить від того, в якому порядку надходять вузли, мені все одно, чи я отримаю (a,b)або (b,a).
Крістіан Сіверс

3

Javascript, послідовність даних: 2,5,21, 81 83,372 67,349

Вдалося збільшити значення для 4, використовуючи випадкове видалення елементів на початку мого пошуку. Як не дивно, видалення 20 елементів з більш ніж 6 з'єднаннями було швидше, ніж видалення 5 елементів з більш ніж 8 з'єднаннями ...

Ця послідовність, ймовірно, не є оптимальною для 5 і може бути не оптимальною для 4. Жоден із вузлів не є близьким до іншого в наборі.

Код:

input=4;
maxConnections=6;
numRand=20;

hammings=[];
h=(x,y)=>{retVal=0;while(x||y){if(x%2!=y%2)retVal++;x>>=1;y>>=1}return retVal};
for(i=1<<(input-1);i<1<<input;i++){
  for(j=0;j<1<<(2*input);j++){
    hamming=[];
    for(k=0;k<input;k++){
      hamming.push(h((j>>k)%(1<<input),i));
    }
    equal=0;
    for(k=0;k<hammings.length;k++){
      if(hamming.join("")==hammings[k].join("")){
        equal=1;
        break;
      }
    }
    if(!equal)hammings.push(hamming);
  }
}
adjMat=[];
for(i=0;i<Math.pow(input+1,input);i++){
  row=[];
  for(j=0;j<Math.pow(input+1,input);j++){
    row.push(0);
  }
  adjMat.push(row);
}
nodes=[]
for(i=0;i<Math.pow(input+1,input);i++){
  nodes[i]=0;
}
for(i=0;i<hammings.length;i++){
  sum=0;
  chkNodes=[[]];
  for(j=0;j<input;j++){
    chkVal=[];
    t=Math.pow(input+1,j);
    sum+=t*hammings[i][j];
    tmp=[];
    for(r=0;r<chkNodes.length;r++){
      for(k=hammings[i][j];k<=Math.min(hammings[i][j]*2,input);k++){
        stor=[]
        for(s=0;s<chkNodes[r].length;s++){
          stor.push(chkNodes[r][s])
        }
        stor.push(k)
        tmp.push(stor);
      }
    }
    chkNodes=[];
    for(r=0;r<tmp.length;r++){
      chkNodes.push(tmp[r])
    }
  }
  nodes[sum]=1;
  for(j=0;j<chkNodes.length;j++){
    adjSum=0
    for(k=0;k<input;k++){
      adjSum+=Math.pow(input+1,k)*chkNodes[j][k]
    }
    if(adjSum!=sum)adjMat[sum][adjSum]=adjMat[adjSum][sum]=1
  }
}
t=nodes.length;
for(i=0;i<t;i++){
  if(!nodes[i]){
    for(k=0;k<t;k++){
      adjMat[i][k]=adjMat[k][i]=0
    }
  }
}
sum=(a,b)=>a+b;
console.log(nodes.reduce(sum))
connections=x=>x.reduce(sum)
counts=adjMat.map(connections);
stor=[];
for(i=0;i<t;i++){
  stor.push(nodes[i]);
}
maxRemainder=0;

greater=[]
for(i=0;i<t;i++){
  if(nodes[i]&&counts[i]>maxConnections){
    greater.push(i);
  }
}

if(input==4){
  for(w=0;w<greater.length*numRand;w++){
    for(i=0;i<t;i++){
      nodes[i]=stor[i];
    }
    counts=adjMat.map(connections);
    toRemove=Math.floor(Math.random()*numRand*2)
    for(i=0;i<toRemove&&i<greater.length;i++){
      rand=Math.floor(Math.random()*greater.length);
      if(nodes[greater[rand]]){
        nodes[greater[rand]]=0;
        for(j=0;j<t;j++){
          if(adjMat[rand][j]){
            counts[j]--;
          }
        }
      }
    }

    for(i=0;i<t*t;i++){
      max=0;
      maxLoc=0;
      for(j=0;j<t;j++){
        if(counts[j]>=max&&nodes[j]){
          max=counts[j];
          maxLoc=j;
        }
      }
      if(max>0){
        for(j=0;j<t;j++){
          if(adjMat[maxLoc][j]){
            counts[j]--;
            if(counts[j]<max-1&&stor[j]&&!nodes[j]){
              nodes[j]=1;
              for(k=0;k<t;k++){
                if(adjMat[j][k])counts[k]++;
              }
            }
          }
          nodes[maxLoc]=0;
        }
      }
      else{
        break;
      }
    }
    maxRemainder=Math.max(maxRemainder,nodes.reduce(sum))
    //console.log(nodes.reduce(sum));
  }
  console.log(maxRemainder);
}
else{
  for(i=0;i<t*t;i++){
    max=0;
    maxLoc=0;
    for(j=0;j<t;j++){
      if(counts[j]>=max&&nodes[j]){
        max=counts[j];
        maxLoc=j;
      }
    }
    if(max>0){
      for(j=0;j<t;j++){
        if(adjMat[maxLoc][j]){
          counts[j]--;
          if(counts[j]<max-1&&stor[j]&&!nodes[j]){
            nodes[j]=1;
            for(k=0;k<t;k++){
              if(adjMat[j][k])counts[k]++;
            }
          }
        }
        nodes[maxLoc]=0;
      }
    }
    else{
      break;
    }
  }
  console.log(nodes.reduce(sum));
}

Спробуйте в Інтернеті!

Фрагмент, до якого можна додати кінець програми, щоб показати, які послідовності дистанцій Хеммінга кожна вибрана послідовність дистанції Хеммінга

for(i=0;i<t;i++){
  if(nodes[i]){
    tmp=[]
    for(j=0;j<input;j++){
      tmp.unshift(Math.floor(i/Math.pow(input+1,j))%(input+1))
    }
    console.log(tmp.join(""))
    output=""
    for(j=0;j<t;j++){
      if(adjMat[i][j]&&stor[j]){
        outArr=[]
        for(k=0;k<input;k++){
          outArr.unshift(Math.floor(j/Math.pow(input+1,k))%(input+1))
        }
        output+=" "+outArr.join("");
      }
    }
    console.log(output)
  }
}

Пояснення:

По-перше, код генерує всі унікальні відстані забивання від підрядів.

input=3;
hammings=[];
h=(x,y)=>{retVal=0;while(x||y){if(x%2!=y%2)retVal++;x>>=1;y>>=1}return retVal};
for(i=1<<(input-1);i<1<<input;i++){
  for(j=0;j<1<<(2*input);j++){
    hamming=[];
    for(k=0;k<input;k++){
      hamming.push(h((j>>k)%(1<<input),i));
    }
    equal=0;
    for(k=0;k<hammings.length;k++){
      if(hamming.join("")==hammings[k].join("")){
        equal=1;
        break;
      }
    }
    if(!equal)hammings.push(hamming);
  }
}

Далі код перетворює цей список у непрямий графік

adjMat=[];
for(i=0;i<Math.pow(input+1,input);i++){
  row=[];
  for(j=0;j<Math.pow(input+1,input);j++){
    row.push(0);
  }
  adjMat.push(row);
}
nodes=[]
for(i=0;i<Math.pow(input+1,input);i++){
  nodes[i]=0;
}
for(i=0;i<hammings.length;i++){
  sum=0;
  chkNodes=[[]];
  for(j=0;j<input;j++){
    chkVal=[];
    t=Math.pow(input+1,j);
    sum+=t*hammings[i][j];
    tmp=[];
    for(r=0;r<chkNodes.length;r++){
      for(k=hammings[i][j];k<=Math.min(hammings[i][j]*2,input);k++){
        stor=[]
        for(s=0;s<chkNodes[r].length;s++){
          stor.push(chkNodes[r][s])
        }
        stor.push(k)
        tmp.push(stor);
      }
    }
    chkNodes=[];
    for(r=0;r<tmp.length;r++){
      chkNodes.push(tmp[r])
    }
  }
  nodes[sum]=1;
  for(j=0;j<chkNodes.length;j++){
    adjSum=0
    for(k=0;k<input;k++){
      adjSum+=Math.pow(input+1,k)*chkNodes[j][k]
    }
    if(adjSum!=sum)adjMat[sum][adjSum]=adjMat[adjSum][sum]=1
  }
}

Нарешті, код проходить цикл через цей графік, видаляючи вершину з найбільшою кількістю з’єднань кожного циклу, перш ніж відновити будь-які вузли, які тепер мали б менше з'єднань, ніж поточний максимум. Закінчивши цей цикл, він виводить кількість інших вузлів

t=nodes.length;
for(i=0;i<t;i++){
  if(!nodes[i]){
    for(k=0;k<t;k++){
      adjMat[i][k]=adjMat[k][i]=0
    }
  }
}
sum=(a,b)=>a+b;
counts=adjMat.map(x=>x.reduce(sum));
stor=[];
for(i=0;i<t;i++){
  stor.push(nodes[i]);
}
for(i=0;i<t*t;i++){
  max=0;
  maxLoc=0;
  for(j=0;j<t;j++){
    if(counts[j]>=max&&nodes[j]){
      max=counts[j];
      maxLoc=j;
    }
  }
  if(max>0){
    for(j=0;j<t;j++){
      if(adjMat[maxLoc][j]){
        counts[j]--;
        if(counts[j]<max-1&&stor[j]&&!nodes[j]){
          nodes[j]=1;
          for(k=0;k<t;k++){
            if(adjMat[j][k])counts[k]++;
          }
        }
      }
      nodes[maxLoc]=0;
    }
  }
  else{
    break;
  }
}
console.log(nodes.reduce(sum));

Набори:

1:

0 1

2:

00 01 10 12 21

3:

000 001 011 013 030 031 100 101 110 111 123 130 132 203 213 231 302 310 312 
321 333

4:

0000 0001 0011 0111 0124 0133 0223 0230 0232 0241 0313 0320 0322 0331 0403 
0412 1000 1001 1013 1021 1100 1102 1110 1111 1134 1201 1224 1233 1243 1304 
1314 1323 1330 1332 1342 1403 1413 1420 1422 2011 2033 2124 2133 2140 2142 
2214 2230 2241 2303 2313 2320 2331 2411 3023 3032 3040 3041 3101 3114 3123 
3130 3132 3141 3203 3213 3220 3231 3302 3310 3312 3321 3334 3343 3433 4031 
4113 4122 4131 4210 4212 4221 4311 4333

5:

00000 00001 00011 00111 00123 01112 01235 01244 01324 01343 02111 02230 
02234 02333 02342 02432 02441 02522 02530 02531 03134 03142 03220 03224 
03233 03241 03314 03323 03331 03403 03412 03421 03520 04133 04141 04214 
04223 04232 04303 04313 04322 05042 05050 05051 05132 10000 10001 10011 
10122 10212 10221 10245 11000 11001 11013 11022 11100 11112 11120 11121 
11202 11211 11345 11353 11443 12012 12111 12201 12245 12253 12335 12344 
12352 12425 12430 12434 12442 12513 12532 13033 13042 13244 13252 13325 
13330 13334 13342 13404 13424 13433 13441 13520 13522 13531 14032 14051 
14140 14152 14225 14230 14234 14241 14243 14304 14315 14324 14332 14413 
14420 14422 14431 15041 15050 15125 15133 15142 15215 15223 15232 20112 
20135 20211 20253 20334 20352 21012 21021 21102 21110 21111 21201 21245 
21344 21352 21430 21433 21442 21514 21523 22011 22101 22135 22244 22252 
22325 22334 22340 22343 22405 22415 22424 22441 22520 22522 22531 23041 
23144 23150 23152 23225 23234 23240 23243 23251 23304 23315 23324 23333 
23341 23403 23413 23420 23432 23521 24031 24050 24125 24130 24134 24142 
24151 24215 24224 24233 24303 24314 24320 24323 24331 24412 24421 25123 
25132 25141 25203 25214 25222 25231 25302 25312 25321 30234 30243 30252 
30324 30333 30340 30342 30414 30423 30430 30432 31011 31235 31244 31253 
31325 31334 31340 31343 31405 31415 31424 31432 31441 31504 31521 32025 
32034 32100 32144 32152 32225 32234 32240 32243 32251 32304 32315 32324 
32330 32333 32342 32403 32414 32423 32512 33024 33031 33033 33125 33134 
33140 33143 33151 33215 33224 33230 33233 33242 33303 33314 33320 33323 
33332 33412 33431 34124 34133 34203 34214 34223 34232 34241 34310 34313 
34322 34411 35202 35213 35221 35311 40323 40332 40341 40431 40505 40513 
41135 41144 41240 41243 41252 41324 41330 41333 41342 41403 41414 41423 
41512 42033 42134 42143 42230 42233 42242 42303 42310 42314 42323 42332 
42341 42413 42422 42431 43023 43124 43130 43133 43142 43203 43220 43223 
43232 43241 43302 43313 43322 43331 43421 44114 44123 44132 44210 44213 
44222 44231 44312 44321 50413 50422 50504 51233 51242 51251 51323 51332 
51341 51413 51422 52023 52133 52142 52151 52223 52232 52241 52313 52322 
52331 52421 53102 53114 53122 53210 53213 53321 54201 54212 54221 54311

Дякуємо за першу відповідь! Не могли б ви дати покроковий посібник для ідіотів про те, як запустити свій код в Linux?

Може, fəˈnɛtɪk міг перетворити свій код у фрагмент стека?
mbomb007

@ mbomb007 чомусь перетворення цього фрагмента призводить до того, що помилка 0 не є функцією ... в рядку для (j = 0; j <t; j ++)
fəˈnɛtɪk

Може, ви могли б спробувати JSFiddle?
mbomb007

Якщо у вас є хром, ви можете скопіювати вставити код у консоль і запустити його, натиснувши клавішу Enter. Не зовсім впевнений в інших браузерах. Chrome запускає код швидше, ніж онлайн-системи для мене. Вдалося отримати 5-е значення - 349
1717
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.