Tags: misc 

Rating: 5.0

Come on, let's get started

First, you download the zip file, then, interact with the server and see 600 lines of results appear as shown below.

![](https://i.imgur.com/TSfo7nj.png)

When extracting the zip file, you will see two files that are misc3.rs and elemprops.csv Then to save your time, I will summarize the content of this challenge as follows.

First, we will have a database file elemprops.csv

```csv
atomicnumber,symbol,valence,electronegativity,group,period
1,H,1,2.2,1,1
2,He,0,0,18,1
3,Li,1,0.98,1,2
4,Be,2,1.57,2,2
5,B,3,2.04,13,2
6,C,-4,2.55,14,2
7,N,-3,3.04,15,2
8,O,-2,3.44,16,2
9,F,-1,3.98,17,2
10,Ne,0,0,18,2
11,Na,1,0.93,1,3
12,Mg,2,1.31,2,3
13,Al,3,1.61,13,3
14,Si,4,1.9,14,3
15,P,-3,2.19,15,3
16,S,-2,2.58,16,3
17,Cl,-1,3.16,17,3
...
```

Then analyze a bit, each data it will have 6 parameters as follows: atomicnumber,symbol,valence,electronegativity,group,period

Now, we have not used this database file, and let's continue to analyze this misc.rs code to understand what it is intended for!

```rs
let mut rng = thread_rng();
let mut lab_key = [0u8; 25];
for i in 0..25 {
lab_key[i] = rng.gen_range(65..127);
}
let lab_key = str::from_utf8(&lab_key[..]).unwrap();
let chem_password: Vec<Atom> = lab_key.as_bytes().iter().map(|x| Atom::from_atomic_number(*x - 64, &elements).unwrap()).collect();
```

Here, we can understand that lab_key is an array of 25 elements and these elements are randomly generated in the range [65;127]

Next, the chem_password is generated from the generated lab_key array, but it is worth noting that the values of the elements in the chem_password are subtracted by 64.

```rs
for i in 0..25 {
for j in 0..25 {
// Reactions with two of the same element are counterproductive
if i == j {
continue;
}
// Give results of reaction, this should be more than enough
let first = &chem_password[i];
let second = &chem_password[j];
let difference1 = (first.element.atomicnumber as i16 - second.element.atomicnumber as i16).abs();
let difference2 = (first.element.electronegativity - second.element.electronegativity).abs();
let bond = Bond::new(first, second);
match bond {
Some(thebond) => println!("Results for index {} and {}: {:?}, {}, {:.2}", i, j, thebond.bondtype, difference1, difference2),
None => println!("Results for index {} and {}: {}, {}, {:.2}", i, j, "No Reaction", difference1, difference2),
}
}
}
```

Next, based on the elements of chem_password, it is generated that the server returns us as shown above, and a total of 600 lines of data are generated like that.

And now we will analyze a bit how it generates those 600 lines of data!

Consider any one of the 600 lines of data that the server gives :

```
Results for index 0 and 1: Metallic, 25, 1.38
```

We notice that, each data line of pair i and j will include 3 parameters: arg1, arg2, arg3. Where arg1,arg2,arg3 are defined as follows:

arg1 = bontypes ; arg2 = difference1 ; arg3 = difference2;

```rs
impl Bond<'_> {
fn new<'b>(atom1: &'b Atom, atom2: &'b Atom) -> Option<Bond<'b>>{
let bondtype;
if atom1.element.valence == 0 || atom2.element.valence == 0 {
// Noble gas bonds not implemented
return None;
}
else if atom1.element.valence.signum() != atom2.element.valence.signum() {
// Ionic
bondtype = BondType::Ionic;
}
else if atom1.element.valence.signum() == 1 && atom2.element.valence.signum() == 1 {
// Metallic
bondtype = BondType::Metallic;
}
else {
// Covalent
bondtype = BondType::Covalent;
}
Some(Bond {
bondtype,
atoms: [atom1, atom2]
})

}
}
```

And our task now is based on 600 data provided by the server, combined with the code misc3.rs along with a database file of more than 100 elements elempros.csv. We have to find out which 25 randomly generated elements are !
And after finding these 25 elements, it seems the problem is solved !

So our team's idea is that because we know lab_key is generated from random numbers in [65;127] and chem_pass is generated from numbers in lab_key minus 64, so we can infer, primes in chem_pass only in fragment [1.63]. And so, our team's job is to generate 3 parameters of all pairs i,j with i,j running from 1 to 63. Then compare the first 25 lines of data that the server has the same level to found 25 elements in chem_pass.

```
Metallic 0 0-->1,1
NoReaction 1 -1-->1,2
Metallic 2 1.22-->1,3
Metallic 3 0.63-->1,4
Metallic 4 0.16-->1,5
Ionic 5 0.35-->1,6
Ionic 6 0.84-->1,7
Ionic 7 1.24-->1,8
Ionic 8 1.78-->1,9
NoReaction 9 -1-->1,10
Metallic 10 1.27-->1,11
Metallic 11 0.89-->1,12
Metallic 12 0.59-->1,13
Metallic 13 0.3-->1,14
Ionic 14 0.01-->1,15
Ionic 15 0.38-->1,16
Ionic 16 0.96-->1,17
NoReaction 17 -1-->1,18
Metallic 18 1.38-->1,19
Metallic 19 1.2-->1,20
Metallic 20 0.84-->1,21
Metallic 21 0.66-->1,22
Metallic 22 0.57-->1,23
Metallic 23 0.54-->1,24
Metallic 24 0.65-->1,25
Metallic 25 0.37-->1,26
Metallic 26 0.32-->1,27
Metallic 27 0.29-->1,28
Metallic 28 0.3-->1,29
Metallic 29 0.55-->1,30
Metallic 30 0.39-->1,31
Metallic 31 0.19-->1,32
Metallic 32 0.02-->1,33
Ionic 33 0.35-->1,34
Ionic 34 0.76-->1,35
NoReaction 35 0.8-->1,36
Metallic 36 1.38-->1,37
...
```

And this is the result that our team was born! To generate this code, our team used C++ language to read the file elemprops.cv

```cpp
// atomicnumber,symbol,valence,electronegativity,group,period
// 1 H 1 2.2 1 1
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 605
struct element{
int id;
string atomicnumber;
int valence;
double electronegativity;
int group;
int period;
void print(){
cout<<this->id<<" "<<this->atomicnumber<<" "<<this->valence<<" "<<this->electronegativity<<" "<<this->group<<" "<<this->period<<'\n';
}
};
struct boba{
string ten;
int diff1;
double diff2;
void print(){
cout<<this->ten<<" "<<this->diff1<<" "<<this->diff2<<'\n';
}
};
bool operator < (boba A, boba B){
return A.ten[0]<B.ten[0];
}
map<boba,pair<int,int>> mapping;
element arr[maxn];
int main(){
freopen("db","r",stdin);
freopen("khong_gian_sinh","w",stdout);
ll n;
cin>>n;
for(ll i=0;i<n;i++){
cin>>arr[i].id>>arr[i].atomicnumber>>arr[i].valence>>arr[i].electronegativity>>arr[i].group>>arr[i].period;
}
// arr[1].print();
for(ll i=0;i<n;i++){
for(ll j=0;j<n;j++){
boba tmp;
// Xu ly ten
if(arr[i].valence>0 && arr[j].valence >0) tmp.ten = "Metallic";
else if(arr[i].valence==0 || arr[j].valence == 0) tmp.ten = "NoReaction";
else if(arr[i].valence*arr[j].valence< 0) tmp.ten = "Ionic";
else tmp.ten = "Covalent";
tmp.diff1 = abs(arr[i].id-arr[j].id);
if(arr[i].electronegativity==0.00 || arr[j].electronegativity==0.00) tmp.diff2=-1.00;
else tmp.diff2 = abs(arr[i].electronegativity-arr[j].electronegativity);
mapping[tmp]={arr[i].id,arr[j].id};
cout<<tmp.ten<<" "<<tmp.diff1<<" "<<tmp.diff2<<"-->"<<arr[i].id<<","<<arr[j].id<<'\n';
}
}
// for(auto p: mapping){
// cout<<p.first.ten<<","<<p.first.diff1<<","<<p.first.diff2<<"-->"<

lepuchinAug. 12, 2021, 9:57 a.m.

I love the way you solved it!


psycholog1stAug. 12, 2021, 10:20 a.m.

Great writeup although i can't understand anything