Skip to content

Commit ce5e1bf

Browse files
init
1 parent 521ba10 commit ce5e1bf

File tree

3 files changed

+176
-9
lines changed

3 files changed

+176
-9
lines changed

.gitignore

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
# Generated by Cargo
2-
# will have compiled files and executables
3-
/target/
4-
5-
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6-
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
1+
target
72
Cargo.lock
8-
9-
# These are backup files generated by rustfmt
10-
**/*.rs.bk
3+
Output.txt

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[package]
2+
name = "SumSquareOrder"
3+
version = "0.1.0"
4+
authors = ["Chris <[email protected]>"]

src/main.rs

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#![allow(non_snake_case)]
2+
use std::thread;
3+
use std::env;
4+
use std::process::Command;
5+
use std::sync::mpsc::SyncSender;
6+
use std::sync::mpsc::sync_channel;
7+
use std::fs::File;
8+
use std::io::prelude::*;
9+
use std::time::Instant;
10+
11+
const maxThreads:i8 = 8;
12+
13+
struct CompleteTask{
14+
startNode: i16,
15+
paths: Vec<Vec<i16>>,
16+
}
17+
18+
fn main(){
19+
let mut _totalNodes:String = "0".to_string();
20+
for argument in env::args() {
21+
_totalNodes = argument.to_string();
22+
}
23+
println!("You have chosen to order numbers upto {}", _totalNodes);
24+
let totalNodes:i16 = _totalNodes.parse::<i16>().unwrap();
25+
let now = Instant::now();
26+
27+
let paths = getCore(totalNodes, now);
28+
29+
let endTime = now.elapsed().as_secs();
30+
printResult(paths, totalNodes);
31+
println!("It took aproximately {} seconds to compute", endTime);
32+
}
33+
34+
fn getCore(totalNodes:i16, now:Instant) -> Vec<Vec<i16>>{
35+
let connections:Vec<[i16; 2]> = findConnections(totalNodes);
36+
let (sender, reciever) = sync_channel(maxThreads as usize);
37+
let mut paths:Vec<Vec<i16>> = vec![];
38+
39+
println!("There are {} connections", connections.len());
40+
41+
let mut i:i16 = 0;
42+
let mut openThreads = 0;
43+
loop{
44+
while (openThreads < maxThreads as usize) && (i < totalNodes){
45+
startCalcAsync(i, connections.clone(), totalNodes.clone(), sender.clone());
46+
openThreads += 1;
47+
i += 1;
48+
}
49+
50+
let completedTask = reciever.recv().unwrap();
51+
paths.append(&mut completedTask.paths.clone());
52+
openThreads -= 1;
53+
54+
println!("finnished task {} of {} at {} seconds", completedTask.startNode, totalNodes, now.elapsed().as_secs());
55+
56+
if openThreads == 0 {
57+
break;
58+
}
59+
}
60+
return paths;
61+
}
62+
63+
fn startCalcAsync(startNode:i16, connections:Vec<[i16; 2]>, totalNodes:i16, sender:SyncSender<CompleteTask>){
64+
println!("Starting task {}", startNode);
65+
66+
let mut path:Vec<i16> = Vec::with_capacity(totalNodes as usize);
67+
path.push(startNode);
68+
69+
thread::spawn(move || {
70+
let paths = doThread(connections, path, totalNodes);
71+
sender.send(CompleteTask{
72+
startNode:startNode,
73+
paths:paths,
74+
}).unwrap();
75+
});
76+
}
77+
fn printResult(paths:Vec<Vec<i16>>, totalNodes:i16){
78+
println!("Exporting final data...");
79+
let result = File::create("Output.txt");
80+
let mut file:File = match result {
81+
Ok(x) => x,
82+
Err(e) => {
83+
println!("Error on Output Attempt: {}", e);
84+
return;
85+
},
86+
};
87+
let mut completePaths:i16 = 0;
88+
for path in paths.clone(){
89+
if path.len() == totalNodes as usize {
90+
write!(file, "A working path is ");
91+
completePaths += 1;
92+
for node in path {
93+
write!(file, "{} ", node);
94+
}
95+
write!(file, "\n");
96+
}
97+
}
98+
99+
println!("DONE!");
100+
println!("Completed with {} paths", paths.len());
101+
println!("{} of them are complete paths", completePaths);
102+
println!("All working paths have been outputted to Output.txt");
103+
}
104+
105+
fn doThread(connections:Vec<[i16; 2]>, _path:Vec<i16>, totalNodes:i16) -> Vec<Vec<i16>>{
106+
let mut path = _path.clone();
107+
let mut paths:Vec<Vec<i16>> = Vec::with_capacity(totalNodes as usize);
108+
109+
loop{
110+
let node = path[path.len()-1];
111+
let mut goTo:i16 = 0;
112+
let mut isFirstConnection:bool = true;
113+
for connection in connections.clone() {
114+
let mut connectedTo:i16 = 0;
115+
if node == connection[0] {
116+
connectedTo = connection[1];
117+
}else if node == connection[1] {
118+
connectedTo = connection[0];
119+
}else{
120+
continue;
121+
}
122+
123+
if !isNodeInPath(connectedTo, path.clone()) {
124+
if isFirstConnection {
125+
isFirstConnection = false;
126+
goTo = connectedTo;
127+
}else{
128+
let mut newPath = path.clone();
129+
newPath.push(connectedTo);
130+
let newConnections = connections.clone();
131+
paths.append(&mut doThread(newConnections, newPath, totalNodes));
132+
}
133+
}
134+
}
135+
if isFirstConnection {
136+
break;
137+
} else {
138+
path.push(goTo);
139+
}
140+
}
141+
142+
paths.push(path);
143+
return paths;
144+
}
145+
146+
fn isNodeInPath(node:i16, path:Vec<i16>)->bool{
147+
for nodeToCheck in path {
148+
if nodeToCheck == node {
149+
return true;
150+
}
151+
}
152+
return false;
153+
}
154+
155+
fn findConnections(totalNodes:i16) -> Vec<[i16; 2]> {
156+
let mut connections:Vec<[i16; 2]> = vec![];
157+
for i in 1..totalNodes {
158+
for j in i+1..totalNodes+1 {
159+
if isSquare(i+j) {
160+
connections.push([i, j]);
161+
}
162+
}
163+
}
164+
return connections;
165+
}
166+
167+
fn isSquare(num:i16) -> bool{
168+
let sqrt:f64 = (num as f64).sqrt();
169+
return sqrt == sqrt.round();
170+
}

0 commit comments

Comments
 (0)