├── .gitignore ├── README.md ├── LICENSE └── sudokus_colored.R /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.Rproj 6 | *.html 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sudokus Colored 2 | 3 | In this experiment I create oversimposed colored sudokus. The project is inspired by Alex Bellos' tridokus, which I found in his book *Snowflake Seashell Star: Colouring Adventures in Numberland*. 4 | 5 | 6 | ## Getting Started 7 | 8 | ### Prerequisites 9 | 10 | You will need to install the following packages (if you don't have them already): 11 | 12 | ``` 13 | install.packages("ggplot2") 14 | install.packages("dplyr") 15 | install.packages("gtools") 16 | install.packages("colourlovers") 17 | install.packages("sudoku") 18 | ``` 19 | 20 | ## More info 21 | 22 | A complete explanation of the experiment can be found [at fronkonstin](https://fronkonstin.com/2018/06/01/coloring-sudokus/) 23 | 24 | An article on [The Guardian](https://www.theguardian.com/books/2015/sep/17/nested-fish-and-golden-triangles-adult-colouring-and-the-beauty-of-maths) by Alex Bellos 25 | 26 | 27 | ## Authors 28 | 29 | * **Antonio Sánchez Chinchón** - [@aschinchon](https://twitter.com/aschinchon) 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Antonio Sánchez Chinchón 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sudokus_colored.R: -------------------------------------------------------------------------------- 1 | # Load in libraries 2 | library(gtools) 3 | library(dplyr) 4 | library(sudoku) 5 | library(ggplot2) 6 | library(colourlovers) 7 | 8 | # To create all possible permutations of subsquent sudokus, I start generating all 9 | # permutations of three elements (6 in total) 10 | # I create column k to do cross joins later 11 | permutations(n=3, r=3, v=1:3) %>% 12 | as.data.frame() %>% 13 | mutate(k=1) -> perm 14 | 15 | # Cross join permutations 4 times. I will use last three columns to interchange 16 | # groups of columns and first nine to interchange within columns 17 | perm %>% 18 | inner_join(perm, by="k") %>% 19 | inner_join(perm, by="k") %>% 20 | inner_join(perm, by="k") %>% 21 | select(-k) -> total_all 22 | 23 | # Rename columns to make it understable 24 | colnames(total_all)=c(paste0("v",1:9),"c1","c2","c3") 25 | 26 | # Generate all possibilities. Each row of total_all is a possible reordering 27 | # of columns to create a new sudoku 28 | total_all %>% 29 | mutate_at(vars(v1:v3), function(.) .+3*total_all[,"c1"]-3) %>% 30 | mutate_at(vars(v4:v6), function(.) .+3*total_all[,"c2"]-3) %>% 31 | mutate_at(vars(v7:v9), function(.) .+3*total_all[,"c3"]-3) %>% 32 | select(v1:v9)-> total_all 33 | 34 | n=3 # n can take value from 1 to 9 35 | data <- data.frame() 36 | total=total_all 37 | 38 | # This loop generates n disjoint sudokus from a base one (when i is equal to 1) 39 | # and resampling from total_all 40 | for (i in n:1) 41 | { 42 | if(i==n) 43 | { 44 | sudoku <- generateSudoku(0) 45 | data.frame(level=sudoku %>% as.vector(), size=i)->new 46 | compare=apply(total, 1, function(x) sum(abs(x-(1:9))==0)) 47 | } else 48 | { 49 | total %>% sample_n(1) -> tran 50 | sudoku_trans <- sudoku[tran %>% as.numeric,] 51 | data.frame(level=sudoku_trans %>% as.vector(), size=i)->new 52 | compare=apply(total, 1, function(x) sum(abs(x-as.numeric(tran))==0)) 53 | } 54 | expand.grid(x=1:9, y=1:9) %>% cbind(new) %>% rbind(data) -> data 55 | total=total[which(compare==0),] # To guaranteeing subsequent sudokus are disjoint from previous 56 | 57 | } 58 | 59 | # Pick a palette from colourLovers 60 | # My favourite are: "1930", "482774", "694737", "953498" y "292482" 61 | id="1930" 62 | palette <- clpalette(id) %>% swatch %>% .[[1]] %>% unique() %>% colorRampPalette() 63 | 64 | # Do the plot 65 | plot <- ggplot(data, aes(group=size, fill=level)) + 66 | geom_rect(aes(xmin=x-((n-(size-1))/n)*0.5, 67 | xmax=x+((n-(size-1))/n)*0.5, 68 | ymin=y-((n-(size-1))/n)*0.5, 69 | ymax=y+((n-(size-1))/n)*0.5))+ 70 | scale_fill_gradientn(colors=palette(9)) + 71 | coord_fixed()+ 72 | theme_void()+ 73 | theme(legend.position="none") 74 | 75 | # To see the plot on screen 76 | plot 77 | 78 | # Do you like it? Save it! 79 | ggsave("my_tridoku.png", height=4, width=4, units='in', dpi=600) 80 | --------------------------------------------------------------------------------