Skip to content

Commit b97c6b5

Browse files
committed
added seive alogrithm visualization
1 parent db68047 commit b97c6b5

12 files changed

Lines changed: 430 additions & 7 deletions

File tree

src/App.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {Component} from 'react';
22
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
33
import Pathfinder from "./pathfinderComponents/pathfinder";
44
import Home from "./homeComponents/home";
5+
import Seive from "./primeComponents/seive";
56

67
class App extends Component {
78
constructor() {
@@ -17,6 +18,7 @@ class App extends Component {
1718
<Switch>
1819
<Route path='/Pathfinder-2.0/' exact component={Home}/>
1920
<Route path='/Pathfinder-2.0/pathfinder' component={Pathfinder}/>
21+
<Route path='/Pathfinder-2.0/prime' component={Seive}/>
2022
</Switch>
2123
</Router>
2224
);

src/homeComponents/cards.jsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@ class Cards extends Component {
1313
},
1414
{
1515
id:2,
16-
title:"Sorting Algorithm",
17-
description:"Coming soon...",
18-
route:"/Pathfinder-2.0/"
16+
title:"Prime Numbers",
17+
description:"Visulaize how Seive is better than brute force",
18+
route:"/Pathfinder-2.0/prime"
1919
},
2020
{
2121
id:3,
22-
title:"8 Queen",
22+
title:"Sorting Algorithm",
2323
description:"Coming soon...",
2424
route:"/Pathfinder-2.0/"
2525
},
2626
{
2727
id:3,
28-
title:"Prime Numbers",
28+
title:"8 Queen",
2929
description:"Coming soon...",
3030
route:"/Pathfinder-2.0/"
3131
},
3232
{
33-
id:3,
33+
id:4,
3434
title:"Backtracking",
3535
description:"Coming soon...",
3636
route:"/Pathfinder-2.0/"

src/pathfinderComponents/menu.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Menu extends Component {
1010
/>
1111
<button
1212
onClick={this.props.onVisualize}
13-
className="btn btn-warning ">Visualize</button>
13+
className="btn btn-warning m-2">Visualize</button>
1414

1515
</nav>
1616
);

src/primeComponents/cell.css

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
.cell{
2+
height:50px;
3+
width:50px;
4+
background-color: white;
5+
outline:1px solid rgb(175, 216, 248);
6+
display: inline-block;
7+
font-size: 25px;
8+
text-align: center;
9+
color: black;
10+
border-radius: 5px 20px;
11+
}
12+
13+
.cell-prime{
14+
background-color: #00f51d;
15+
animation-name: isPrime;
16+
animation-duration: 1s;
17+
animation-delay: 0s;
18+
animation-iteration-count: 1;
19+
animation-timing-function: linear;
20+
21+
}
22+
@keyframes isPrime {
23+
0% {
24+
transform: rotate(90deg);
25+
background-color: rgba(0, 0, 66, 0.75);
26+
border-radius: 100%;
27+
}
28+
29+
50% {
30+
background-color: rgba(17, 104, 217, 0.75);
31+
transform: scale(1.5);
32+
33+
}
34+
35+
75% {
36+
background-color: rgba(0, 217, 159, 0.75);
37+
transform: rotate(270deg);
38+
39+
}
40+
41+
100% {
42+
43+
background-color: rgba(0, 190, 218, 0.75);
44+
transform: rotate(360deg);
45+
}
46+
}
47+
.cell-check{
48+
background-color: grey;
49+
}
50+
.cell-visiting{
51+
outline:3px solid rgb(175, 216, 248);
52+
animation-name: isVisiting;
53+
animation-duration: 1s;
54+
}
55+
@keyframes isVisiting {
56+
50%{
57+
transform: scale(1.5);
58+
}
59+
}

src/primeComponents/cell.jsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React, {Component} from 'react';
2+
import './cell.css';
3+
class Cell extends Component {
4+
render() {
5+
return (
6+
<div className={this.getClass()}>
7+
<span >
8+
{this.props.cell.val}
9+
</span>
10+
</div>
11+
);
12+
}
13+
getClass = () =>{
14+
const { val, isVisiting,isChecking,isPrime} = this.props.cell;
15+
if(isPrime){
16+
return "cell cell-prime m-2";
17+
}else if( isVisiting ){
18+
return "cell cell-visiting m-2";
19+
} else if( isChecking ){
20+
return "cell cell-check m-2";
21+
} else{
22+
return "cell m-2";
23+
}
24+
}
25+
}
26+
27+
export default Cell;

src/primeComponents/cells.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.Cells{
2+
font-size: 0px;
3+
}

src/primeComponents/cells.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React, {Component} from 'react';
2+
import Cell from "./cell";
3+
import './cells.css'
4+
class Cells extends Component {
5+
6+
render() {
7+
return (
8+
<div className="Cells">
9+
{this.props.cells.map( (cell,cellidx)=>{
10+
return (
11+
<Cell
12+
key={cellidx}
13+
cell={cell}
14+
/>
15+
);
16+
} )}
17+
</div>
18+
);
19+
}
20+
}
21+
22+
export default Cells;

src/primeComponents/menu.jsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React, {Component} from 'react';
2+
import DiscreteSlider from "./slider";
3+
import SimpleSelect from "./simpleSelect";
4+
5+
class Menu extends Component {
6+
render() {
7+
return (
8+
<nav className="nav alert-dark">
9+
<button className="btn btn-primary btn-lg m-2" onClick={this.props.onRefresh} disabled={this.props.isDisabled} style={this.isClickable()}>Refresh</button>
10+
<SimpleSelect/>
11+
<DiscreteSlider
12+
onChange={this.props.onChangeSpeed}
13+
title="speed"
14+
marks={true}
15+
default={10}
16+
step={10}
17+
min={10}
18+
max={50}
19+
isDisabled={this.props.isDisabled}
20+
/>
21+
<DiscreteSlider
22+
onChange={this.props.onChangeValues}
23+
title="Total Number"
24+
marks={false}
25+
default={100}
26+
step={1}
27+
min={10}
28+
max={500}
29+
isDisabled={this.props.isDisabled}
30+
/>
31+
<button className="btn btn-warning btn-lg m-2" onClick={this.props.onVisualize} disabled={this.props.isDisabled} style={this.isClickable()}>Visualize</button>
32+
33+
34+
</nav>
35+
);
36+
}
37+
isClickable = () =>{
38+
if( this.props.isDisabled ){
39+
return {cursor: "not-allowed"};
40+
} else{
41+
return {};
42+
}
43+
}
44+
}
45+
46+
export default Menu;

src/primeComponents/navbar.jsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, {Component} from 'react';
2+
import {Link} from "react-router-dom";
3+
4+
5+
class Navbar extends Component {
6+
render() {
7+
return (
8+
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
9+
<span className="navbar-brand">Sieve</span>
10+
<button className="navbar-toggler" type="button" data-toggle="collapse"
11+
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
12+
aria-expanded="false" aria-label="Toggle navigation">
13+
<span className="navbar-toggler-icon"></span>
14+
</button>
15+
<div className="collapse navbar-collapse" id="navbarSupportedContent" >
16+
<Link to={"/Pathfinder-2.0/"}>
17+
<span style={{color:"white"}}>
18+
Home
19+
</span>
20+
</Link>
21+
</div>
22+
23+
</nav>
24+
);
25+
}
26+
}
27+
28+
export default Navbar;

src/primeComponents/seive.jsx

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import React, {Component} from 'react';
2+
import Cells from "./cells";
3+
import Navbar from "./navbar";
4+
import DiscreteSlider from "./slider";
5+
import Menu from "./menu";
6+
7+
class Seive extends Component {
8+
state = {
9+
number: 100,
10+
cells:[],
11+
isRunning:false,
12+
speed:500
13+
}
14+
15+
constructor(props) {
16+
super(props);
17+
}
18+
componentDidMount() {
19+
const cells = getCells(this.state.number);
20+
this.setState({cells});
21+
}
22+
23+
render() {
24+
return (
25+
<div>
26+
<Navbar/>
27+
<Menu
28+
onChangeSpeed={this.changeSpeed}
29+
onChangeValues={this.handleValueIncease}
30+
onVisualize = {this.startSeive}
31+
onRefresh = {this.handleRefresh}
32+
isDisabled = {this.state.isRunning}
33+
/>
34+
<Cells
35+
num={this.state.number}
36+
cells={this.state.cells}
37+
/>
38+
39+
</div>
40+
);
41+
}
42+
43+
changeSpeed = (speed) => {
44+
//console.log(typeof speed);
45+
this.setState({speed:600-speed*10});
46+
}
47+
handleValueIncease = (value) => {
48+
this.setState({number:value});
49+
this.setState({cells:getCells(value),isRunning:false});
50+
console.log(value);
51+
}
52+
handleRefresh = () => {
53+
this.setState({cells:getCells(this.state.number),isRunning:false});
54+
}
55+
startSeive = () => {
56+
const speed = this.state.speed;
57+
this.setState({isRunning:true});
58+
const prime = [];
59+
for(let i = 0;i<=this.state.number;i++){
60+
prime.push(1);
61+
}
62+
prime[0] = prime[1] = 0;
63+
let changedCells = this.state.cells;
64+
let prevCheck = -1;
65+
let counter = 0;
66+
for( let i = 2; i<=this.state.number;i++){
67+
if( prime[i] === 1 ){
68+
setTimeout(()=>{
69+
changedCells = getNewCellPrimeToggled(changedCells,i-1);
70+
this.setState({cells:changedCells});
71+
},counter*speed);
72+
counter++;
73+
for(let j = i*i;j<=this.state.number;j+=i){
74+
setTimeout(()=>{
75+
if( prevCheck!=-1 ){
76+
changedCells = getNewCellVisitingToggled(changedCells,prevCheck);
77+
}
78+
prevCheck = j-1;
79+
changedCells = getNewCellCheckToggled(changedCells,j-1);
80+
changedCells = getNewCellVisitingToggled(changedCells,prevCheck);
81+
this.setState({cells:changedCells});
82+
},counter*speed);
83+
counter++;
84+
prime[j] = 0;
85+
}
86+
}
87+
}
88+
setTimeout(()=>{
89+
changedCells = getNewCellVisitingToggled(changedCells,prevCheck);
90+
this.setState({cells:changedCells,isRunning:false});
91+
},counter*speed);
92+
}
93+
}
94+
95+
const getNewCellPrimeToggled = (cells,pos) =>{
96+
const newCells = cells.slice();
97+
const cell = newCells[pos];
98+
const newCell = {
99+
...cell,
100+
isPrime:true
101+
}
102+
newCells[pos] = newCell;
103+
return newCells;
104+
}
105+
106+
const getNewCellVisitingToggled = (cells,pos)=>{
107+
const newCells = cells.slice();
108+
const cell = newCells[pos];
109+
const newCell = {
110+
...cell,
111+
isVisiting:!cell.isVisiting
112+
}
113+
newCells[pos] = newCell;
114+
return newCells;
115+
}
116+
117+
const getNewCellCheckToggled = (cells,pos) =>{
118+
const newCells = cells.slice();
119+
const cell = newCells[pos];
120+
const newCell = {
121+
...cell,
122+
isChecking:true
123+
}
124+
newCells[pos] = newCell;
125+
return newCells;
126+
}
127+
128+
const getCells = (rows)=>{
129+
const cells = [];
130+
for(let cell = 1;cell<=rows;cell++){
131+
cells.push(createCell(cell))
132+
}
133+
return cells;
134+
}
135+
const createCell = (val)=>{
136+
return {
137+
val,
138+
isChecking:false,
139+
isVisiting:false,
140+
isPrime:false
141+
};
142+
}
143+
144+
export default Seive;

0 commit comments

Comments
 (0)