Data update

This commit is contained in:
Ingy döt Net 2024-10-16 18:07:41 -07:00
parent 81fd053722
commit 52a6ef48dd
10248 changed files with 63654 additions and 6775 deletions

View file

@ -0,0 +1,163 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
const int32_t EMPTY = -1;
const std::vector<std::vector<int32_t>> tableau_one = { { 0, 5, 1, 3, 2, 2, 3, 1 },
{ 0, 5, 5, 0, 5, 2, 4, 6 },
{ 4, 3, 0, 3, 6, 6, 2, 0 },
{ 0, 6, 2, 3, 5, 1, 2, 6 },
{ 1, 1, 3, 0, 0, 2, 4, 5 },
{ 2, 1, 4, 3, 3, 4, 6, 6 },
{ 6, 4, 5, 1, 5, 4, 1, 4 } };
const std::vector<std::vector<int32_t>> tableau_two = { { 6, 4, 2, 2, 0, 6, 5, 0 },
{ 1, 6, 2, 3, 4, 1, 4, 3 },
{ 2, 1, 0, 2, 3, 5, 5, 1 },
{ 1, 3, 5, 0, 5, 6, 1, 0 },
{ 4, 2, 6, 0, 4, 0, 1, 1 },
{ 4, 4, 2, 0, 5, 3, 6, 3 },
{ 6, 6, 5, 2, 5, 3, 3, 4 } };
class Domino {
public:
Domino(const int32_t& aOne, const int32_t& aTwo) {
one = std::min(aOne, aTwo);
two = std::max(aOne, aTwo);
}
bool operator==(const Domino& other) const {
return one == other.one && two == other.two;
}
private:
int32_t one, two;
};
class Point {
public:
Point(const int32_t& aX, const int32_t& aY) : x(aX), y(aY) { }
bool operator==(const Point& other) const {
return x == other.x && y == other.y;
}
int32_t x, y;
};
struct Pattern {
std::vector<std::vector<int32_t>> tableau;
std::vector<Domino> dominoes;
std::vector<Point> points;
};
int32_t first_empty_cell(const std::vector<std::vector<int32_t>>& tableau) {
for ( uint64_t row = 0; row < tableau.size(); ++row ) {
for ( uint64_t col = 0; col < tableau[0].size(); ++col ) {
if ( tableau[row][col] == EMPTY ) {
return row * tableau[0].size() + col;
}
}
}
return EMPTY;
}
void print_layout(const Pattern& pattern) {
std::vector<std::string> output(
2 * pattern.tableau.size(), std::string(2 * pattern.tableau[0].size() - 1, ' '));
for ( uint64_t i = 0; i < pattern.points.size() - 1; i += 2 ) {
const int x1 = pattern.points[i].x;
const int y1 = pattern.points[i].y;
const int x2 = pattern.points[i + 1].x;
const int y2 = pattern.points[i + 1].y;
const int n1 = pattern.tableau[x1][y1];
const int n2 = pattern.tableau[x2][y2];
output[2 * x1][2 * y1] = static_cast<char>('0' + n1);
output[2 * x2][2 * y2] = static_cast<char>('0' + n2);
if ( x1 == x2 ) {
output[2 * x1][2 * y1 + 1] = '+';
} else if ( y1 == y2 ) {
output[2 * x1 + 1][2 * y1] = '+';
}
}
for ( const std::string& line : output ) {
std::cout << line << "\n";
}
}
std::vector<Pattern> find_patterns(const std::vector<std::vector<int32_t>>& tableau) {
const int32_t n_rows = tableau.size();
const int32_t n_cols = tableau[0].size();
const uint64_t domino_count = ( n_rows * n_cols ) / 2;
std::vector<std::vector<int32_t>> empty_tableau =
{ static_cast<uint64_t>(n_rows), std::vector<int32_t>(n_cols, EMPTY) };
std::vector<Pattern> patterns = { Pattern(empty_tableau, std::vector<Domino>(), std::vector<Point>()) };
while ( true ) {
std::vector<Pattern> next_patterns = { };
for ( Pattern pattern : patterns ) {
std::vector<std::vector<int32_t>> next_tableau = pattern.tableau;
std::vector<Domino> dominoes = pattern.dominoes;
std::vector<Point> points = pattern.points;
int32_t index = first_empty_cell(next_tableau);
if ( index == EMPTY ) {
continue;
}
int32_t row = index / n_cols;
int32_t col = index % n_cols;
if ( row + 1 < n_rows && next_tableau[row + 1][col] == EMPTY ) {
Domino domino(tableau[row][col], tableau[row + 1][col]);
if ( std::find(dominoes.begin(), dominoes.end(), domino) == dominoes.end() ) {
std::vector<std::vector<int32_t>> final_tableau = { };
std::copy(next_tableau.begin(), next_tableau.end(), std::back_inserter(final_tableau));
final_tableau[row][col] = tableau[row][col];
final_tableau[row + 1][col] = tableau[row + 1][col];
std::vector<Domino> next_dominoes(dominoes.begin(), dominoes.end());
next_dominoes.emplace_back(domino);
std::vector<Point> next_points(points.begin(), points.end());
next_points.emplace_back(Point(row, col));
next_points.emplace_back(Point(row + 1, col));
next_patterns.emplace_back(Pattern(final_tableau, next_dominoes, next_points));
}
}
if ( col + 1 < n_cols && next_tableau[row][col + 1] == EMPTY ) {
Domino domino(tableau[row][col], tableau[row][col + 1]);
if ( std::find(dominoes.begin(), dominoes.end(), domino) == dominoes.end() ) {
next_tableau[row][col] = tableau[row][col];
next_tableau[row][col + 1] = tableau[row][col + 1];
dominoes.emplace_back(domino);
points.emplace_back(Point(row, col));
points.emplace_back(Point(row, col + 1));
next_patterns.emplace_back(Pattern(next_tableau, dominoes, points));
}
}
}
if ( next_patterns.empty() ) {
break;
}
patterns = next_patterns;
if ( patterns[0].dominoes.size() == domino_count ) {
break;
}
}
return patterns;
}
int main() {
for ( const std::vector<std::vector<int32_t>>& tableau : { tableau_one, tableau_two } ) {
std::vector<Pattern> patterns = find_patterns(tableau);
std::cout << "Layouts found: " << patterns.size() << "\n";
print_layout(patterns[0]);
}
}

