Skip to content

Commit a5b44fc

Browse files
committed
Working mining
1 parent 827943b commit a5b44fc

File tree

6 files changed

+172
-39
lines changed

6 files changed

+172
-39
lines changed

mining.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
3+
while true; do
4+
cargo run --bin mining --release
5+
sleep 60
6+
done

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use std::io::Write;
66

77
use icfpc::models::*;
88
use icfpc::parse::read_all_inputs;
9-
use icfpc::solve::solve_small;
9+
use icfpc::solve::solve_small_while;
1010

1111
fn solve<W: Write>(task: Task, f: &mut W) {
12-
let cmds = solve_small(task);
12+
let cmds = solve_small_while(task, std::time::Duration::from_secs(2));
1313
for cmd in cmds {
1414
write!(f, "{}", cmd).unwrap();
1515
}

src/mine.rs

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::{thread, time};
77

88
use crate::models::*;
99
use crate::parse::{read_puzzle, read_task};
10-
use crate::puzzle::solve_pazzle;
11-
use crate::solve::solve_small;
10+
use crate::puzzle::solve_puzzle;
11+
use crate::solve::solve_small_while;
1212

1313
#[derive(Debug, Serialize, Deserialize)]
1414
pub struct BlockChainInfo {
@@ -58,36 +58,89 @@ impl Client {
5858
Client { api: client }
5959
}
6060

61-
pub fn solve(&self, block: usize, puzzle: &str, task: &str) {
62-
let mut rand = thread_rng();
63-
let puzzle = read_puzzle(puzzle);
64-
eprintln!("{:?}", puzzle);
65-
let task = read_task(task);
66-
//let commands = solve_small(task);
67-
68-
let puzzle_answer = solve_pazzle(puzzle);
69-
println!("{:?}", puzzle_answer);
61+
pub fn latest_block(&mut self) -> Option<usize> {
62+
match self.api.getmininginfo().call() {
63+
Ok(m) => Some(m.block),
64+
Err(e) => {
65+
eprintln!("{}", e);
66+
None
67+
}
68+
}
7069
}
7170

72-
pub fn execute(&mut self) {
73-
loop {
74-
match self.api.getmininginfo().call() {
75-
Ok(x) => {
76-
for b in 0..x.block {
77-
let b = self.api.getblockinfo(b).call().unwrap();
78-
let puzzle = read_puzzle(&b.puzzle);
79-
let puzzle_answer = solve_pazzle(puzzle);
80-
println!("{:?}", puzzle_answer);
81-
}
82-
self.solve(x.block, &x.puzzle, &x.task);
83-
}
84-
Err(e) => {
85-
println!("{}", e);
71+
pub fn submit_latest(&mut self) {
72+
if let Some(block) = self.latest_block() {
73+
if self.generate_solution(block) {
74+
match self
75+
.api
76+
.submit(
77+
block,
78+
&format!("./mining/{}-task.sol", block),
79+
&format!("./mining/{}-puzzle.desc", block),
80+
)
81+
.call()
82+
{
83+
Ok(value) => eprintln!("{:?}", value),
84+
Err(e) => eprintln!("{}", e),
8685
}
8786
}
87+
}
88+
}
89+
90+
pub fn generate_solution(&mut self, block: usize) -> bool {
91+
let blockinfo = match self.api.getblockinfo(block).call() {
92+
Ok(m) => m,
93+
Err(e) => {
94+
eprintln!("{}", e);
95+
return false;
96+
}
97+
};
98+
99+
let puzzle = read_puzzle(&blockinfo.puzzle);
100+
let task = read_task(&blockinfo.task);
101+
let task_answer = solve_small_while(task, std::time::Duration::from_secs(180));
102+
let puzzle_answer = solve_puzzle(puzzle);
103+
104+
self.dump_task_answer(block, task_answer);
105+
if let Some(puzzle_answer) = puzzle_answer {
106+
self.dump_puzzle_answer(block, puzzle_answer);
107+
true
108+
} else {
109+
false
110+
}
111+
}
88112

89-
let one_sec = time::Duration::from_secs(60);
90-
thread::sleep(one_sec);
113+
fn dump_task_answer(&self, block: usize, answer: Vec<Command>) {
114+
let mut content = String::new();
115+
for b in answer {
116+
content.push_str(&format!("{}", b));
117+
}
118+
match self.dump_file(&format!("./mining/{}-task.sol", block), &content) {
119+
Ok(()) => {}
120+
Err(e) => {
121+
eprintln!("{}", e);
122+
}
123+
}
124+
}
125+
126+
fn dump_puzzle_answer(&self, block: usize, answer: Task) {
127+
let content = format!("{}", answer);
128+
match self.dump_file(&format!("./mining/{}-puzzle.desc", block), &content) {
129+
Ok(()) => {}
130+
Err(e) => {
131+
eprintln!("{}", e);
132+
}
133+
}
134+
}
135+
136+
fn dump_file(&self, path: &str, content: &str) -> std::io::Result<()> {
137+
std::fs::write(path, content)
138+
}
139+
140+
pub fn execute(&mut self) {
141+
loop {
142+
self.submit_latest();
143+
thread::sleep(time::Duration::from_secs(60));
91144
}
92145
}
93146
}

src/puzzle.rs

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,77 @@
11
use crate::models::*;
22
use crate::utils::Range;
33
use rand::prelude::*;
4-
use std::collections::VecDeque;
4+
use std::collections::{HashSet, VecDeque};
55

66
fn construct_map_from_ranges(ranges: &[Range]) -> Map {
77
let len = ranges.len();
88
let mut vertexes = Vec::new();
9-
vertexes.push(Point::new(0, ranges[0].start as i32));
10-
vertexes.push(Point::new(0, ranges[0].end as i32));
9+
vertexes.push(Point::new(ranges[0].start as i32, 0));
10+
vertexes.push(Point::new(ranges[0].end as i32, 0));
1111
for y in 0..len - 1 {
1212
if ranges[y].end != ranges[y + 1].end {
13-
vertexes.push(Point::new((y + 1) as i32, ranges[y].end as i32));
14-
vertexes.push(Point::new((y + 1) as i32, ranges[y + 1].end as i32));
13+
vertexes.push(Point::new(ranges[y].end as i32, (y + 1) as i32));
14+
vertexes.push(Point::new(ranges[y + 1].end as i32, (y + 1) as i32));
1515
}
1616
}
17-
vertexes.push(Point::new(len as i32, ranges[len - 1].end as i32));
18-
vertexes.push(Point::new(len as i32, ranges[len - 1].start as i32));
17+
vertexes.push(Point::new(ranges[len - 1].end as i32, len as i32));
18+
vertexes.push(Point::new(ranges[len - 1].start as i32, len as i32));
1919
for y in (0..len - 1).rev() {
2020
if ranges[y].start != ranges[y + 1].start {
21-
vertexes.push(Point::new((y + 1) as i32, ranges[y + 1].start as i32));
22-
vertexes.push(Point::new((y + 1) as i32, ranges[y].start as i32));
21+
vertexes.push(Point::new(ranges[y + 1].start as i32, (y + 1) as i32));
22+
vertexes.push(Point::new(ranges[y].start as i32, (y + 1) as i32));
2323
}
2424
}
2525
Map::new(vertexes)
2626
}
2727

28+
fn compute_vertex_number(ranges: &[Range]) -> usize {
29+
construct_map_from_ranges(ranges).len()
30+
}
31+
32+
fn increse_vertex_number(ranges: &mut [Range], includes: Vec<Point>, min_vertex: usize) -> bool {
33+
let mut vertex_num = compute_vertex_number(ranges);
34+
let includes = includes.iter().cloned().collect::<HashSet<_>>();
35+
for i in 1..ranges.len() - 1 {
36+
if vertex_num >= min_vertex + 10 {
37+
break;
38+
}
39+
if ranges[i].end == ranges[i - 1].end
40+
&& ranges[i].len() > 1
41+
&& !includes.contains(&Point::new(ranges[i].end as i32 - 1, i as i32))
42+
{
43+
let new_range = ranges[i].remove_end();
44+
if new_range.intersect(ranges[i - 1]) && new_range.intersect(ranges[i + 1]) {
45+
ranges[i] = new_range;
46+
vertex_num += 2;
47+
if ranges[i - 1].end == ranges[i + 1].end {
48+
vertex_num += 2;
49+
}
50+
if new_range.end == ranges[i + 1].end {
51+
vertex_num -= 2;
52+
}
53+
}
54+
}
55+
if ranges[i].start == ranges[i - 1].start
56+
&& ranges[i].len() > 1
57+
&& !includes.contains(&Point::new(ranges[i].start as i32, i as i32))
58+
{
59+
let new_range = ranges[i].remove_begin();
60+
if new_range.intersect(ranges[i - 1]) && new_range.intersect(ranges[i + 1]) {
61+
ranges[i] = new_range;
62+
vertex_num += 2;
63+
if ranges[i - 1].start == ranges[i + 1].start {
64+
vertex_num += 2;
65+
}
66+
if new_range.start == ranges[i + 1].start {
67+
vertex_num -= 2;
68+
}
69+
}
70+
}
71+
}
72+
vertex_num >= min_vertex
73+
}
74+
2875
fn consume_points_for(source: &mut VecDeque<Point>, num: usize, kind: BoosterType) -> Vec<Booster> {
2976
let mut res = Vec::new();
3077
for _ in 0..num {
@@ -33,7 +80,7 @@ fn consume_points_for(source: &mut VecDeque<Point>, num: usize, kind: BoosterTyp
3380
res
3481
}
3582

36-
pub fn solve_pazzle(puzzle: Puzzle) -> Option<Task> {
83+
pub fn solve_puzzle(puzzle: Puzzle) -> Option<Task> {
3784
let len = puzzle.max_length - 1;
3885
assert!(puzzle.includes.iter().all(|p| p.x < len as i32));
3986
assert!(puzzle.includes.iter().all(|p| p.y < len as i32));
@@ -109,6 +156,11 @@ pub fn solve_pazzle(puzzle: Puzzle) -> Option<Task> {
109156
}
110157
ranges.reverse();
111158

159+
if !increse_vertex_number(&mut ranges, puzzle.includes, puzzle.vertex_min) {
160+
eprintln!("Failed to increase vertex");
161+
return None;
162+
}
163+
112164
let map = construct_map_from_ranges(&ranges);
113165

114166
if map.len() < puzzle.vertex_min {

src/solve.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::models::*;
22
use crate::utils::Matrix;
33

4+
use std::time;
45
use rand::seq::SliceRandom;
56
use rand::thread_rng;
67
use std::collections::{HashMap, VecDeque};
@@ -250,3 +251,18 @@ pub fn solve_small(task: Task) -> Vec<Command> {
250251
}
251252
state.commands
252253
}
254+
255+
pub fn solve_small_while(task: Task, duration: time::Duration) -> Vec<Command> {
256+
let mut res = solve_small(task.clone());
257+
let now = time::Instant::now();;
258+
loop {
259+
if now.elapsed() >= duration {
260+
break;
261+
}
262+
let new = solve_small(task.clone());
263+
if new.len() < res.len() {
264+
res = new;
265+
}
266+
}
267+
res
268+
}

src/utils.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,10 @@ impl Range {
8181
let right = Range::new(mid + 1, self.end);
8282
(left, right)
8383
}
84+
pub fn remove_begin(&self) -> Range {
85+
Range::new(self.start+1, self.end)
86+
}
87+
pub fn remove_end(&self) -> Range {
88+
Range::new(self.start, self.end - 1)
89+
}
8490
}

0 commit comments

Comments
 (0)