Skip to content
Permalink
Browse files

Working mining

  • Loading branch information...
ichyo committed Jun 23, 2019
1 parent 827943b commit a5b44fc4d82701562aa50d23af4dbd9b9bde4a37
Showing with 172 additions and 39 deletions.
  1. +6 −0 mining.sh
  2. +2 −2 src/main.rs
  3. +80 −27 src/mine.rs
  4. +62 −10 src/puzzle.rs
  5. +16 −0 src/solve.rs
  6. +6 −0 src/utils.rs
@@ -0,0 +1,6 @@
#!/bin/sh

while true; do
cargo run --bin mining --release
sleep 60
done
@@ -6,10 +6,10 @@ use std::io::Write;

use icfpc::models::*;
use icfpc::parse::read_all_inputs;
use icfpc::solve::solve_small;
use icfpc::solve::solve_small_while;

fn solve<W: Write>(task: Task, f: &mut W) {
let cmds = solve_small(task);
let cmds = solve_small_while(task, std::time::Duration::from_secs(2));
for cmd in cmds {
write!(f, "{}", cmd).unwrap();
}
@@ -7,8 +7,8 @@ use std::{thread, time};

use crate::models::*;
use crate::parse::{read_puzzle, read_task};
use crate::puzzle::solve_pazzle;
use crate::solve::solve_small;
use crate::puzzle::solve_puzzle;
use crate::solve::solve_small_while;

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

pub fn solve(&self, block: usize, puzzle: &str, task: &str) {
let mut rand = thread_rng();
let puzzle = read_puzzle(puzzle);
eprintln!("{:?}", puzzle);
let task = read_task(task);
//let commands = solve_small(task);

let puzzle_answer = solve_pazzle(puzzle);
println!("{:?}", puzzle_answer);
pub fn latest_block(&mut self) -> Option<usize> {
match self.api.getmininginfo().call() {
Ok(m) => Some(m.block),
Err(e) => {
eprintln!("{}", e);
None
}
}
}

pub fn execute(&mut self) {
loop {
match self.api.getmininginfo().call() {
Ok(x) => {
for b in 0..x.block {
let b = self.api.getblockinfo(b).call().unwrap();
let puzzle = read_puzzle(&b.puzzle);
let puzzle_answer = solve_pazzle(puzzle);
println!("{:?}", puzzle_answer);
}
self.solve(x.block, &x.puzzle, &x.task);
}
Err(e) => {
println!("{}", e);
pub fn submit_latest(&mut self) {
if let Some(block) = self.latest_block() {
if self.generate_solution(block) {
match self
.api
.submit(
block,
&format!("./mining/{}-task.sol", block),
&format!("./mining/{}-puzzle.desc", block),
)
.call()
{
Ok(value) => eprintln!("{:?}", value),
Err(e) => eprintln!("{}", e),
}
}
}
}

pub fn generate_solution(&mut self, block: usize) -> bool {
let blockinfo = match self.api.getblockinfo(block).call() {
Ok(m) => m,
Err(e) => {
eprintln!("{}", e);
return false;
}
};

let puzzle = read_puzzle(&blockinfo.puzzle);
let task = read_task(&blockinfo.task);
let task_answer = solve_small_while(task, std::time::Duration::from_secs(180));
let puzzle_answer = solve_puzzle(puzzle);

self.dump_task_answer(block, task_answer);
if let Some(puzzle_answer) = puzzle_answer {
self.dump_puzzle_answer(block, puzzle_answer);
true
} else {
false
}
}

let one_sec = time::Duration::from_secs(60);
thread::sleep(one_sec);
fn dump_task_answer(&self, block: usize, answer: Vec<Command>) {
let mut content = String::new();
for b in answer {
content.push_str(&format!("{}", b));
}
match self.dump_file(&format!("./mining/{}-task.sol", block), &content) {
Ok(()) => {}
Err(e) => {
eprintln!("{}", e);
}
}
}

fn dump_puzzle_answer(&self, block: usize, answer: Task) {
let content = format!("{}", answer);
match self.dump_file(&format!("./mining/{}-puzzle.desc", block), &content) {
Ok(()) => {}
Err(e) => {
eprintln!("{}", e);
}
}
}

fn dump_file(&self, path: &str, content: &str) -> std::io::Result<()> {
std::fs::write(path, content)
}

pub fn execute(&mut self) {
loop {
self.submit_latest();
thread::sleep(time::Duration::from_secs(60));
}
}
}
@@ -1,30 +1,77 @@
use crate::models::*;
use crate::utils::Range;
use rand::prelude::*;
use std::collections::VecDeque;
use std::collections::{HashSet, VecDeque};

fn construct_map_from_ranges(ranges: &[Range]) -> Map {
let len = ranges.len();
let mut vertexes = Vec::new();
vertexes.push(Point::new(0, ranges[0].start as i32));
vertexes.push(Point::new(0, ranges[0].end as i32));
vertexes.push(Point::new(ranges[0].start as i32, 0));
vertexes.push(Point::new(ranges[0].end as i32, 0));
for y in 0..len - 1 {
if ranges[y].end != ranges[y + 1].end {
vertexes.push(Point::new((y + 1) as i32, ranges[y].end as i32));
vertexes.push(Point::new((y + 1) as i32, ranges[y + 1].end as i32));
vertexes.push(Point::new(ranges[y].end as i32, (y + 1) as i32));
vertexes.push(Point::new(ranges[y + 1].end as i32, (y + 1) as i32));
}
}
vertexes.push(Point::new(len as i32, ranges[len - 1].end as i32));
vertexes.push(Point::new(len as i32, ranges[len - 1].start as i32));
vertexes.push(Point::new(ranges[len - 1].end as i32, len as i32));
vertexes.push(Point::new(ranges[len - 1].start as i32, len as i32));
for y in (0..len - 1).rev() {
if ranges[y].start != ranges[y + 1].start {
vertexes.push(Point::new((y + 1) as i32, ranges[y + 1].start as i32));
vertexes.push(Point::new((y + 1) as i32, ranges[y].start as i32));
vertexes.push(Point::new(ranges[y + 1].start as i32, (y + 1) as i32));
vertexes.push(Point::new(ranges[y].start as i32, (y + 1) as i32));
}
}
Map::new(vertexes)
}

fn compute_vertex_number(ranges: &[Range]) -> usize {
construct_map_from_ranges(ranges).len()
}

fn increse_vertex_number(ranges: &mut [Range], includes: Vec<Point>, min_vertex: usize) -> bool {
let mut vertex_num = compute_vertex_number(ranges);
let includes = includes.iter().cloned().collect::<HashSet<_>>();
for i in 1..ranges.len() - 1 {
if vertex_num >= min_vertex + 10 {
break;
}
if ranges[i].end == ranges[i - 1].end
&& ranges[i].len() > 1
&& !includes.contains(&Point::new(ranges[i].end as i32 - 1, i as i32))
{
let new_range = ranges[i].remove_end();
if new_range.intersect(ranges[i - 1]) && new_range.intersect(ranges[i + 1]) {
ranges[i] = new_range;
vertex_num += 2;
if ranges[i - 1].end == ranges[i + 1].end {
vertex_num += 2;
}
if new_range.end == ranges[i + 1].end {
vertex_num -= 2;
}
}
}
if ranges[i].start == ranges[i - 1].start
&& ranges[i].len() > 1
&& !includes.contains(&Point::new(ranges[i].start as i32, i as i32))
{
let new_range = ranges[i].remove_begin();
if new_range.intersect(ranges[i - 1]) && new_range.intersect(ranges[i + 1]) {
ranges[i] = new_range;
vertex_num += 2;
if ranges[i - 1].start == ranges[i + 1].start {
vertex_num += 2;
}
if new_range.start == ranges[i + 1].start {
vertex_num -= 2;
}
}
}
}
vertex_num >= min_vertex
}

fn consume_points_for(source: &mut VecDeque<Point>, num: usize, kind: BoosterType) -> Vec<Booster> {
let mut res = Vec::new();
for _ in 0..num {
@@ -33,7 +80,7 @@ fn consume_points_for(source: &mut VecDeque<Point>, num: usize, kind: BoosterTyp
res
}

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

if !increse_vertex_number(&mut ranges, puzzle.includes, puzzle.vertex_min) {
eprintln!("Failed to increase vertex");
return None;
}

let map = construct_map_from_ranges(&ranges);

if map.len() < puzzle.vertex_min {
@@ -1,6 +1,7 @@
use crate::models::*;
use crate::utils::Matrix;

use std::time;
use rand::seq::SliceRandom;
use rand::thread_rng;
use std::collections::{HashMap, VecDeque};
@@ -250,3 +251,18 @@ pub fn solve_small(task: Task) -> Vec<Command> {
}
state.commands
}

pub fn solve_small_while(task: Task, duration: time::Duration) -> Vec<Command> {
let mut res = solve_small(task.clone());
let now = time::Instant::now();;
loop {
if now.elapsed() >= duration {
break;
}
let new = solve_small(task.clone());
if new.len() < res.len() {
res = new;
}
}
res
}
@@ -81,4 +81,10 @@ impl Range {
let right = Range::new(mid + 1, self.end);
(left, right)
}
pub fn remove_begin(&self) -> Range {
Range::new(self.start+1, self.end)
}
pub fn remove_end(&self) -> Range {
Range::new(self.start, self.end - 1)
}
}

0 comments on commit a5b44fc

Please sign in to comment.
You can’t perform that action at this time.