View file

@ -0,0 +1,151 @@
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public final class Dominos {
public static void main(String[] args) {
List.of( tableauOne, tableauTwo ).forEach( tableau -> {
List<Pattern> patterns = findPatterns(tableau);
System.out.println("Layouts found: " + patterns.size() + System.lineSeparator());
printLayout(patterns.getFirst());
} );
}
private static List<Pattern> findPatterns(int[][] tableau) {
final int nRows = tableau.length;
final int nCols = tableau[0].length;
final int dominoCount = ( nRows * nCols ) / 2;
int[][] emptyTableau = IntStream.range(0, nRows)
.mapToObj( i -> IntStream.range(0, nCols).map( j -> EMPTY ).toArray() ).toArray(int[][]::new);
List<Pattern> patterns = new ArrayList<Pattern>();
patterns.addLast( new Pattern(emptyTableau, new ArrayList<Domino>(), new ArrayList<Point>()) );
while ( true ) {
List<Pattern> nextPatterns = new ArrayList<Pattern>();
for ( Pattern pattern : patterns ) {
int[][] nextTableau = pattern.tableau;
List<Domino> dominoes = pattern.dominoes;
List<Point> points = pattern.points;
final int index = IntStream.range(0, nRows * nCols)
.filter( i -> nextTableau[i / nCols][i % nCols] == EMPTY ).findFirst().orElse(EMPTY);
if ( index == EMPTY ) {
continue;
}
int row = index / nCols;
int col = index % nCols;
if ( row + 1 < nRows && nextTableau[row + 1][col] == EMPTY ) {
Domino domino = new Domino(tableau[row][col], tableau[row + 1][col]);
if ( ! dominoes.contains(domino) ) {
int[][] finalTableau = new int[nextTableau.length][];
for ( int i = 0; i < nextTableau.length; i++ ) {
finalTableau[i] = new int[nextTableau[i].length];
System.arraycopy(nextTableau[i], 0, finalTableau[i], 0, nextTableau[i].length);
}
finalTableau[row][col] = tableau[row][col];
finalTableau[row + 1][col] = tableau[row + 1][col];
List<Domino> nextDominoes = new ArrayList<Domino>(dominoes);
nextDominoes.addLast(domino);
List<Point> nextPoints = new ArrayList<Point>(points);
nextPoints.addAll(List.of( new Point(row, col), new Point(row + 1, col) ));
nextPatterns.addLast( new Pattern(finalTableau, nextDominoes, nextPoints) );
}
}
if ( col + 1 < nCols && nextTableau[row][col + 1] == EMPTY ) {
Domino domino = new Domino(tableau[row][col], tableau[row][col + 1]);
if ( ! dominoes.contains(domino) ) {
nextTableau[row][col] = tableau[row][col];
nextTableau[row][col + 1] = tableau[row][col + 1];
dominoes.add(domino);
points.addAll(List.of( new Point(row, col), new Point(row, col + 1) ));
nextPatterns.addLast( new Pattern(nextTableau, dominoes, points) );
}
}
}
if ( nextPatterns.isEmpty() ) {
break;
}
patterns = nextPatterns;
if ( patterns.getFirst().dominoes.size() == dominoCount ) {
break;
}
}
return patterns;
}
private static void printLayout(Pattern pattern) {
List<List<String>> output = IntStream.range(0, 2 * pattern.tableau.length)
.mapToObj( i -> new ArrayList<String>(Collections.nCopies(2 * pattern.tableau[0].length - 1, " ")) )
.collect(Collectors.toList());
for ( int i = 0; i < pattern.points.size() - 1; i += 2 ) {
final int x1 = pattern.points.get(i).x;
final int y1 = pattern.points.get(i).y;
final int x2 = pattern.points.get(i + 1).x;
final int y2 = pattern.points.get(i + 1).y;
final int n1 = pattern.tableau[x1][y1];
final int n2 = pattern.tableau[x2][y2];
output.get(2 * x1).set(2 * y1, String.valueOf(n1));
output.get(2 * x2).set(2 * y2, String.valueOf(n2));
if ( x1 == x2 ) {
output.get(2 * x1).set(2 * y1 + 1, "+");
} else if ( y1 == y2 ) {
output.get(2 * x1 + 1).set(2 * y1, "+");
}
}
output.forEach( i -> System.out.println(i.stream().collect(Collectors.joining())) );
}
private static class Domino {
public Domino(int aOne, int aTwo) {
one = Math.min(aOne, aTwo);
two = Math.max(aOne, aTwo);
}
@Override
public int hashCode() {
return 2 * one + 3 * two;
}
@Override
public boolean equals(Object other) {
return switch ( other ) {
case Domino domino -> one == domino.one && two == domino.two;
case Object object -> false;
};
}
private int one, two;
}
private static final int EMPTY = -1;
private static record Pattern(int[][] tableau, List<Domino> dominoes, List<Point> points) {}
private static final int[][] tableauOne = { { 0, 5, 1, 3, 2, 2, 3, 1 },
{ 0, 5, 5, 0, 5, 2, 4, 6 },
{ 4, 3, 0, 3, 6, 6, 2, 0 },
{ 0, 6, 2, 3, 5, 1, 2, 6 },
{ 1, 1, 3, 0, 0, 2, 4, 5 },
{ 2, 1, 4, 3, 3, 4, 6, 6 },
{ 6, 4, 5, 1, 5, 4, 1, 4 } };
private static final int[][] tableauTwo = { { 6, 4, 2, 2, 0, 6, 5, 0 },
{ 1, 6, 2, 3, 4, 1, 4, 3 },
{ 2, 1, 0, 2, 3, 5, 5, 1 },
{ 1, 3, 5, 0, 5, 6, 1, 0 },
{ 4, 2, 6, 0, 4, 0, 1, 1 },
{ 4, 4, 2, 0, 5, 3, 6, 3 },
{ 6, 6, 5, 2, 5, 3, 3, 4 } };
}

