Advertisement
Guest User

anti-particle solver

a guest
Mar 24th, 2017
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.14 KB | None | 0 0
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6.  
  7. /*
  8. * File: main.cc
  9. * Author: theleader
  10. *
  11. * Created on March 24, 2017, 8:38 PM
  12. */
  13.  
  14. #include <cstdlib>
  15. #include <iostream>
  16. #include <map>
  17. #include <string>
  18. #include <vector>
  19.  
  20. // boards are expressed as strings with slashes in them.
  21. // coords are (x,y) with (0,0) top left.
  22.  
  23.  
  24. using namespace std;
  25.  
  26. vector<string> split(string s, string to_split){
  27. vector<string> output;
  28. int x=0;
  29. int limit=0;
  30. while(limit != string::npos){
  31. limit = s.find(to_split, x);
  32. output.emplace_back(s.substr(x, limit-x));
  33. x = limit+to_split.length();
  34. }
  35. return output;
  36. }
  37. template <class T> // vector concatenation,.
  38. vector<T> operator+(const vector<T> & x, const vector<T> & y){
  39. vector<T> z = x;
  40. z.insert(z.end(), y.begin(), y.end());
  41. return z;
  42. }
  43.  
  44. class point{
  45. public:
  46. int x;
  47. int y;
  48. point(int x, int y):x(x),y(y){};
  49. point(){}; //map requires ctor with no args
  50. bool operator==(const point & p){
  51. return (x==p.x && y==p.y);
  52. }
  53. };
  54. class history_string{ // a string with history
  55. public:
  56. string s;
  57. vector<point> history;
  58. history_string(string s, vector<point> h):s(s),history(h){};
  59. history_string(){}; //map requires ctor with no args
  60. bool operator==(const history_string hs){
  61. return (s == hs.s);
  62. }
  63.  
  64.  
  65. };
  66.  
  67. // printing:
  68. ostream & operator<<(ostream & os, const point & p){
  69. os << "("<< p.x << "," << p.y<<")";
  70. return os;
  71. }
  72.  
  73. ostream & operator<<(ostream & os, const history_string & hs){
  74. os << "[" << hs.s << "]:";
  75. for(const point & i : hs.history){
  76. os << i;
  77. }
  78. return os;
  79. }
  80.  
  81.  
  82.  
  83. map<string, history_string> * table = new map<string, history_string>; // lookup table.
  84. //do not forget to free this
  85.  
  86. vector<point> component(string s, point p){ // returns the set of points in the connected component. (0,0) is the top left.
  87. //throws if p is out of bounds
  88. vector<point> output {p};
  89. vector<string> board = split(s, "/");
  90. //note: this should be accessed y,x
  91. int height = board.size();
  92. int width = board.at(0).length();
  93. char lookFor = board.at(p.y).at(p.x); // DO NOT modify.
  94. if(lookFor == '.'){
  95. return vector<point>{};
  96. }
  97. /*for each unchecked point, check all of its neighbors, if they're the same
  98. color, then add them to the output and unchecked lists
  99. }*/
  100. vector<point> unchecked {p};
  101. vector<point> checked {};
  102. while(unchecked.size() != 0){
  103. //check the adjacent to the point
  104. vector<point> newUnchecked {};
  105. for(point & checking : unchecked){
  106. vector<point> neighbors {point(checking.x-1, checking.y),
  107. point(checking.x+1, checking.y) ,
  108. point(checking.x, checking.y-1),
  109. point(checking.x, checking.y+1)};
  110. for(point & neighbor : neighbors){
  111. /* check each neighbor of the point
  112. * when will a point not be added into the output?
  113. * if that point is out of bounds
  114. * if that point is . or does not match
  115. * if that point is in output */
  116. if(neighbor.x < 0 || neighbor.y < 0 || neighbor.x >= width|| neighbor.y >= height ){
  117. continue;
  118. }
  119. if(board.at(neighbor.y).at(neighbor.x) == '.' || board.at(neighbor.y).at(neighbor.x) != lookFor ){
  120. continue;
  121. }
  122. bool alreadyChecked = false;
  123. for(point & checkedPoint : checked){
  124. if(neighbor == checkedPoint){
  125. alreadyChecked = true;
  126. break;
  127. }
  128. }
  129. if(alreadyChecked){
  130. continue;
  131. }
  132. output.push_back(neighbor);
  133. newUnchecked.push_back(neighbor);
  134. }
  135. checked.push_back(checking);
  136. }
  137. unchecked = newUnchecked;
  138. }
  139. return output;
  140. }
  141. string remove(string str, point p){
  142. //removes a single block from the board and moves everything above down
  143. //does not remove the entire connected component.
  144. string s = "";
  145. vector<string> board = split(str, "/");
  146. for(int row=0; row<board.size(); row++){
  147. for(int col=0; col < board.at(0).length(); col++){
  148. //if col match and 0th row, add .
  149. //if col match and row is less than or equal to p.y, but not zero, add previous row
  150. //else, add as is.
  151. if(col == p.x){
  152. if(row == 0){
  153. s=s+".";
  154. } else if (row <= p.y){
  155. s=s+board.at(row-1).at(col);
  156. }
  157. else{
  158. s=s+board.at(row).at(col);
  159. }
  160. }else{
  161. s=s+board.at(row).at(col);
  162. }
  163. }
  164. if(row+1 < board.size()){
  165. s=s+"/";
  166. }
  167. }
  168. return s;
  169. }
  170. bool emptyColumn(string str, int c){ //determine if a column is empty
  171. vector<string> board = split(str, "/");
  172. for(int row=0; row<board.size(); row++){
  173. if(board.at(row).at(c) != '.'){
  174. return false;
  175. }
  176. }
  177. return true;
  178. }
  179. string removeCol(string str , int c){//removes an entire column, and adds empty spots on the right.
  180. vector<string> board = split(str, "/");
  181. string s = "";
  182. for(int row=0; row<board.size(); row++){
  183. for(int col=0; col < board.at(0).length()-1; col++){
  184. if(col >= c){
  185. s=s+board.at(row).at(col+1);
  186. } else {
  187. s=s+board.at(row).at(col);
  188. }
  189. }
  190. if(row+1 < board.size()){
  191. s=s+"/";
  192. }
  193. }
  194. return s;
  195. }
  196. string removeComponent(string s, point p){
  197. //removes the entire component, and moves all empty rows to the left
  198. vector<point> toRemove = component(s, p); // must go from top down
  199. vector<string> board = split(s, "/");
  200. for(int i=0; i<board.size();i++){
  201. for(point & p : toRemove){
  202. if(p.y == i){
  203. s = remove(s, p);
  204. }
  205. }
  206. }
  207. string ns = s;
  208. //must go right to left
  209. for(int i=board.at(0).size()-1; i>=0;i-- ){
  210. if(emptyColumn(s, i)){
  211. ns=removeCol(ns, i);
  212. }
  213. }
  214. return ns;
  215. }
  216. int score(string str){
  217. int x =0;
  218. for(int i=0;i<str.length();i++){
  219. if(str.at(i) != '.' && str.at(i) != '/'){
  220. x++;
  221. }
  222. }
  223. return x;
  224. }
  225. history_string solve(string str){
  226. /* For each point on the grid: get its connected components
  227. * for each component of size at least 2:
  228. * create a new string with the component removed, and solve the string
  229. * this gives us a list of history-strings
  230. * choose the one with the fewest, and return (that string, history with the chosen component pre-pended)
  231. *
  232. */
  233. //if it's already in the lookup table, don't do it again,
  234. if(table->find(str) != table->end()){
  235. return table->at(str);
  236. }
  237. vector<string> board = split(str, "/");
  238. vector<point> candidates {};
  239. //first make a list of possible places to choose places.
  240. vector<point> seen {};
  241. for(int y=0; y<board.size();y++){
  242. for(int x=0;x<board.at(0).length();x++){
  243. bool alreadySeenThisPoint = false;
  244. for(point & p : seen){
  245. if (p == point(x, y)){
  246. alreadySeenThisPoint = true;
  247. break;
  248. }
  249. }
  250. if(alreadySeenThisPoint){
  251. continue;
  252. }
  253. vector<point> theComponent = component(str, point(x,y));
  254. if(theComponent.size() >= 2){
  255. candidates.push_back(theComponent.at(0));
  256. seen = seen + theComponent;
  257. }
  258. }
  259. }
  260. if(candidates.size() ==0){ //we're done!
  261. history_string result = history_string(str, vector<point> {});
  262. (*table)[str] = result;
  263. return result;
  264. }
  265. vector<history_string> candidateResults {};
  266. //recursively call this function for each component
  267. for(point & i : candidates){
  268. candidateResults.push_back(solve(removeComponent(str, i)));
  269. }
  270. //find the result with the smallest score:
  271. int argmin =-1;
  272. int minScore = str.size()+1;
  273. for(int i=0; i < candidateResults.size();i++){
  274. history_string hs = candidateResults.at(i);
  275. int score_this = score(hs.s) ;
  276. if(score_this < minScore){
  277. argmin = i;
  278. minScore = score_this;
  279. }
  280. }
  281. //we're done!
  282. history_string result = candidateResults.at(argmin);
  283. result.history = vector<point>{candidates.at(argmin)}+result.history;
  284. (*table)[str] = result;
  285. return result;
  286. }
  287.  
  288. void show_removing_point(string str, point p){ // shows the string with the point to be removed
  289. vector<string> board = split(str, "/");
  290. for(int row=0; row < board.size(); row++){
  291. for(int col = 0; col < board.at(0).size() ; col++){
  292. cout << board.at(row).at(col);
  293. if(p.x == col && p.y == row){
  294. cout << "<";
  295. }else{
  296. cout << " ";
  297. }
  298. }
  299. cout << "\n";
  300. }
  301. cout << "tiles remaining: " << score(str) << "\n";
  302.  
  303. }
  304. void show_solve(string str){ //graphically show how it is solved
  305. history_string hs = solve(str);
  306. for(point & p : hs.history){
  307. //print the string before removal and the point to be removed
  308. show_removing_point(str, p);
  309. cout << "removing point at " << p << "\n";
  310. str = removeComponent(str, p);
  311. }
  312. //show ending solution
  313. cout << "Final board : \n";
  314. show_removing_point(str, point(-3, -3));
  315. cout << "\n";
  316. }
  317. /*
  318. *
  319. */
  320. void test_cases(){
  321. //test insertion and deletion, and printing
  322. //expected : [A1B2C3]:(3,4)(65,21)(512,3)
  323. (*table)["ABC"] =history_string("A1B2C3", vector<point>{point(3,4), point(65,21), point(512,3)});
  324. cout << (*table)["ABC"] << "\n";
  325. //test finding connected components:
  326. //expected: 3
  327. //expected: (2,0)
  328. //expected: (1,1)
  329. string testBoard = "123456/234561/134125/131256/333162/5277..";
  330. cout << split(testBoard, "/").at(0).at(2) << "\n";
  331. for (point & p : component(testBoard, point(2, 0))){
  332. cout << p << " ";
  333. }
  334. cout << "\n";
  335. //expected : (1,1) (1,2) (1,3) (1,4) (0,4) (2,4)
  336. for (point & p : component(testBoard, point(1, 1))){
  337. cout << p << " ";
  338. }
  339. cout << "\n";
  340. // no output expected;
  341. for (point & p : component(testBoard, point(5, 5))){
  342. cout << p << " ";
  343. }
  344. //testing removing a point:
  345. //expected: 12.456/233561/134125/134256/333162/5277..
  346. cout << remove(testBoard, point(2,3))<<"\n";
  347. //expected: .23456/134561/234125/131256/333162/5277..
  348. cout << remove(testBoard, point(0,3))<<"\n";
  349. //testing removing an entire column
  350. string out = remove(".32/.63/134", point(0,2));
  351. cout << out << "\n";// .32/.63/.34
  352. cout << emptyColumn(out, 1) << "\n"; // false
  353. cout << emptyColumn(out, 0) << "\n"; // true
  354. cout << removeCol(out, 0) << "\n"; // expected: 32/63/34
  355. //testing removing an entire component
  356. cout << removeComponent("3224/1111/5611/3422", point(1,0)) << "\n"; //
  357. cout << removeComponent("3..4/1111/5611/3422", point(0,1)) << "\n"; //
  358. cout << removeComponent("..../3.../56../3422", point(2,3)) << "\n"; //
  359. //testing solving
  360. show_solve("3224/1111/3611/6422");
  361. show_solve("3422/1113/5622");
  362. //
  363. }
  364. int main(int argc, char** argv) {
  365. //test_cases();
  366. cout << "enter the grid, use . for a blank tile, use / for new line, and use numbers/letters for the cells";
  367. string s;
  368. getline(cin,s);
  369. show_solve(s);
  370. delete table;
  371. table = nullptr;
  372. return 0;
  373. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement