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.

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<<"-->"<
I love the way you solved it!
Great writeup although i can't understand anything