View file

@ -0,0 +1,38 @@
import java.math.BigInteger;
public final class DominosExtraCredit {
public static void main(String[] args) {
BigInteger arrangements = BigInteger.valueOf(dominoTilingCount(7, 8));
BigInteger permutations = factorial(BigInteger.valueOf(28));
BigInteger flips = BigInteger.TWO.pow(28);
System.out.println("Arrangements ignoring values: " + arrangements);
System.out.println("Permutations of 28 dominos: " + permutations);
System.out.println("Permuted arrangements ignoring flipping dominos: "
+ permutations.multiply(arrangements));
System.out.println("Possible flip configurations: " + flips);
System.out.println("Possible permuted arrangements with flips: "
+ permutations.multiply(flips).multiply(arrangements));
}
private static int dominoTilingCount(int rows, int cols) {
double product = 1.0;
for ( int i = 1; i <= ( rows + 1 ) / 2; i++ ) {
for ( int j = 1; j <= ( cols + 1 ) / 2; j++ ) {
final double cosRows = Math.cos(Math.PI * i / ( rows + 1 ));
final double cosCols = Math.cos(Math.PI * j / ( cols + 1 ));
product *= ( cosRows * cosRows + cosCols * cosCols ) * 4;
}
}
return (int) product;
}
private static BigInteger factorial(BigInteger number) {
if ( number.equals(BigInteger.TWO) ) {
return number;
}
return number.multiply(factorial(number.subtract(BigInteger.ONE)));
}
}