Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Random-Latin-squares/00-META.yaml
Normal file
2
Task/Random-Latin-squares/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Random_Latin_squares
|
||||
25
Task/Random-Latin-squares/00-TASK.txt
Normal file
25
Task/Random-Latin-squares/00-TASK.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
A Latin square of size <code>n</code> is an arrangement of <code>n</code> symbols in an <code>n-by-n</code> square in such a way that each row and column has each symbol appearing exactly once.<br>
|
||||
For the purposes of this task, a random Latin square of size <code>n</code> is a Latin square constructed or generated by a probabilistic procedure such that the probability of any particular Latin square of size <code>n</code> being produced is non-zero.
|
||||
|
||||
;Example n=4 randomised Latin square:
|
||||
<pre>0 2 3 1
|
||||
2 1 0 3
|
||||
3 0 1 2
|
||||
1 3 2 0</pre>
|
||||
|
||||
;Task:
|
||||
# Create a function/routine/procedure/method/... that given <code>n</code> generates a randomised Latin square of size <code>n</code>.
|
||||
# Use the function to generate ''and show here'', two randomly generated squares of size 5.
|
||||
|
||||
;Note:
|
||||
Strict ''uniformity'' in the random generation is a hard problem and '''not''' a requirement of the task.
|
||||
|
||||
;Related tasks:
|
||||
* [[Latin Squares in reduced form/Randomizing using Jacobson and Matthews’ Technique]]
|
||||
* [[Latin Squares in reduced form]]
|
||||
|
||||
;Reference:
|
||||
* [[wp:Latin_square|Wikipedia: Latin square]]
|
||||
* [[oeis:A002860|OEIS: A002860]]
|
||||
<br>
|
||||
|
||||
46
Task/Random-Latin-squares/11l/random-latin-squares.11l
Normal file
46
Task/Random-Latin-squares/11l/random-latin-squares.11l
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
F _transpose(matrix)
|
||||
assert(matrix.len == matrix[0].len)
|
||||
V r = [[0] * matrix.len] * matrix.len
|
||||
L(i) 0 .< matrix.len
|
||||
L(j) 0 .< matrix.len
|
||||
r[i][j] = matrix[j][i]
|
||||
R r
|
||||
|
||||
F _shuffle_transpose_shuffle(matrix)
|
||||
V square = copy(matrix)
|
||||
random:shuffle(&square)
|
||||
V trans = _transpose(square)
|
||||
random:shuffle(&trans)
|
||||
R trans
|
||||
|
||||
F _rls(&symbols)
|
||||
V n = symbols.len
|
||||
I n == 1
|
||||
R [symbols]
|
||||
E
|
||||
V sym = random:choice(symbols)
|
||||
symbols.remove(sym)
|
||||
V square = _rls(&symbols)
|
||||
square.append(copy(square[0]))
|
||||
L(i) 0 .< n
|
||||
square[i].insert(i, sym)
|
||||
R square
|
||||
|
||||
F rls(n)
|
||||
V symbols = Array(0 .< n)
|
||||
V square = _rls(&symbols)
|
||||
R _shuffle_transpose_shuffle(square)
|
||||
|
||||
F _check_rows(square)
|
||||
V set_row0 = Set(square[0])
|
||||
R all(square.map(row -> row.len == Set(row).len & Set(row) == @set_row0))
|
||||
|
||||
F _check(square)
|
||||
V transpose = _transpose(square)
|
||||
assert(_check_rows(square) & _check_rows(transpose), ‘Not a Latin square’)
|
||||
|
||||
L(i) [3, 3, 5, 5]
|
||||
V square = rls(i)
|
||||
print(square.map(row -> row.join(‘ ’)).join("\n"))
|
||||
_check(square)
|
||||
print()
|
||||
81
Task/Random-Latin-squares/ALGOL-68/random-latin-squares.alg
Normal file
81
Task/Random-Latin-squares/ALGOL-68/random-latin-squares.alg
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
BEGIN # generate random latin squares #
|
||||
|
||||
# Knuth Shuffle routine from the Knuth Shuffle Task #
|
||||
# modified to shufflw a row of a [,]CHAR array #
|
||||
PROC knuth shuffle = (REF[,]CHAR a, INT row)VOID:
|
||||
(
|
||||
PROC between = (INT a, b)INT :
|
||||
(
|
||||
ENTIER (random * ABS (b-a+1) + (a<b|a|b))
|
||||
);
|
||||
FOR i FROM LWB a TO UPB a DO
|
||||
INT j = between(LWB a, UPB a);
|
||||
CHAR t = a[row, i];
|
||||
a[row, i] := a[row, j];
|
||||
a[row, j] := t
|
||||
OD
|
||||
);
|
||||
|
||||
# generates a random latin square #
|
||||
PROC latin square = ( INT n )[,]CHAR:
|
||||
BEGIN
|
||||
[ 1 : n ]CHAR letters;
|
||||
[ 1 : n, 1 : n ]CHAR result;
|
||||
FOR col TO n DO
|
||||
letters[ col ] := REPR ( ABS "A" + ( col - 1 ) )
|
||||
OD;
|
||||
FOR row TO n DO
|
||||
result[ row, : ] := letters
|
||||
OD;
|
||||
knuth shuffle( result, 1 );
|
||||
FOR row FROM 2 TO n - 1 DO
|
||||
BOOL ok := FALSE;
|
||||
WHILE
|
||||
knuth shuffle( result, row );
|
||||
BOOL all different := TRUE;
|
||||
FOR prev TO row - 1 WHILE all different DO
|
||||
FOR col TO n
|
||||
WHILE all different :=
|
||||
result[ row, col ] /= result[ prev, col ]
|
||||
DO SKIP OD
|
||||
OD;
|
||||
NOT all different
|
||||
DO SKIP OD
|
||||
OD;
|
||||
# the final row, there is only one possibility for each column #
|
||||
FOR col TO n DO
|
||||
[ 1 : n ]CHAR free := letters;
|
||||
FOR row TO n - 1 DO
|
||||
free[ ( ABS result[ row, col ] - ABS "A" ) + 1 ] := REPR 0
|
||||
OD;
|
||||
BOOL found := FALSE;
|
||||
FOR row FROM 1 LWB result TO 1 UPB result WHILE NOT found DO
|
||||
IF free[ row ] /= REPR 0 THEN
|
||||
found := TRUE;
|
||||
result[ n, col ] := free[ row ]
|
||||
FI
|
||||
OD
|
||||
OD;
|
||||
result
|
||||
END # latin suare # ;
|
||||
|
||||
# prints a latin square #
|
||||
PROC print square = ( [,]CHAR square )VOID:
|
||||
FOR row FROM 1 LWB square TO 1 UPB square DO
|
||||
IF 2 LWB square <= 2 UPB square THEN
|
||||
print( ( square[ row, 2 LWB square ] ) );
|
||||
FOR col FROM 2 LWB square + 1 TO 2 UPB square DO
|
||||
print( ( " ", square[ row, col ] ) )
|
||||
OD;
|
||||
print( ( newline ) )
|
||||
FI
|
||||
OD # print square # ;
|
||||
|
||||
next random;
|
||||
print square( latin square( 5 ) );
|
||||
print( ( newline ) );
|
||||
print square( latin square( 5 ) );
|
||||
print( ( newline ) );
|
||||
print square( latin square( 10 ) )
|
||||
|
||||
END
|
||||
124
Task/Random-Latin-squares/Action-/random-latin-squares.action
Normal file
124
Task/Random-Latin-squares/Action-/random-latin-squares.action
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
DEFINE PTR="CARD"
|
||||
DEFINE DIMENSION="5"
|
||||
|
||||
TYPE Matrix=[
|
||||
PTR data ;BYTE ARRAY
|
||||
BYTE dim]
|
||||
|
||||
PTR FUNC GetPtr(Matrix POINTER mat BYTE x,y)
|
||||
RETURN (mat.data+x+y*mat.dim)
|
||||
|
||||
PROC PrintMatrix(Matrix POINTER mat)
|
||||
BYTE x,y
|
||||
BYTE POINTER d
|
||||
|
||||
d=GetPtr(mat,0,0)
|
||||
FOR y=0 TO mat.dim-1
|
||||
DO
|
||||
FOR x=0 TO mat.dim-1
|
||||
DO
|
||||
PrintB(d^) Put(32)
|
||||
d==+1
|
||||
OD
|
||||
PutE()
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC KnuthShuffle(BYTE ARRAY tab BYTE size)
|
||||
BYTE i,j,tmp
|
||||
|
||||
i=size-1
|
||||
WHILE i>0
|
||||
DO
|
||||
j=Rand(i+1)
|
||||
tmp=tab(i)
|
||||
tab(i)=tab(j)
|
||||
tab(j)=tmp
|
||||
i==-1
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC LatinSquare(Matrix POINTER mat)
|
||||
BYTE x,y,yy,shuffled
|
||||
BYTE POINTER ptr1,ptr2
|
||||
BYTE ARRAY used(DIMENSION)
|
||||
|
||||
ptr1=GetPtr(mat,0,0)
|
||||
FOR y=0 TO mat.dim-1
|
||||
DO
|
||||
FOR x=0 TO mat.dim-1
|
||||
DO
|
||||
ptr1^=x
|
||||
ptr1==+1
|
||||
OD
|
||||
OD
|
||||
|
||||
;first row
|
||||
ptr1=GetPtr(mat,0,0)
|
||||
KnuthShuffle(ptr1,mat.dim)
|
||||
|
||||
;middle rows
|
||||
FOR y=1 TO mat.dim-2
|
||||
DO
|
||||
shuffled=0
|
||||
WHILE shuffled=0
|
||||
DO
|
||||
ptr1=GetPtr(mat,0,y)
|
||||
KnuthShuffle(ptr1,mat.dim)
|
||||
|
||||
shuffled=1
|
||||
yy=0
|
||||
WHILE shuffled=1 AND yy<y
|
||||
DO
|
||||
x=0
|
||||
WHILE shuffled=1 AND x<mat.dim
|
||||
DO
|
||||
ptr1=GetPtr(mat,x,yy)
|
||||
ptr2=GetPtr(mat,x,y)
|
||||
IF ptr1^=ptr2^ THEN
|
||||
shuffled=0
|
||||
FI
|
||||
x==+1
|
||||
OD
|
||||
yy==+1
|
||||
OD
|
||||
OD
|
||||
OD
|
||||
|
||||
;last row
|
||||
FOR x=0 TO mat.dim-1
|
||||
DO
|
||||
Zero(used,mat.dim)
|
||||
|
||||
FOR y=0 TO mat.dim-2
|
||||
DO
|
||||
ptr1=GetPtr(mat,x,y)
|
||||
yy=ptr1^ used(yy)=1
|
||||
OD
|
||||
|
||||
FOR y=0 TO mat.dim-1
|
||||
DO
|
||||
IF used(y)=0 THEN
|
||||
ptr1=GetPtr(mat,x,mat.dim-1)
|
||||
ptr1^=y
|
||||
EXIT
|
||||
FI
|
||||
OD
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
BYTE ARRAY d(25)
|
||||
BYTE i
|
||||
Matrix mat
|
||||
|
||||
mat.data=d
|
||||
mat.dim=DIMENSION
|
||||
|
||||
FOR i=1 TO 2
|
||||
DO
|
||||
LatinSquare(mat)
|
||||
PrintMatrix(mat)
|
||||
PutE()
|
||||
OD
|
||||
RETURN
|
||||
24
Task/Random-Latin-squares/Arturo/random-latin-squares.arturo
Normal file
24
Task/Random-Latin-squares/Arturo/random-latin-squares.arturo
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
latinSquare: function [n][
|
||||
square: new []
|
||||
variants: shuffle permutate 0..n-1
|
||||
while -> n > size square [
|
||||
row: sample variants
|
||||
'square ++ @[row]
|
||||
filter 'variants 'variant [
|
||||
reject: false
|
||||
loop.with:'i variant 'col [
|
||||
if col = row\[i] ->
|
||||
reject: true
|
||||
]
|
||||
reject
|
||||
]
|
||||
]
|
||||
return square
|
||||
]
|
||||
|
||||
loop 2 'x [
|
||||
ls: latinSquare 5
|
||||
loop ls 'row ->
|
||||
print row
|
||||
print "---------"
|
||||
]
|
||||
94
Task/Random-Latin-squares/C++/random-latin-squares.cpp
Normal file
94
Task/Random-Latin-squares/C++/random-latin-squares.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
|
||||
auto it = v.cbegin();
|
||||
auto end = v.cend();
|
||||
|
||||
os << '[';
|
||||
if (it != end) {
|
||||
os << *it;
|
||||
it = std::next(it);
|
||||
}
|
||||
while (it != end) {
|
||||
os << ", ";
|
||||
os << *it;
|
||||
it = std::next(it);
|
||||
}
|
||||
return os << ']';
|
||||
}
|
||||
|
||||
void printSquare(const std::vector<std::vector<int>> &latin) {
|
||||
for (auto &row : latin) {
|
||||
std::cout << row << '\n';
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
void latinSquare(int n) {
|
||||
if (n <= 0) {
|
||||
std::cout << "[]\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// obtain a time-based seed:
|
||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
auto g = std::default_random_engine(seed);
|
||||
|
||||
std::vector<std::vector<int>> latin;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
std::vector<int> inner;
|
||||
for (int j = 0; j < n; ++j) {
|
||||
inner.push_back(j);
|
||||
}
|
||||
latin.push_back(inner);
|
||||
}
|
||||
// first row
|
||||
std::shuffle(latin[0].begin(), latin[0].end(), g);
|
||||
|
||||
// middle row(s)
|
||||
for (int i = 1; i < n - 1; ++i) {
|
||||
bool shuffled = false;
|
||||
|
||||
while (!shuffled) {
|
||||
std::shuffle(latin[i].begin(), latin[i].end(), g);
|
||||
for (int k = 0; k < i; ++k) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
if (latin[k][j] == latin[i][j]) {
|
||||
goto shuffling;
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true;
|
||||
|
||||
shuffling: {}
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for (int j = 0; j < n; ++j) {
|
||||
std::vector<bool> used(n, false);
|
||||
for (int i = 0; i < n - 1; ++i) {
|
||||
used[latin[i][j]] = true;
|
||||
}
|
||||
for (int k = 0; k < n; ++k) {
|
||||
if (!used[k]) {
|
||||
latin[n - 1][j] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printSquare(latin);
|
||||
}
|
||||
|
||||
int main() {
|
||||
latinSquare(5);
|
||||
latinSquare(5);
|
||||
latinSquare(10);
|
||||
return 0;
|
||||
}
|
||||
105
Task/Random-Latin-squares/C-sharp/random-latin-squares.cs
Normal file
105
Task/Random-Latin-squares/C-sharp/random-latin-squares.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RandomLatinSquares {
|
||||
using Matrix = List<List<int>>;
|
||||
|
||||
// Taken from https://stackoverflow.com/a/1262619
|
||||
static class Helper {
|
||||
private static readonly Random rng = new Random();
|
||||
|
||||
public static void Shuffle<T>(this IList<T> list) {
|
||||
int n = list.Count;
|
||||
while (n > 1) {
|
||||
n--;
|
||||
int k = rng.Next(n + 1);
|
||||
T value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Program {
|
||||
static void PrintSquare(Matrix latin) {
|
||||
foreach (var row in latin) {
|
||||
Console.Write('[');
|
||||
|
||||
var it = row.GetEnumerator();
|
||||
if (it.MoveNext()) {
|
||||
Console.Write(it.Current);
|
||||
}
|
||||
while (it.MoveNext()) {
|
||||
Console.Write(", ");
|
||||
Console.Write(it.Current);
|
||||
}
|
||||
|
||||
Console.WriteLine(']');
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static void LatinSquare(int n) {
|
||||
if (n <= 0) {
|
||||
Console.WriteLine("[]");
|
||||
return;
|
||||
}
|
||||
|
||||
var latin = new Matrix();
|
||||
for (int i = 0; i < n; i++) {
|
||||
List<int> temp = new List<int>();
|
||||
for (int j = 0; j < n; j++) {
|
||||
temp.Add(j);
|
||||
}
|
||||
latin.Add(temp);
|
||||
}
|
||||
// first row
|
||||
latin[0].Shuffle();
|
||||
|
||||
// middle row(s)
|
||||
for (int i = 1; i < n - 1; i++) {
|
||||
bool shuffled = false;
|
||||
|
||||
while (!shuffled) {
|
||||
latin[i].Shuffle();
|
||||
for (int k = 0; k < i; k++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (latin[k][j] == latin[i][j]) {
|
||||
goto shuffling;
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true;
|
||||
|
||||
shuffling: { }
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for (int j = 0; j < n; j++) {
|
||||
List<bool> used = new List<bool>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
used.Add(false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n-1; i++) {
|
||||
used[latin[i][j]] = true;
|
||||
}
|
||||
for (int k = 0; k < n; k++) {
|
||||
if (!used[k]) {
|
||||
latin[n - 1][j] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrintSquare(latin);
|
||||
}
|
||||
|
||||
static void Main() {
|
||||
LatinSquare(5);
|
||||
LatinSquare(5);
|
||||
LatinSquare(10); // for good measure
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Task/Random-Latin-squares/C/random-latin-squares.c
Normal file
118
Task/Random-Latin-squares/C/random-latin-squares.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
// low <= num < high
|
||||
int randInt(int low, int high) {
|
||||
return (rand() % (high - low)) + low;
|
||||
}
|
||||
|
||||
// shuffle an array of n elements
|
||||
void shuffle(int *const array, const int n) {
|
||||
if (n > 1) {
|
||||
int i;
|
||||
for (i = 0; i < n - 1; i++) {
|
||||
int j = randInt(i, n);
|
||||
|
||||
int t = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print an n * n array
|
||||
void printSquare(const int *const latin, const int n) {
|
||||
int i, j;
|
||||
for (i = 0; i < n; i++) {
|
||||
printf("[");
|
||||
for (j = 0; j < n; j++) {
|
||||
if (j > 0) {
|
||||
printf(", ");
|
||||
}
|
||||
printf("%d", latin[i * n + j]);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void latinSquare(const int n) {
|
||||
int *latin, *used;
|
||||
int i, j, k;
|
||||
|
||||
if (n <= 0) {
|
||||
printf("[]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate
|
||||
latin = (int *)malloc(n * n * sizeof(int));
|
||||
if (!latin) {
|
||||
printf("Failed to allocate memory.");
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize
|
||||
for (i = 0; i < n; i++) {
|
||||
for (j = 0; j < n; j++) {
|
||||
latin[i * n + j] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// first row
|
||||
shuffle(latin, n);
|
||||
|
||||
// middle row(s)
|
||||
for (i = 1; i < n - 1; i++) {
|
||||
bool shuffled = false;
|
||||
|
||||
while (!shuffled) {
|
||||
shuffle(&latin[i * n], n);
|
||||
|
||||
for (k = 0; k < i; k++) {
|
||||
for (j = 0; j < n; j++) {
|
||||
if (latin[k * n + j] == latin[i * n + j]) {
|
||||
goto shuffling;
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true;
|
||||
|
||||
shuffling: {}
|
||||
}
|
||||
}
|
||||
|
||||
//last row
|
||||
used = (int *)malloc(n * sizeof(int));
|
||||
for (j = 0; j < n; j++) {
|
||||
memset(used, 0, n * sizeof(int));
|
||||
for (i = 0; i < n - 1; i++) {
|
||||
used[latin[i * n + j]] = 1;
|
||||
}
|
||||
for (k = 0; k < n; k++) {
|
||||
if (used[k] == 0) {
|
||||
latin[(n - 1) * n + j] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(used);
|
||||
|
||||
// print the result
|
||||
printSquare(latin, n);
|
||||
free(latin);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// initialze the random number generator
|
||||
srand((unsigned int)time((time_t)0));
|
||||
|
||||
latinSquare(5);
|
||||
latinSquare(5);
|
||||
latinSquare(10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
73
Task/Random-Latin-squares/D/random-latin-squares.d
Normal file
73
Task/Random-Latin-squares/D/random-latin-squares.d
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import std.array;
|
||||
import std.random;
|
||||
import std.stdio;
|
||||
|
||||
alias Matrix = int[][];
|
||||
|
||||
void latinSquare(int n) {
|
||||
if (n <= 0) {
|
||||
writeln("[]");
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix latin = uninitializedArray!Matrix(n, n);
|
||||
foreach (row; latin) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
row[i] = i;
|
||||
}
|
||||
}
|
||||
// first row
|
||||
latin[0].randomShuffle;
|
||||
|
||||
// middle row(s)
|
||||
for (int i = 1; i < n - 1; i++) {
|
||||
bool shuffled = false;
|
||||
|
||||
shuffling:
|
||||
while (!shuffled) {
|
||||
latin[i].randomShuffle;
|
||||
for (int k = 0; k < i; k++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (latin[k][j] == latin[i][j]) {
|
||||
continue shuffling;
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for (int j = 0; j < n; j++) {
|
||||
bool[] used = uninitializedArray!(bool[])(n);
|
||||
used[] = false;
|
||||
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
used[latin[i][j]] = true;
|
||||
}
|
||||
for (int k = 0; k < n; k++) {
|
||||
if (!used[k]) {
|
||||
latin[n - 1][j] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printSquare(latin);
|
||||
}
|
||||
|
||||
void printSquare(Matrix latin) {
|
||||
foreach (row; latin) {
|
||||
writeln(row);
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
latinSquare(5);
|
||||
writeln;
|
||||
|
||||
latinSquare(5);
|
||||
writeln;
|
||||
|
||||
latinSquare(10);
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Generate 2 Random Latin Squares of order 5. Nigel Galloway: July 136th., 2019
|
||||
let N=let N=System.Random() in (fun n->N.Next(n))
|
||||
let rc()=let β=lN2p [|0;N 4;N 3;N 2|] [|0..4|] in Seq.item (N 56) (normLS 5) |> List.map(lN2p [|N 5;N 4;N 3;N 2|]) |> List.permute(fun n->β.[n]) |> List.iter(printfn "%A")
|
||||
rc(); printfn ""; rc()
|
||||
11
Task/Random-Latin-squares/Factor/random-latin-squares.factor
Normal file
11
Task/Random-Latin-squares/Factor/random-latin-squares.factor
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
USING: arrays combinators.extras fry io kernel math.matrices
|
||||
prettyprint random sequences sets ;
|
||||
IN: rosetta-code.random-latin-squares
|
||||
|
||||
: rand-permutation ( n -- seq ) <iota> >array randomize ;
|
||||
: ls? ( n -- ? ) [ all-unique? ] column-map t [ and ] reduce ;
|
||||
: (ls) ( n -- m ) dup '[ _ rand-permutation ] replicate ;
|
||||
: ls ( n -- m ) dup (ls) dup ls? [ nip ] [ drop ls ] if ;
|
||||
: random-latin-squares ( -- ) [ 5 ls simple-table. nl ] twice ;
|
||||
|
||||
MAIN: random-latin-squares
|
||||
80
Task/Random-Latin-squares/Go/random-latin-squares-1.go
Normal file
80
Task/Random-Latin-squares/Go/random-latin-squares-1.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type matrix [][]int
|
||||
|
||||
func shuffle(row []int, n int) {
|
||||
rand.Shuffle(n, func(i, j int) {
|
||||
row[i], row[j] = row[j], row[i]
|
||||
})
|
||||
}
|
||||
|
||||
func latinSquare(n int) {
|
||||
if n <= 0 {
|
||||
fmt.Println("[]\n")
|
||||
return
|
||||
}
|
||||
latin := make(matrix, n)
|
||||
for i := 0; i < n; i++ {
|
||||
latin[i] = make([]int, n)
|
||||
if i == n-1 {
|
||||
break
|
||||
}
|
||||
for j := 0; j < n; j++ {
|
||||
latin[i][j] = j
|
||||
}
|
||||
}
|
||||
// first row
|
||||
shuffle(latin[0], n)
|
||||
|
||||
// middle row(s)
|
||||
for i := 1; i < n-1; i++ {
|
||||
shuffled := false
|
||||
shuffling:
|
||||
for !shuffled {
|
||||
shuffle(latin[i], n)
|
||||
for k := 0; k < i; k++ {
|
||||
for j := 0; j < n; j++ {
|
||||
if latin[k][j] == latin[i][j] {
|
||||
continue shuffling
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for j := 0; j < n; j++ {
|
||||
used := make([]bool, n)
|
||||
for i := 0; i < n-1; i++ {
|
||||
used[latin[i][j]] = true
|
||||
}
|
||||
for k := 0; k < n; k++ {
|
||||
if !used[k] {
|
||||
latin[n-1][j] = k
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
printSquare(latin, n)
|
||||
}
|
||||
|
||||
func printSquare(latin matrix, n int) {
|
||||
for i := 0; i < n; i++ {
|
||||
fmt.Println(latin[i])
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
latinSquare(5)
|
||||
latinSquare(5)
|
||||
latinSquare(10) // for good measure
|
||||
}
|
||||
253
Task/Random-Latin-squares/Go/random-latin-squares-2.go
Normal file
253
Task/Random-Latin-squares/Go/random-latin-squares-2.go
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
type matrix [][]int
|
||||
|
||||
// generate derangements of first n numbers, with 'start' in first place.
|
||||
func dList(n, start int) (r matrix) {
|
||||
start-- // use 0 basing
|
||||
a := make([]int, n)
|
||||
for i := range a {
|
||||
a[i] = i
|
||||
}
|
||||
a[0], a[start] = start, a[0]
|
||||
sort.Ints(a[1:])
|
||||
first := a[1]
|
||||
// recursive closure permutes a[1:]
|
||||
var recurse func(last int)
|
||||
recurse = func(last int) {
|
||||
if last == first {
|
||||
// bottom of recursion. you get here once for each permutation.
|
||||
// test if permutation is deranged.
|
||||
for j, v := range a[1:] { // j starts from 0, not 1
|
||||
if j+1 == v {
|
||||
return // no, ignore it
|
||||
}
|
||||
}
|
||||
// yes, save a copy
|
||||
b := make([]int, n)
|
||||
copy(b, a)
|
||||
for i := range b {
|
||||
b[i]++ // change back to 1 basing
|
||||
}
|
||||
r = append(r, b)
|
||||
return
|
||||
}
|
||||
for i := last; i >= 1; i-- {
|
||||
a[i], a[last] = a[last], a[i]
|
||||
recurse(last - 1)
|
||||
a[i], a[last] = a[last], a[i]
|
||||
}
|
||||
}
|
||||
recurse(n - 1)
|
||||
return
|
||||
}
|
||||
|
||||
func reducedLatinSquares(n int) []matrix {
|
||||
var rls []matrix
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
rlatin := make(matrix, n)
|
||||
for i := 0; i < n; i++ {
|
||||
rlatin[i] = make([]int, n)
|
||||
}
|
||||
if n <= 1 {
|
||||
return append(rls, rlatin)
|
||||
}
|
||||
// first row
|
||||
for j := 0; j < n; j++ {
|
||||
rlatin[0][j] = j + 1
|
||||
}
|
||||
// recursive closure to compute reduced latin squares
|
||||
var recurse func(i int)
|
||||
recurse = func(i int) {
|
||||
rows := dList(n, i) // get derangements of first n numbers, with 'i' first.
|
||||
outer:
|
||||
for r := 0; r < len(rows); r++ {
|
||||
copy(rlatin[i-1], rows[r])
|
||||
for k := 0; k < i-1; k++ {
|
||||
for j := 1; j < n; j++ {
|
||||
if rlatin[k][j] == rlatin[i-1][j] {
|
||||
if r < len(rows)-1 {
|
||||
continue outer
|
||||
} else if i > 2 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if i < n {
|
||||
recurse(i + 1)
|
||||
} else {
|
||||
rl := copyMatrix(rlatin)
|
||||
rls = append(rls, rl)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// remaining rows
|
||||
recurse(2)
|
||||
return rls
|
||||
}
|
||||
|
||||
func copyMatrix(m matrix) matrix {
|
||||
le := len(m)
|
||||
cpy := make(matrix, le)
|
||||
for i := 0; i < le; i++ {
|
||||
cpy[i] = make([]int, le)
|
||||
copy(cpy[i], m[i])
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
|
||||
func printSquare(latin matrix, n int) {
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < n; j++ {
|
||||
fmt.Printf("%d ", latin[i][j]-1)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func factorial(n uint64) uint64 {
|
||||
if n == 0 {
|
||||
return 1
|
||||
}
|
||||
prod := uint64(1)
|
||||
for i := uint64(2); i <= n; i++ {
|
||||
prod *= i
|
||||
}
|
||||
return prod
|
||||
}
|
||||
|
||||
// generate permutations of first n numbers, starting from 0.
|
||||
func pList(n int) matrix {
|
||||
fact := factorial(uint64(n))
|
||||
perms := make(matrix, fact)
|
||||
a := make([]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
a[i] = i
|
||||
}
|
||||
t := make([]int, n)
|
||||
copy(t, a)
|
||||
perms[0] = t
|
||||
n--
|
||||
var i, j int
|
||||
for c := uint64(1); c < fact; c++ {
|
||||
i = n - 1
|
||||
j = n
|
||||
for a[i] > a[i+1] {
|
||||
i--
|
||||
}
|
||||
for a[j] < a[i] {
|
||||
j--
|
||||
}
|
||||
a[i], a[j] = a[j], a[i]
|
||||
j = n
|
||||
i++
|
||||
for i < j {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
i++
|
||||
j--
|
||||
}
|
||||
t := make([]int, n+1)
|
||||
copy(t, a)
|
||||
perms[c] = t
|
||||
}
|
||||
return perms
|
||||
}
|
||||
|
||||
func generateLatinSquares(n, tests, echo int) {
|
||||
rls := reducedLatinSquares(n)
|
||||
perms := pList(n)
|
||||
perms2 := pList(n - 1)
|
||||
for test := 0; test < tests; test++ {
|
||||
rn := rand.Intn(len(rls))
|
||||
rl := rls[rn] // select reduced random square at random
|
||||
rn = rand.Intn(len(perms))
|
||||
rp := perms[rn] // select a random permuation of 'rl's columns
|
||||
// permute columns
|
||||
t := make(matrix, n)
|
||||
for i := 0; i < n; i++ {
|
||||
t[i] = make([]int, n)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < n; j++ {
|
||||
t[i][j] = rl[i][rp[j]]
|
||||
}
|
||||
}
|
||||
rn = rand.Intn(len(perms2))
|
||||
rp = perms2[rn] // select a random permutation of 't's rows 2 to n
|
||||
// permute rows 2 to n
|
||||
u := make(matrix, n)
|
||||
for i := 0; i < n; i++ {
|
||||
u[i] = make([]int, n)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < n; j++ {
|
||||
if i == 0 {
|
||||
u[i][j] = t[i][j]
|
||||
} else {
|
||||
u[i][j] = t[rp[i-1]+1][j]
|
||||
}
|
||||
}
|
||||
}
|
||||
if test < echo {
|
||||
printSquare(u, n)
|
||||
}
|
||||
if n == 4 {
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 4; j++ {
|
||||
u[i][j]--
|
||||
}
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
copy(a[4*i:], u[i])
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
if testSquares[i] == a {
|
||||
counts[i]++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testSquares = [4][16]int{
|
||||
{0, 1, 2, 3, 1, 0, 3, 2, 2, 3, 0, 1, 3, 2, 1, 0},
|
||||
{0, 1, 2, 3, 1, 0, 3, 2, 2, 3, 1, 0, 3, 2, 0, 1},
|
||||
{0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2},
|
||||
{0, 1, 2, 3, 1, 3, 0, 2, 2, 0, 3, 1, 3, 2, 1, 0},
|
||||
}
|
||||
|
||||
var (
|
||||
counts [4]int
|
||||
a [16]int
|
||||
)
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
fmt.Println("Two randomly generated latin squares of order 5 are:\n")
|
||||
generateLatinSquares(5, 2, 2)
|
||||
|
||||
fmt.Println("Out of 1,000,000 randomly generated latin squares of order 4, ")
|
||||
fmt.Println("of which there are 576 instances ( => expected 1736 per instance),")
|
||||
fmt.Println("the following squares occurred the number of times shown:\n")
|
||||
generateLatinSquares(4, 1e6, 0)
|
||||
for i := 0; i < 4; i++ {
|
||||
fmt.Println(testSquares[i][:], ":", counts[i])
|
||||
}
|
||||
|
||||
fmt.Println("\nA randomly generated latin square of order 6 is:\n")
|
||||
generateLatinSquares(6, 1, 1)
|
||||
}
|
||||
28
Task/Random-Latin-squares/Haskell/random-latin-squares-1.hs
Normal file
28
Task/Random-Latin-squares/Haskell/random-latin-squares-1.hs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import Data.List (permutations, (\\))
|
||||
|
||||
latinSquare :: Eq a => [a] -> [a] -> [[a]]
|
||||
latinSquare [] [] = []
|
||||
latinSquare c r
|
||||
| head r /= head c = []
|
||||
| otherwise = reverse <$> foldl addRow firstRow perms
|
||||
where
|
||||
-- permutations grouped by the first element
|
||||
perms =
|
||||
tail $
|
||||
fmap
|
||||
(fmap . (:) <*> (permutations . (r \\) . return))
|
||||
c
|
||||
firstRow = pure <$> r
|
||||
addRow tbl rows =
|
||||
head
|
||||
[ zipWith (:) row tbl
|
||||
| row <- rows,
|
||||
and $ different (tail row) (tail tbl)
|
||||
]
|
||||
different = zipWith $ (not .) . elem
|
||||
|
||||
printTable :: Show a => [[a]] -> IO ()
|
||||
printTable tbl =
|
||||
putStrLn $
|
||||
unlines $
|
||||
unwords . map show <$> tbl
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
randomLatinSquare :: Eq a => [a] -> Random [[a]]
|
||||
randomLatinSquare set = do
|
||||
r <- randomPermutation set
|
||||
c <- randomPermutation (tail r)
|
||||
return $ latinSquare r (head r:c)
|
||||
21
Task/Random-Latin-squares/Haskell/random-latin-squares-3.hs
Normal file
21
Task/Random-Latin-squares/Haskell/random-latin-squares-3.hs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import Control.Monad.State
|
||||
|
||||
type Random a = State Int a
|
||||
|
||||
random :: Integral a => a -> Random a
|
||||
random k = rescale <$> modify iter
|
||||
where
|
||||
iter x = (x * a + c) `mod` m
|
||||
(a, c, m) = (1103515245, 12345, 2^31-1)
|
||||
rescale x = fromIntegral x `mod` k
|
||||
|
||||
randomPermutation :: Eq a => [a] -> Random [a]
|
||||
randomPermutation = go
|
||||
where
|
||||
go [] = pure []
|
||||
go lst = do
|
||||
x <- randomSample lst
|
||||
(x :) <$> go (lst \\ [x])
|
||||
|
||||
randomSample :: [a] -> Random a
|
||||
randomSample lst = (lst !!) <$> random (length lst)
|
||||
11
Task/Random-Latin-squares/J/random-latin-squares.j
Normal file
11
Task/Random-Latin-squares/J/random-latin-squares.j
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rls=: 3 : 0
|
||||
s=. ?~ y NB. "deal" y unique integers from 0 to y
|
||||
for_ijk. i.<:y do.
|
||||
NB. deal a new row. subtract it from all previous rows
|
||||
NB. if you get a 0, some column has a matching integer, deal again
|
||||
whilst. 0 = */ */ s -"1 r do.
|
||||
r=. ?~ y
|
||||
end.
|
||||
s=. s ,,: r NB. "laminate" successful row to the square
|
||||
end.
|
||||
)
|
||||
86
Task/Random-Latin-squares/Java/random-latin-squares.java
Normal file
86
Task/Random-Latin-squares/Java/random-latin-squares.java
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RandomLatinSquares {
|
||||
private static void printSquare(List<List<Integer>> latin) {
|
||||
for (List<Integer> row : latin) {
|
||||
Iterator<Integer> it = row.iterator();
|
||||
|
||||
System.out.print("[");
|
||||
if (it.hasNext()) {
|
||||
Integer col = it.next();
|
||||
System.out.print(col);
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
Integer col = it.next();
|
||||
System.out.print(", ");
|
||||
System.out.print(col);
|
||||
}
|
||||
System.out.println("]");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static void latinSquare(int n) {
|
||||
if (n <= 0) {
|
||||
System.out.println("[]");
|
||||
return;
|
||||
}
|
||||
|
||||
List<List<Integer>> latin = new ArrayList<>(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
List<Integer> inner = new ArrayList<>(n);
|
||||
for (int j = 0; j < n; ++j) {
|
||||
inner.add(j);
|
||||
}
|
||||
latin.add(inner);
|
||||
}
|
||||
// first row
|
||||
Collections.shuffle(latin.get(0));
|
||||
|
||||
// middle row(s)
|
||||
for (int i = 1; i < n - 1; ++i) {
|
||||
boolean shuffled = false;
|
||||
shuffling:
|
||||
while (!shuffled) {
|
||||
Collections.shuffle(latin.get(i));
|
||||
for (int k = 0; k < i; ++k) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
if (Objects.equals(latin.get(k).get(j), latin.get(i).get(j))) {
|
||||
continue shuffling;
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for (int j = 0; j < n; ++j) {
|
||||
List<Boolean> used = new ArrayList<>(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
used.add(false);
|
||||
}
|
||||
for (int i = 0; i < n - 1; ++i) {
|
||||
used.set(latin.get(i).get(j), true);
|
||||
}
|
||||
for (int k = 0; k < n; ++k) {
|
||||
if (!used.get(k)) {
|
||||
latin.get(n - 1).set(j, k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printSquare(latin);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
latinSquare(5);
|
||||
latinSquare(5);
|
||||
latinSquare(10);
|
||||
}
|
||||
}
|
||||
52
Task/Random-Latin-squares/JavaScript/random-latin-squares.js
Normal file
52
Task/Random-Latin-squares/JavaScript/random-latin-squares.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
class Latin {
|
||||
constructor(size = 3) {
|
||||
this.size = size;
|
||||
this.mst = [...Array(this.size)].map((v, i) => i + 1);
|
||||
this.square = Array(this.size).fill(0).map(() => Array(this.size).fill(0));
|
||||
|
||||
if (this.create(0, 0)) {
|
||||
console.table(this.square);
|
||||
}
|
||||
}
|
||||
|
||||
create(c, r) {
|
||||
const d = [...this.mst];
|
||||
let s;
|
||||
while (true) {
|
||||
do {
|
||||
s = d.splice(Math.floor(Math.random() * d.length), 1)[0];
|
||||
if (!s) return false;
|
||||
} while (this.check(s, c, r));
|
||||
|
||||
this.square[c][r] = s;
|
||||
if (++c >= this.size) {
|
||||
c = 0;
|
||||
if (++r >= this.size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this.create(c, r)) return true;
|
||||
if (--c < 0) {
|
||||
c = this.size - 1;
|
||||
if (--r < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check(d, c, r) {
|
||||
for (let a = 0; a < this.size; a++) {
|
||||
if (c - a > -1) {
|
||||
if (this.square[c - a][r] === d)
|
||||
return true;
|
||||
}
|
||||
if (r - a > -1) {
|
||||
if (this.square[c][r - a] === d)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
new Latin(5);
|
||||
2
Task/Random-Latin-squares/Jq/random-latin-squares-1.jq
Normal file
2
Task/Random-Latin-squares/Jq/random-latin-squares-1.jq
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
< /dev/random tr -cd '0-9' | fold -w 1 | jq -Mcnr -f random-latin-squares.jq
|
||||
42
Task/Random-Latin-squares/Jq/random-latin-squares-2.jq
Normal file
42
Task/Random-Latin-squares/Jq/random-latin-squares-2.jq
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
'''Generic Utility Functions'''
|
||||
# For inclusion using jq's `include` directive:
|
||||
# Output: a PRN in range(0;$n) where $n is .
|
||||
def prn:
|
||||
if . == 1 then 0
|
||||
else . as $n
|
||||
| (($n-1)|tostring|length) as $w
|
||||
| [limit($w; inputs)] | join("") | tonumber
|
||||
| if . < $n then . else ($n | prn) end
|
||||
end;
|
||||
|
||||
def knuthShuffle:
|
||||
length as $n
|
||||
| if $n <= 1 then .
|
||||
else {i: $n, a: .}
|
||||
| until(.i == 0;
|
||||
.i += -1
|
||||
| (.i + 1 | prn) as $j
|
||||
| .a[.i] as $t
|
||||
| .a[.i] = .a[$j]
|
||||
| .a[$j] = $t)
|
||||
| .a
|
||||
end;
|
||||
|
||||
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
|
||||
|
||||
# If the input array is not rectangular, let nulls fall where they may
|
||||
def column($j):
|
||||
[.[] | .[$j]];
|
||||
|
||||
# Emit a stream of [value, frequency] pairs
|
||||
def histogram(stream):
|
||||
reduce stream as $s ({};
|
||||
($s|type) as $t
|
||||
| (if $t == "string" then $s else ($s|tojson) end) as $y
|
||||
| .[$t][$y][0] = $s
|
||||
| .[$t][$y][1] += 1 )
|
||||
| .[][] ;
|
||||
|
||||
def ss(s): reduce s as $x (0; . + ($x * $x));
|
||||
|
||||
def chiSquared($expected): ss( .[] - $expected ) / $expected;
|
||||
85
Task/Random-Latin-squares/Jq/random-latin-squares-3.jq
Normal file
85
Task/Random-Latin-squares/Jq/random-latin-squares-3.jq
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Include the utilities e.g. by
|
||||
# include "random-latin-squares.utilities" {search: "."};
|
||||
|
||||
# Determine orthogonality of two arrays, confining attention
|
||||
# to the first $n elements in each:
|
||||
def orthogonal($a; $b; $n):
|
||||
first( (range(0; $n) | if $a[.] == $b[.] then 0 else empty end) // 1) | . == 1;
|
||||
|
||||
# Are the two arrays orthogonal up to the length of the shorter?
|
||||
def orthogonal($a; $b):
|
||||
([$a, $b | length] | min) as $min
|
||||
| orthogonal($a; $b; $min);
|
||||
|
||||
# Is row $i orthogonal to all the previous rows?
|
||||
def orthogonal($i):
|
||||
. as $in
|
||||
| .[$i] as $row
|
||||
| all(range(0;$i); orthogonal($row; $in[.]));
|
||||
|
||||
# verify columnwise orthogonality
|
||||
def columnwise:
|
||||
length as $n
|
||||
| transpose as $t
|
||||
| all( range(1;$n); . as $i | $t | orthogonal($i)) ;
|
||||
|
||||
def addLast:
|
||||
(.[0] | length) as $n
|
||||
| [range(0; $n)] as $range
|
||||
| [range(0; $n) as $i
|
||||
| ($range - column($i))[0] ] as $last
|
||||
| . + [$last] ;
|
||||
|
||||
# input: an array being a permutation of [range(0;$n)] for some $n
|
||||
# output: a Latin Square selected at random from all the candidates
|
||||
def extend:
|
||||
(.[0] | length) as $n
|
||||
| if length >= $n then .
|
||||
elif length == $n - 1 then addLast
|
||||
else ([range(0; $n)] | knuthShuffle) as $row
|
||||
| (. + [$row] )
|
||||
| if orthogonal(length - 1) and columnwise then extend else empty end
|
||||
end ;
|
||||
|
||||
# Generate a Latin Square.
|
||||
# The input should be an integer specifying its size.
|
||||
def latinSquare:
|
||||
. as $n
|
||||
| if $n <= 0 then []
|
||||
else
|
||||
[ [range(0; $n)] | knuthShuffle]
|
||||
| first(repeat(extend))
|
||||
# | (if columnwise then . else debug end) # internal check
|
||||
end ;
|
||||
|
||||
# If the input is a positive integer, $n, generate and print an $n x $n Latin Square.
|
||||
# If it is not number, echo it.
|
||||
def printLatinSquare:
|
||||
if type == "number"
|
||||
then latinSquare
|
||||
| .[] | map(lpad(3)) | join(" ")
|
||||
else .
|
||||
end;
|
||||
|
||||
# $order should be in 1 .. 5 inclusive
|
||||
# If $n is null, then use 10 * $counts[$order]
|
||||
def stats($order; $n):
|
||||
# table of counts:
|
||||
[0,1,2,12,576,161280] as $counts
|
||||
| $counts[$order] as $possibilities
|
||||
| (if $n then $n else 10 * $possibilities end) as $n
|
||||
| reduce range(0;$n) as $i ({};
|
||||
($order|latinSquare|flatten|join("")) as $row
|
||||
| .[$row] += 1)
|
||||
| # ([histogram(.[])] | sort[] | join(" ")),
|
||||
"Number of LS(\($order)): \($n)",
|
||||
(if length == $possibilities
|
||||
then "All \($possibilities) possibilities have been generated."
|
||||
else "Of \($possibilities) possibilities, only \(length) were generated."
|
||||
end),
|
||||
"Chi-squared statistic (df=\($possibilities-1)): \( [.[]] | chiSquared( $n / $possibilities))";
|
||||
|
||||
|
||||
stats(3;null), "",
|
||||
stats(4;5760), ""
|
||||
stats(4;5760)
|
||||
62
Task/Random-Latin-squares/Jq/random-latin-squares-4.jq
Normal file
62
Task/Random-Latin-squares/Jq/random-latin-squares-4.jq
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Include the utilities e.g. by
|
||||
# include "random-latin-squares.utilities" {search: "."};
|
||||
|
||||
# Select an element at random from [range(0;$n)] - column($j)
|
||||
def candidate($j):
|
||||
(.[0] | length) as $n
|
||||
| [range(0;$n)] - column($j)
|
||||
| .[length|prn];
|
||||
|
||||
# Input: the first row or rows of a Latin Square
|
||||
def extend:
|
||||
# The input to ext should be several rows of a Latin Square
|
||||
# optionally followed by a candidate for an additional row.
|
||||
def ext:
|
||||
.[0] as $first
|
||||
| length as $length
|
||||
| ($first|length) as $n
|
||||
| .[-1] as $last
|
||||
| if ($last|length) < $n # then extend the last row
|
||||
then ( ([range(0;$n)] - column($last|length)) - $last) as $candidates
|
||||
| .[:$length-1] as $good
|
||||
| ($candidates|length) as $cl
|
||||
|
||||
# if we can complete the row, then there is no need for another backtrack point!
|
||||
| if $cl == 1 and ($last|length) == $n - 1
|
||||
then ($good + [ $last + $candidates]) | ext # n.b. or use `extend` to speed things up at the cost of more bias
|
||||
else
|
||||
if $cl == 1 then ($good + [ $last + $candidates]) | ext
|
||||
elif $cl == 0
|
||||
then empty
|
||||
else ($candidates[$cl | prn] as $add
|
||||
| ($good + [$last + [$add]]) | ext)
|
||||
end
|
||||
end
|
||||
elif length < $n then ((. + [[candidate(0)]]) | ext)
|
||||
else .
|
||||
end;
|
||||
# If at first you do not succeed ...
|
||||
first( repeat( ext ));
|
||||
|
||||
# Generate a Latin Square.
|
||||
# The input should be an integer specifying its size.
|
||||
def latinSquare:
|
||||
. as $n
|
||||
| if $n <= 0 then []
|
||||
else
|
||||
[ [range(0; $n)] | knuthShuffle]
|
||||
| extend
|
||||
end ;
|
||||
|
||||
# If the input is a positive integer, $n, generate and print an $n x $n Latin Square.
|
||||
# Otherwise, simply echo it.
|
||||
def printLatinSquare:
|
||||
if type == "number"
|
||||
then latinSquare
|
||||
| .[] | map(lpad(3)) | join(" ")
|
||||
else .
|
||||
end;
|
||||
|
||||
"Five", 5, "\nFive", 5, "\nTen", 10, "\nForty", 40
|
||||
| printLatinSquare
|
||||
'
|
||||
31
Task/Random-Latin-squares/Julia/random-latin-squares.julia
Normal file
31
Task/Random-Latin-squares/Julia/random-latin-squares.julia
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using Random
|
||||
|
||||
shufflerows(mat) = mat[shuffle(1:end), :]
|
||||
shufflecols(mat) = mat[:, shuffle(1:end)]
|
||||
|
||||
function addatdiagonal(mat)
|
||||
n = size(mat)[1] + 1
|
||||
newmat = similar(mat, size(mat) .+ 1)
|
||||
for j in 1:n, i in 1:n
|
||||
newmat[i, j] = (i == n && j < n) ? mat[1, j] : (i == j) ? n - 1 :
|
||||
(i < j) ? mat[i, j - 1] : mat[i, j]
|
||||
end
|
||||
newmat
|
||||
end
|
||||
|
||||
function makelatinsquare(N)
|
||||
mat = [0 1; 1 0]
|
||||
for i in 3:N
|
||||
mat = addatdiagonal(mat)
|
||||
end
|
||||
shufflecols(shufflerows(mat))
|
||||
end
|
||||
|
||||
function printlatinsquare(N)
|
||||
mat = makelatinsquare(N)
|
||||
for i in 1:N, j in 1:N
|
||||
print(rpad(mat[i, j], 3), j == N ? "\n" : "")
|
||||
end
|
||||
end
|
||||
|
||||
printlatinsquare(5), println("\n"), printlatinsquare(5)
|
||||
58
Task/Random-Latin-squares/Kotlin/random-latin-squares.kotlin
Normal file
58
Task/Random-Latin-squares/Kotlin/random-latin-squares.kotlin
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
typealias matrix = MutableList<MutableList<Int>>
|
||||
|
||||
fun printSquare(latin: matrix) {
|
||||
for (row in latin) {
|
||||
println(row)
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
fun latinSquare(n: Int) {
|
||||
if (n <= 0) {
|
||||
println("[]")
|
||||
return
|
||||
}
|
||||
|
||||
val latin = MutableList(n) { MutableList(n) { it } }
|
||||
// first row
|
||||
latin[0].shuffle()
|
||||
|
||||
// middle row(s)
|
||||
for (i in 1 until n - 1) {
|
||||
var shuffled = false
|
||||
shuffling@
|
||||
while (!shuffled) {
|
||||
latin[i].shuffle()
|
||||
for (k in 0 until i) {
|
||||
for (j in 0 until n) {
|
||||
if (latin[k][j] == latin[i][j]) {
|
||||
continue@shuffling
|
||||
}
|
||||
}
|
||||
}
|
||||
shuffled = true
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for (j in 0 until n) {
|
||||
val used = MutableList(n) { false }
|
||||
for (i in 0 until n - 1) {
|
||||
used[latin[i][j]] = true
|
||||
}
|
||||
for (k in 0 until n) {
|
||||
if (!used[k]) {
|
||||
latin[n - 1][j] = k
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printSquare(latin)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
latinSquare(5)
|
||||
latinSquare(5)
|
||||
latinSquare(10) // for good measure
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
Module FastLatinSquare {
|
||||
n=5
|
||||
For k=1 To 2
|
||||
latin()
|
||||
Next
|
||||
n=40
|
||||
latin()
|
||||
Sub latin()
|
||||
Local i,a, a(1 To n), b, k
|
||||
Profiler
|
||||
flush
|
||||
Print "latin square ";n;" by ";n
|
||||
For i=1 To n
|
||||
Push i
|
||||
Next i
|
||||
For i=1 To n div 2
|
||||
Shiftback random(2, n)
|
||||
Next i
|
||||
a=[]
|
||||
Push ! stack(a)
|
||||
a=array(a) ' change a from stack to array
|
||||
For i=1 To n*10
|
||||
Shiftback random(2, n)
|
||||
Next i
|
||||
For i=0 To n-1
|
||||
Data number ' rotate by one the stack items
|
||||
b=[] ' move stack To b, leave empty stack
|
||||
a(a#val(i))=b
|
||||
Push ! stack(b) ' Push from a copy of b all items To stack
|
||||
Next i
|
||||
flush
|
||||
For k=1 To n div 2
|
||||
z=random(2, n)
|
||||
For i=1 To n
|
||||
a=a(i)
|
||||
stack a {
|
||||
shift z
|
||||
}
|
||||
Next
|
||||
Next
|
||||
For i=1 To n
|
||||
a=a(i)
|
||||
a(i)=array(a) ' change To array from stack
|
||||
Next i
|
||||
For i=1 To n
|
||||
Print a(i)
|
||||
Next i
|
||||
Print TimeCount
|
||||
End Sub
|
||||
}
|
||||
FastLatinSquare
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
Module LatinSquare (n, z=1, f$="latin.dat", NewFile As Boolean=False) {
|
||||
If Not Exist(f$) Or NewFile Then
|
||||
Open f$ For Wide Output As f
|
||||
Else
|
||||
Open f$ For Wide Append As f
|
||||
End If
|
||||
ArrayToString=Lambda -> {
|
||||
Shift 2 ' swap two top values in stack
|
||||
Push Letter$+Str$(Number)
|
||||
}
|
||||
Dim line(1 to n)
|
||||
flush ' erase current stack of value
|
||||
z=if(z<1->1, z)
|
||||
newColumn()
|
||||
For j=1 To z
|
||||
Profiler
|
||||
ResetColumns()
|
||||
For i=1 To n
|
||||
placeColumn()
|
||||
Next
|
||||
Print "A latin square of ";n;" by ";n
|
||||
For i=1 To n
|
||||
Print line(i)
|
||||
Print #f, line(i)#Fold$(ArrayToString)
|
||||
Next
|
||||
Print TimeCount
|
||||
Refresh
|
||||
Next
|
||||
close #f
|
||||
Flush ' empty stack again
|
||||
End
|
||||
Sub ResetColumns()
|
||||
Local i
|
||||
For i=1 To n:line(i)=(,):Next
|
||||
End Sub
|
||||
Sub newColumn()
|
||||
Local i
|
||||
For i=1 To n : Push i: Next
|
||||
End Sub
|
||||
Sub shuffle()
|
||||
Local i
|
||||
For i=1 To n div 2: Shift Random(2, n): Next
|
||||
End Sub
|
||||
Sub shuffleLocal(x)
|
||||
If Stack.size<=x Then Exit Sub
|
||||
Shift Random(x+1, Stack.size)
|
||||
Shiftback x
|
||||
End Sub
|
||||
Sub PlaceColumn()
|
||||
Local i, a, b, k
|
||||
shuffle()
|
||||
Do
|
||||
data number ' rotate one position
|
||||
k=0
|
||||
For i=1 To n
|
||||
a=line(i) ' get the pointer
|
||||
Do
|
||||
If a#Pos(Stackitem(i))=-1 Then k=0 :Exit Do
|
||||
shuffleLocal(i)
|
||||
k++
|
||||
Until k>Stack.size-i
|
||||
If k>0 Then Exit For
|
||||
Next
|
||||
Until k=0
|
||||
For i=1 To n
|
||||
a=line(i)
|
||||
Append a, (Stackitem(i),)
|
||||
Next
|
||||
End Sub
|
||||
}
|
||||
Form 100,50
|
||||
LatinSquare 5, 2, True
|
||||
LatinSquare 16
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Clear[RandomLatinSquare]
|
||||
RandomLatinSquare[n_] := Module[{out, ord},
|
||||
out = Table[RotateLeft[Range[n], i], {i, n}];
|
||||
out = RandomSample[out];
|
||||
ord = RandomSample[Range[n]];
|
||||
out = out[[All, ord]];
|
||||
out
|
||||
]
|
||||
RandomLatinSquare[5] // Grid
|
||||
44
Task/Random-Latin-squares/Nim/random-latin-squares.nim
Normal file
44
Task/Random-Latin-squares/Nim/random-latin-squares.nim
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import random, sequtils, strutils
|
||||
|
||||
type LatinSquare = seq[seq[char]]
|
||||
|
||||
proc get[T](s: set[T]): T =
|
||||
## Return the first element of a set.
|
||||
for n in s:
|
||||
return n
|
||||
|
||||
proc letterAt(n: Natural): char {.inline.} = chr(ord('A') - 1 + n)
|
||||
|
||||
|
||||
proc latinSquare(n: Positive): LatinSquare =
|
||||
result = newSeqWith(n, toSeq(letterAt(1)..letterAt(n)))
|
||||
result[0].shuffle()
|
||||
|
||||
for row in 1..(n - 2):
|
||||
var ok = false
|
||||
while not ok:
|
||||
block shuffling:
|
||||
result[row].shuffle()
|
||||
for prev in 0..<row:
|
||||
for col in 0..<n:
|
||||
if result[row][col] == result[prev][col]:
|
||||
break shuffling
|
||||
ok = true
|
||||
|
||||
for col in 0..<n:
|
||||
var s = {letterAt(1)..letterAt(n)}
|
||||
for row in 0..(n - 2):
|
||||
s.excl result[row][col]
|
||||
result[^1][col] = s.get()
|
||||
|
||||
|
||||
proc `$`(s: LatinSquare): string =
|
||||
let n = s.len
|
||||
for row in 0..<n:
|
||||
result.add s[row].join(" ") & '\n'
|
||||
|
||||
|
||||
randomize()
|
||||
echo latinSquare(5)
|
||||
echo latinSquare(5)
|
||||
echo latinSquare(10)
|
||||
138
Task/Random-Latin-squares/Pascal/random-latin-squares.pas
Normal file
138
Task/Random-Latin-squares/Pascal/random-latin-squares.pas
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
{$APPTYPE CONSOLE}
|
||||
|
||||
const
|
||||
Alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
|
||||
Type
|
||||
IncidenceCube = Array of Array Of Array of Integer;
|
||||
|
||||
Var
|
||||
Cube : IncidenceCube;
|
||||
DIM : Integer;
|
||||
|
||||
|
||||
Procedure InitIncidenceCube(Var c:IncidenceCube; const Size:Integer);
|
||||
var i, j, k : integer;
|
||||
begin
|
||||
DIM := Size;
|
||||
SetLength(c,DIM,DIM,DIM);
|
||||
for i := 0 to DIM-1 do
|
||||
for j := 0 to DIM-1 do
|
||||
for k := 0 to DIM-1 do c[i,j,k] := 0 ;
|
||||
|
||||
for i := 0 to DIM-1 do
|
||||
for j := 0 to DIM-1 do c[i,j,(i+j) mod DIM] := 1;
|
||||
end;
|
||||
|
||||
|
||||
Procedure FreeIncidenceCube(Var c:IncidenceCube);
|
||||
begin
|
||||
Finalize(c);
|
||||
end;
|
||||
|
||||
|
||||
procedure PrintIncidenceCube(var c:IncidenceCube);
|
||||
var i, j, k : integer;
|
||||
begin
|
||||
for i := 0 to DIM-1 do begin
|
||||
for j := 0 to DIM-1 do begin
|
||||
for k := 0 to DIM-1 do begin
|
||||
if (c[i,j,k]=1) then begin
|
||||
write(Alpha[k+1],' ');
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Writeln;
|
||||
end;
|
||||
Writeln;
|
||||
WriteLn;
|
||||
end;
|
||||
|
||||
|
||||
procedure ShuffleIncidenceCube(var c:IncidenceCube);
|
||||
var i, j, rx, ry, rz, ox, oy, oz : integer;
|
||||
begin
|
||||
|
||||
for i := 0 to (DIM*DIM*DIM)-1 do begin
|
||||
|
||||
repeat
|
||||
rx := Random(DIM);
|
||||
ry := Random(DIM);
|
||||
rz := Random(DIM);
|
||||
until (c[rx,ry,rz]=0);
|
||||
|
||||
for j := 0 to DIM-1 do begin
|
||||
if (c[j,ry,rz]=1) then ox := j;
|
||||
if (c[rx,j,rz]=1) then oy := j;
|
||||
if (c[rx,ry,j]=1) then oz := j;
|
||||
end;
|
||||
|
||||
Inc(c[rx,ry,rz]);
|
||||
Inc(c[rx,oy,oz]);
|
||||
Inc(c[ox,ry,oz]);
|
||||
Inc(c[ox,oy,rz]);
|
||||
|
||||
Dec(c[rx,ry,oz]);
|
||||
Dec(c[rx,oy,rz]);
|
||||
Dec(c[ox,ry,rz]);
|
||||
Dec(c[ox,oy,oz]);
|
||||
|
||||
while (c[ox,oy,oz] < 0) do begin
|
||||
|
||||
rx := ox ;
|
||||
ry := oy ;
|
||||
rz := oz ;
|
||||
|
||||
if (random(2)=0) then begin
|
||||
for j := 0 to DIM-1 do begin
|
||||
if (c[j,ry,rz]=1) then ox := j;
|
||||
end;
|
||||
end else begin
|
||||
for j := DIM-1 downto 0 do begin
|
||||
if (c[j,ry,rz]=1) then ox := j;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (random(2)=0) then begin
|
||||
for j := 0 to DIM-1 do begin
|
||||
if (c[rx,j,rz]=1) then oy := j;
|
||||
end;
|
||||
end else begin
|
||||
for j := DIM-1 downto 0 do begin
|
||||
if (c[rx,j,rz]=1) then oy := j;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (random(2)=0) then begin
|
||||
for j := 0 to DIM-1 do begin
|
||||
if (c[rx,ry,j]=1) then oz := j;
|
||||
end;
|
||||
end else begin
|
||||
for j := DIM-1 downto 0 do begin
|
||||
if (c[rx,ry,j]=1) then oz := j;
|
||||
end;
|
||||
end;
|
||||
|
||||
Inc(c[rx,ry,rz]);
|
||||
Inc(c[rx,oy,oz]);
|
||||
Inc(c[ox,ry,oz]);
|
||||
Inc(c[ox,oy,rz]);
|
||||
|
||||
Dec(c[rx,ry,oz]);
|
||||
Dec(c[rx,oy,rz]);
|
||||
Dec(c[ox,ry,rz]);
|
||||
Dec(c[ox,oy,oz]);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Randomize;
|
||||
InitIncidenceCube(cube, 5); ShuffleIncidenceCube(cube); PrintIncidenceCube(cube); FreeIncidenceCube(Cube);
|
||||
InitIncidenceCube(cube, 5); ShuffleIncidenceCube(cube); PrintIncidenceCube(cube); FreeIncidenceCube(Cube);
|
||||
InitIncidenceCube(cube,10); ShuffleIncidenceCube(cube); PrintIncidenceCube(cube); FreeIncidenceCube(Cube);
|
||||
InitIncidenceCube(cube,26); ShuffleIncidenceCube(cube); PrintIncidenceCube(cube); FreeIncidenceCube(Cube);
|
||||
end.
|
||||
33
Task/Random-Latin-squares/Perl/random-latin-squares.pl
Normal file
33
Task/Random-Latin-squares/Perl/random-latin-squares.pl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
use List::Util 'shuffle';
|
||||
|
||||
sub random_ls {
|
||||
my($n) = @_;
|
||||
my(@cols,@symbols,@ls_sym);
|
||||
|
||||
# build n-sized latin square
|
||||
my @ls = [0,];
|
||||
for my $i (1..$n-1) {
|
||||
@{$ls[$i]} = @{$ls[0]};
|
||||
splice(@{$ls[$_]}, $_, 0, $i) for 0..$i;
|
||||
}
|
||||
|
||||
# shuffle rows and columns
|
||||
@cols = shuffle 0..$n-1;
|
||||
@ls = map [ @{$_}[@cols] ], @ls[shuffle 0..$n-1];
|
||||
|
||||
# replace numbers with symbols
|
||||
@symbols = shuffle( ('A'..'Z')[0..$n-1] );
|
||||
push @ls_sym, [@symbols[@$_]] for @ls;
|
||||
@ls_sym
|
||||
}
|
||||
|
||||
sub display {
|
||||
my $str;
|
||||
$str .= join(' ', @$_) . "\n" for @_;
|
||||
$str
|
||||
}
|
||||
|
||||
say display random_ls($_) for 2..5, 5;
|
||||
67
Task/Random-Latin-squares/Phix/random-latin-squares.phix
Normal file
67
Task/Random-Latin-squares/Phix/random-latin-squares.phix
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">aleph</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">ls</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">aleph</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- too big...</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- {1..n}</span>
|
||||
<span style="color: #000000;">vcs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- valid for cols</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">clashes</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">rn</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- next row</span>
|
||||
<span style="color: #000000;">vr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- valid for row (ie all)</span>
|
||||
<span style="color: #000000;">vc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vcs</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- copy (in case of clash)</span>
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">clash</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000080;font-style:italic;">-- collect all still valid options</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">vr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">and</span> <span style="color: #000000;">vc</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">k</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">clash</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">z</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">))]</span>
|
||||
<span style="color: #000000;">rn</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">z</span>
|
||||
<span style="color: #000000;">vr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">z</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- no longer valid</span>
|
||||
<span style="color: #000000;">vc</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">][</span><span style="color: #000000;">z</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- ""</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">clash</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rn</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">vcs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vc</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">clashes</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rows completed:%d/%d, clashes:%d\n"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">clashes</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">line</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">aleph</span><span style="color: #0000FF;">[</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">line</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">latin_square</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ls</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Latin square of order %d (%s):\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
<span style="color: #000000;">latin_square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">latin_square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">latin_square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">latin_square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">latin_square</span><span style="color: #0000FF;">(</span><span style="color: #000000;">42</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<!--
|
||||
36
Task/Random-Latin-squares/Picat/random-latin-squares-1.picat
Normal file
36
Task/Random-Latin-squares/Picat/random-latin-squares-1.picat
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
main =>
|
||||
_ = random2(), % random seed
|
||||
N = 5,
|
||||
foreach(_ in 1..2)
|
||||
latin_square(N, X),
|
||||
pretty_print(X)
|
||||
end,
|
||||
% A larger random instance
|
||||
latin_square(62,X),
|
||||
pretty_print(X).
|
||||
|
||||
% Latin square
|
||||
latin_square(N, X) =>
|
||||
X = new_array(N,N),
|
||||
X :: 1..N,
|
||||
foreach(I in 1..N)
|
||||
all_different([X[I,J] : J in 1..N]),
|
||||
all_different([X[J,I] : J in 1..N])
|
||||
end,
|
||||
% rand_val for randomness
|
||||
solve($[ff,rand_val],X).
|
||||
|
||||
pretty_print(X) =>
|
||||
N = X.len,
|
||||
Alpha = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
foreach(I in 1..N)
|
||||
foreach(J in 1..N)
|
||||
if N > 20 then
|
||||
printf("%w",Alpha[X[I,J]])
|
||||
else
|
||||
printf("%2w ",X[I,J])
|
||||
end
|
||||
end,
|
||||
nl
|
||||
end,
|
||||
nl.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
main =>
|
||||
foreach(N in 1..6)
|
||||
Count = count_all(latin_square(N,_)),
|
||||
println(N=Count)
|
||||
end.
|
||||
61
Task/Random-Latin-squares/Python/random-latin-squares.py
Normal file
61
Task/Random-Latin-squares/Python/random-latin-squares.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
from random import choice, shuffle
|
||||
from copy import deepcopy
|
||||
|
||||
def rls(n):
|
||||
if n <= 0:
|
||||
return []
|
||||
else:
|
||||
symbols = list(range(n))
|
||||
square = _rls(symbols)
|
||||
return _shuffle_transpose_shuffle(square)
|
||||
|
||||
|
||||
def _shuffle_transpose_shuffle(matrix):
|
||||
square = deepcopy(matrix)
|
||||
shuffle(square)
|
||||
trans = list(zip(*square))
|
||||
shuffle(trans)
|
||||
return trans
|
||||
|
||||
|
||||
def _rls(symbols):
|
||||
n = len(symbols)
|
||||
if n == 1:
|
||||
return [symbols]
|
||||
else:
|
||||
sym = choice(symbols)
|
||||
symbols.remove(sym)
|
||||
square = _rls(symbols)
|
||||
square.append(square[0].copy())
|
||||
for i in range(n):
|
||||
square[i].insert(i, sym)
|
||||
return square
|
||||
|
||||
def _to_text(square):
|
||||
if square:
|
||||
width = max(len(str(sym)) for row in square for sym in row)
|
||||
txt = '\n'.join(' '.join(f"{sym:>{width}}" for sym in row)
|
||||
for row in square)
|
||||
else:
|
||||
txt = ''
|
||||
return txt
|
||||
|
||||
def _check(square):
|
||||
transpose = list(zip(*square))
|
||||
assert _check_rows(square) and _check_rows(transpose), \
|
||||
"Not a Latin square"
|
||||
|
||||
def _check_rows(square):
|
||||
if not square:
|
||||
return True
|
||||
set_row0 = set(square[0])
|
||||
return all(len(row) == len(set(row)) and set(row) == set_row0
|
||||
for row in square)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for i in [3, 3, 5, 5, 12]:
|
||||
square = rls(i)
|
||||
print(_to_text(square))
|
||||
_check(square)
|
||||
print()
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
[ [] []
|
||||
rot times
|
||||
[ i join ]
|
||||
dup size times
|
||||
[ tuck
|
||||
nested join
|
||||
swap
|
||||
behead join ]
|
||||
drop
|
||||
shuffle
|
||||
transpose
|
||||
shuffle ] is rls ( n --> [ )
|
||||
|
||||
2 times
|
||||
[ 5 rls
|
||||
witheach
|
||||
[ witheach
|
||||
[ echo sp ]
|
||||
cr ]
|
||||
cr ]
|
||||
16
Task/Random-Latin-squares/REXX/random-latin-squares.rexx
Normal file
16
Task/Random-Latin-squares/REXX/random-latin-squares.rexx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/*REXX program generates and displays a randomized Latin square. */
|
||||
parse arg N seed . /*obtain the optional argument from CL.*/
|
||||
if N=='' | N=="," then N= 5 /*Not specified? Then use the default.*/
|
||||
if datatype(seed, 'W') then call random ,,seed /*Seed numeric? Then use it for seed.*/
|
||||
w= length(N - 1) /*get the length of the largest number.*/
|
||||
$= /*initialize $ string to null. */
|
||||
do i=0 for N; $= $ right(i, w, '_') /*build a string of numbers (from zero)*/
|
||||
end /*i*/ /* [↑] $ string is (so far) in order.*/
|
||||
z= /*Z: will be the 1st row of the square*/
|
||||
do N; ?= random(1,words($)) /*gen a random number from the $ string*/
|
||||
z= z word($, ?); $= delword($, ?, 1) /*add the number to string; del from $.*/
|
||||
end /*r*/
|
||||
zz= z||z /*build a double-length string of Z. */
|
||||
do j=1 for N /* [↓] display rows of random Latin sq*/
|
||||
say translate(subword(zz, j, N), , '_') /*translate leading underbar to blank. */
|
||||
end /*j*/ /*stick a fork in it, we're all done. */
|
||||
35
Task/Random-Latin-squares/Raku/random-latin-squares.raku
Normal file
35
Task/Random-Latin-squares/Raku/random-latin-squares.raku
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
sub latin-square { [[0],] };
|
||||
|
||||
sub random ( @ls, :$size = 5 ) {
|
||||
|
||||
# Build
|
||||
for 1 ..^ $size -> $i {
|
||||
@ls[$i] = @ls[0].clone;
|
||||
@ls[$_].splice($_, 0, $i) for 0 .. $i;
|
||||
}
|
||||
|
||||
# Shuffle
|
||||
@ls = @ls[^$size .pick(*)];
|
||||
my @cols = ^$size .pick(*);
|
||||
@ls[$_] = @ls[$_][@cols] for ^@ls;
|
||||
|
||||
# Some random Latin glyphs
|
||||
my @symbols = ('A' .. 'Z').pick($size);
|
||||
|
||||
@ls.deepmap: { $_ = @symbols[$_] };
|
||||
|
||||
}
|
||||
|
||||
sub display ( @array ) { $_.fmt("%2s ").put for |@array, '' }
|
||||
|
||||
|
||||
# The Task
|
||||
|
||||
# Default size 5
|
||||
display random latin-square;
|
||||
|
||||
# Specified size
|
||||
display random :size($_), latin-square for 5, 3, 9;
|
||||
|
||||
# Or, if you'd prefer:
|
||||
display random latin-square, :size($_) for 12, 2, 1;
|
||||
344
Task/Random-Latin-squares/Ring/random-latin-squares.ring
Normal file
344
Task/Random-Latin-squares/Ring/random-latin-squares.ring
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
load "stdlib.ring"
|
||||
load "guilib.ring"
|
||||
|
||||
###====================================================================================
|
||||
|
||||
size = 10
|
||||
|
||||
time1 = 0
|
||||
bwidth = 0
|
||||
bheight = 0
|
||||
|
||||
a2DSquare = newlist(size,size)
|
||||
a2DFinal = newlist(size,size)
|
||||
|
||||
aList = 1:size
|
||||
aList2 = RandomList(aList)
|
||||
|
||||
GenerateRows(aList2)
|
||||
ShuffleCols(a2DSquare, a2DFinal)
|
||||
|
||||
C_SPACING = 1
|
||||
Button = newlist(size,size)
|
||||
LayoutButtonRow = list(size)
|
||||
C_ButtonOrangeStyle = 'border-radius:1x;color:black; background-color: orange'
|
||||
|
||||
###====================================================================================
|
||||
|
||||
MyApp = New qApp {
|
||||
|
||||
StyleFusion()
|
||||
|
||||
win = new qWidget() {
|
||||
|
||||
workHeight = win.height()
|
||||
fontSize = 8 + (300/size)
|
||||
|
||||
wwidth = win.width()
|
||||
wheight = win.height()
|
||||
bwidth = wwidth/size
|
||||
bheight = wheight/size
|
||||
|
||||
setwindowtitle("Random Latin Squares")
|
||||
move(555,0)
|
||||
setfixedsize(1000,1000)
|
||||
|
||||
myfilter = new qallevents(win)
|
||||
myfilter.setResizeEvent("resizeBoard()")
|
||||
installeventfilter(myfilter)
|
||||
|
||||
LayoutButtonMain = new QVBoxLayout() {
|
||||
setSpacing(C_SPACING)
|
||||
setContentsmargins(50,50,50,50)
|
||||
}
|
||||
|
||||
LayoutButtonStart = new QHBoxLayout() {
|
||||
setSpacing(C_SPACING)
|
||||
setContentsmargins(0,0,0,0)
|
||||
}
|
||||
|
||||
btnStart = new qPushButton(win) {
|
||||
setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
resize(bwidth,bheight)
|
||||
settext(" Start ")
|
||||
setstylesheet(C_ButtonOrangeStyle)
|
||||
setclickevent("gameSolution()")
|
||||
}
|
||||
|
||||
sizeBtn = new qlabel(win)
|
||||
{
|
||||
setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
resize(bwidth,bheight)
|
||||
setStyleSheet("background-color:rgb(255,255,204)")
|
||||
setText(" Size: ")
|
||||
}
|
||||
|
||||
lineSize = new qLineEdit(win)
|
||||
{
|
||||
setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
resize(bwidth,bheight)
|
||||
setStyleSheet("background-color:rgb(255,255,204)")
|
||||
setAlignment( Qt_AlignHCenter)
|
||||
setAlignment( Qt_AlignVCenter)
|
||||
setreturnPressedEvent("newBoardSize()")
|
||||
setText(string(size))
|
||||
}
|
||||
|
||||
btnExit = new qPushButton(win) {
|
||||
setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
resize(bwidth,bheight)
|
||||
settext(" Exit ")
|
||||
setstylesheet(C_ButtonOrangeStyle)
|
||||
setclickevent("pExit()")
|
||||
}
|
||||
|
||||
LayoutButtonStart.AddWidget(btnStart)
|
||||
LayoutButtonStart.AddWidget(sizeBtn)
|
||||
LayoutButtonStart.AddWidget(lineSize)
|
||||
LayoutButtonStart.AddWidget(btnExit)
|
||||
|
||||
LayoutButtonMain.AddLayout(LayoutButtonStart)
|
||||
|
||||
for Row = 1 to size
|
||||
|
||||
LayoutButtonRow[Row] = new QHBoxLayout() {
|
||||
setSpacing(C_SPACING)
|
||||
setContentsmargins(0,0,0,0)
|
||||
}
|
||||
|
||||
for Col = 1 to size
|
||||
Button[Row][Col] = new qlabel(win) {
|
||||
setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
resize(bwidth,bheight)
|
||||
}
|
||||
LayoutButtonRow[Row].AddWidget(Button[Row][Col])
|
||||
next
|
||||
LayoutButtonMain.AddLayout(LayoutButtonRow[Row])
|
||||
|
||||
next
|
||||
|
||||
setLayout(LayoutButtonMain)
|
||||
|
||||
show()
|
||||
|
||||
}
|
||||
|
||||
exec()
|
||||
}
|
||||
|
||||
###====================================================================================
|
||||
|
||||
func newBoardSize()
|
||||
|
||||
nrSize = number(lineSize.text())
|
||||
|
||||
if nrSize = 1
|
||||
? "Enter: Size > 1"
|
||||
return
|
||||
ok
|
||||
|
||||
for Row = 1 to size
|
||||
for Col = 1 to size
|
||||
Button[Row][Col].settext("")
|
||||
next
|
||||
next
|
||||
|
||||
newWindow(nrSize)
|
||||
|
||||
###====================================================================================
|
||||
|
||||
func newWindow(newSize)
|
||||
|
||||
time1 = clock()
|
||||
|
||||
for Row = 1 to size
|
||||
for Col = 1 to size
|
||||
Button[Row][Col].delete()
|
||||
next
|
||||
next
|
||||
|
||||
size = newSize
|
||||
|
||||
bwidth = ceil((win.width() - 8) / size)
|
||||
bheight = ceil((win.height() - 32) / size)
|
||||
|
||||
fontSize = 8 + (300/size)
|
||||
|
||||
if size > 16
|
||||
fontSize = 8 + (150/size)
|
||||
ok
|
||||
|
||||
if size < 8
|
||||
fontSize = 30 + (150/size)
|
||||
ok
|
||||
|
||||
if size = 2
|
||||
fontSize = 10 + (100/size)
|
||||
ok
|
||||
|
||||
btnStart.setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
sizeBtn.setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
lineSize.setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
btnExit.setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
|
||||
LayoutButtonStart = new QHBoxLayout() {
|
||||
setSpacing(C_SPACING)
|
||||
setContentsmargins(0,0,0,0)
|
||||
}
|
||||
|
||||
Button = newlist(size,size)
|
||||
LayoutButtonRow = list(size)
|
||||
|
||||
for Row = 1 to size
|
||||
|
||||
LayoutButtonRow[Row] = new QHBoxLayout() {
|
||||
setSpacing(C_SPACING)
|
||||
setContentsmargins(0,0,0,0)
|
||||
}
|
||||
|
||||
for Col = 1 to size
|
||||
|
||||
Button[Row][Col] = new qlabel(win) {
|
||||
setFont(new qFont("Calibri",fontsize,2100,0))
|
||||
resize(bwidth,bheight)
|
||||
}
|
||||
LayoutButtonRow[Row].AddWidget(Button[Row][Col])
|
||||
|
||||
next
|
||||
|
||||
LayoutButtonMain.AddLayout(LayoutButtonRow[Row])
|
||||
|
||||
next
|
||||
|
||||
win.setLayout(LayoutButtonMain)
|
||||
|
||||
return
|
||||
|
||||
###====================================================================================
|
||||
|
||||
func resizeBoard
|
||||
|
||||
bwidth = ceil((win.width() - 8) / size)
|
||||
bheight = ceil((win.height() - 32) / size)
|
||||
|
||||
for Row = 1 to size
|
||||
for Col = 1 to size
|
||||
Button[Row][Col].resize(bwidth,bheight)
|
||||
next
|
||||
next
|
||||
|
||||
###====================================================================================
|
||||
|
||||
Func pExit
|
||||
|
||||
MyApp.quit()
|
||||
|
||||
###====================================================================================
|
||||
|
||||
func gameSolution()
|
||||
|
||||
a2DSquare = newlist(size,size)
|
||||
a2DFinal = newlist(size,size)
|
||||
|
||||
aList = 1:size
|
||||
aList2 = RandomList(aList)
|
||||
|
||||
GenerateRows(aList2)
|
||||
ShuffleCols(a2DSquare, a2DFinal)
|
||||
|
||||
for nRow = 1 to size
|
||||
for nCol = 1 to size
|
||||
Button[nRow][nCol].settext("-")
|
||||
next
|
||||
next
|
||||
|
||||
for nRow = 1 to size
|
||||
for nCol = 1 to size
|
||||
Button[nRow][nCol].resize(bwidth,bheight)
|
||||
Button[nRow][nCol].settext(string(a2DSquare[nRow][nCol]))
|
||||
next
|
||||
next
|
||||
|
||||
time2 = clock()
|
||||
time3 = (time2 - time1)/1000
|
||||
? "Elapsed time: " + time3 + " ms at size = " + size + nl
|
||||
|
||||
###====================================================================================
|
||||
|
||||
// Scramble the numbers in the List
|
||||
// Uniq random picks, then shorten list by each pick
|
||||
|
||||
Func RandomList(aInput)
|
||||
|
||||
aOutput = []
|
||||
|
||||
while len(aInput) > 1
|
||||
nIndex = random(len(aInput)-1)
|
||||
nIndex++
|
||||
|
||||
aOutput + aInput[nIndex]
|
||||
del(aInput,nIndex)
|
||||
end
|
||||
|
||||
aOutput + aInput[1]
|
||||
|
||||
return aOutput
|
||||
|
||||
###====================================================================================
|
||||
// Generate Rows of data. Put them in the 2DArray
|
||||
|
||||
Func GenerateRows(aInput)
|
||||
|
||||
aOutput = []
|
||||
size = len(aInput)
|
||||
shift = 1
|
||||
|
||||
for k = 1 to size // Make 8 Rows of lists
|
||||
aOutput = []
|
||||
|
||||
for i = 1 to size // make a list
|
||||
pick = i + shift // shift every Row by +1 more
|
||||
if pick > size pick = pick - size ok
|
||||
|
||||
aOutput + aInput[pick]
|
||||
next
|
||||
|
||||
a2DSquare[k] = aOutput // Row of Output to a2DSquare
|
||||
|
||||
shift++ // shift next line by +1 more
|
||||
if shift > size shift = 1 ok
|
||||
next
|
||||
|
||||
return
|
||||
|
||||
###====================================================================================
|
||||
// Shift random Rows into a2DFinal, then random Cols
|
||||
|
||||
Func ShuffleCols(a2DSquare, a2DFinal)
|
||||
|
||||
aSuffle = 1:size
|
||||
aSuffle2 = RandomList(aSuffle) // Pick random Col to insert in a2DFinal
|
||||
|
||||
for i = 1 to size // Row
|
||||
pick = aSuffle2[i]
|
||||
|
||||
for j = 1 to size // Col
|
||||
a2DFinal[i][j] = a2DSquare[pick][j] // i-Row-Col j-Horz-Vert
|
||||
next
|
||||
next
|
||||
|
||||
a2DSquare = a2DFinal // Now do the verticals
|
||||
aSuffle = 1:size
|
||||
aSuffle2 = RandomList(aSuffle)
|
||||
|
||||
for i = 1 to size // Row
|
||||
pick = aSuffle2[i]
|
||||
|
||||
for j = 1 to size // Col
|
||||
a2DFinal[j][i] = a2DSquare[j][pick] //Reverse i-j , i-Row-Col j-Horz-Vert
|
||||
next
|
||||
next
|
||||
|
||||
return
|
||||
|
||||
###====================================================================================
|
||||
19
Task/Random-Latin-squares/Ruby/random-latin-squares.rb
Normal file
19
Task/Random-Latin-squares/Ruby/random-latin-squares.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
N = 5
|
||||
|
||||
def generate_square
|
||||
perms = (1..N).to_a.permutation(N).to_a.shuffle
|
||||
square = []
|
||||
N.times do
|
||||
square << perms.pop
|
||||
perms.reject!{|perm| perm.zip(square.last).any?{|el1, el2| el1 == el2} }
|
||||
end
|
||||
square
|
||||
end
|
||||
|
||||
def print_square(square)
|
||||
cell_size = N.digits.size + 1
|
||||
strings = square.map!{|row| row.map!{|el| el.to_s.rjust(cell_size)}.join }
|
||||
puts strings, "\n"
|
||||
end
|
||||
|
||||
2.times{print_square( generate_square)}
|
||||
60
Task/Random-Latin-squares/Wren/random-latin-squares-1.wren
Normal file
60
Task/Random-Latin-squares/Wren/random-latin-squares-1.wren
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import "random" for Random
|
||||
|
||||
var rand = Random.new()
|
||||
|
||||
var printSquare = Fn.new { |latin|
|
||||
for (row in latin) System.print(row)
|
||||
System.print()
|
||||
}
|
||||
|
||||
var latinSquare = Fn.new { |n|
|
||||
if (n <= 0) {
|
||||
System.print("[]\n")
|
||||
return
|
||||
}
|
||||
var latin = List.filled(n, null)
|
||||
for (i in 0...n) {
|
||||
latin[i] = List.filled(n, 0)
|
||||
if (i == n - 1) break
|
||||
for (j in 0...n) latin[i][j] = j
|
||||
}
|
||||
|
||||
// first row
|
||||
rand.shuffle(latin[0])
|
||||
|
||||
// middle row(s)
|
||||
for (i in 1...n-1) {
|
||||
var shuffled = false
|
||||
while (!shuffled) {
|
||||
rand.shuffle(latin[i])
|
||||
var shuffling = false
|
||||
for (k in 0...i) {
|
||||
for (j in 0...n) {
|
||||
if (latin[k][j] == latin[i][j]) {
|
||||
shuffling = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (shuffling) break
|
||||
}
|
||||
if (!shuffling) shuffled = true
|
||||
}
|
||||
}
|
||||
|
||||
// last row
|
||||
for (j in 0...n) {
|
||||
var used = List.filled(n, false)
|
||||
for (i in 0...n-1) used[latin[i][j]] = true
|
||||
for (k in 0...n) {
|
||||
if (!used[k]) {
|
||||
latin[n-1][j] = k
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
printSquare.call(latin)
|
||||
}
|
||||
|
||||
latinSquare.call(5)
|
||||
latinSquare.call(5)
|
||||
latinSquare.call(10) // for good measure
|
||||
216
Task/Random-Latin-squares/Wren/random-latin-squares-2.wren
Normal file
216
Task/Random-Latin-squares/Wren/random-latin-squares-2.wren
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
import "random" for Random
|
||||
import "/sort" for Sort
|
||||
import "/fmt" for Fmt
|
||||
import "/math" for Int
|
||||
|
||||
var rand = Random.new()
|
||||
var counts = List.filled(4, 0)
|
||||
var aa = List.filled(16, 0)
|
||||
|
||||
var testSquares = [
|
||||
[0, 1, 2, 3, 1, 0, 3, 2, 2, 3, 0, 1, 3, 2, 1, 0],
|
||||
[0, 1, 2, 3, 1, 0, 3, 2, 2, 3, 1, 0, 3, 2, 0, 1],
|
||||
[0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2],
|
||||
[0, 1, 2, 3, 1, 3, 0, 2, 2, 0, 3, 1, 3, 2, 1, 0]
|
||||
]
|
||||
|
||||
// Checks whether two lists contain the same elements in the same order
|
||||
var areSame = Fn.new { |l1, l2|
|
||||
if (l1.count != l2.count) return false
|
||||
for (i in 0...l1.count) {
|
||||
if (l1[i] != l2[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// generate derangements of first n numbers, with 'start' in first place.
|
||||
var dList = Fn.new { |n, start|
|
||||
var r = []
|
||||
start = start - 1 // use 0 basing
|
||||
var a = List.filled(n, 0)
|
||||
for (i in 0...n) a[i] = i
|
||||
var t = a[0]
|
||||
a[0] = start
|
||||
a[start] = t
|
||||
Sort.quick(a, 1, a.count-1, null)
|
||||
var first = a[1]
|
||||
var recurse // recursive closure permutes a[1..-1]
|
||||
recurse = Fn.new { |last|
|
||||
if (last == first) {
|
||||
// bottom of recursion. you get here once for each permutation.
|
||||
// test if permutation is deranged.
|
||||
var j = 0 // j starts from 0, not 1
|
||||
for (v in a.skip(1)) {
|
||||
if (j+1 == v) return r // no, ignore it
|
||||
j = j + 1
|
||||
}
|
||||
// yes, save a copy
|
||||
var b = a.toList
|
||||
for (i in 0...b.count) b[i] = b[i] + 1 // change back to 1 basing
|
||||
r.add(b)
|
||||
return r
|
||||
}
|
||||
var i = last
|
||||
while (i >= 1) {
|
||||
a.swap(i, last)
|
||||
recurse.call(last - 1)
|
||||
a.swap(i, last)
|
||||
i = i - 1
|
||||
}
|
||||
}
|
||||
recurse.call(n - 1)
|
||||
return r
|
||||
}
|
||||
|
||||
var copyMatrix = Fn.new { |m|
|
||||
var le = m.count
|
||||
var cpy = List.filled(le, null)
|
||||
for (i in 0...le) cpy[i] = m[i].toList
|
||||
return cpy
|
||||
}
|
||||
|
||||
var reducedLatinSquares = Fn.new { |n|
|
||||
var rls = []
|
||||
if (n < 0) n = 0
|
||||
var rlatin = List.filled(n, null)
|
||||
for (i in 0...n) rlatin[i] = List.filled(n, 0)
|
||||
if (n <= 1) {
|
||||
rls.add(rlatin)
|
||||
return rls
|
||||
}
|
||||
|
||||
// first row
|
||||
for (j in 0...n) rlatin[0][j] = j + 1
|
||||
|
||||
// recursive closure to compute reduced latin squares
|
||||
var recurse
|
||||
recurse = Fn.new { |i|
|
||||
var rows = dList.call(n, i) // get derangements of first n numbers, with 'i' first.
|
||||
for (r in 0...rows.count) {
|
||||
var outer = false
|
||||
rlatin[i-1] = rows[r].toList
|
||||
for (k in 0...i-1) {
|
||||
for (j in 1...n) {
|
||||
if (rlatin[k][j] == rlatin[i-1][j]) {
|
||||
if (r < rows.count-1) {
|
||||
outer = true
|
||||
break
|
||||
} else if (i > 2) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outer) break
|
||||
}
|
||||
if (outer) continue
|
||||
if (i < n) {
|
||||
recurse.call(i + 1)
|
||||
} else {
|
||||
var rl = copyMatrix.call(rlatin)
|
||||
rls.add(rl)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// remaining rows
|
||||
recurse.call(2)
|
||||
return rls
|
||||
}
|
||||
|
||||
var printSquare = Fn.new { |latin, n|
|
||||
for (i in 0...n) {
|
||||
for (j in 0...n) Fmt.write("$d ", latin[i][j]-1)
|
||||
System.print()
|
||||
}
|
||||
System.print()
|
||||
}
|
||||
|
||||
// generate permutations of first n numbers, starting from 0.
|
||||
var pList = Fn.new { |n|
|
||||
var fact = Int.factorial(n)
|
||||
var perms = List.filled(fact, null)
|
||||
var a = List.filled(n, 0)
|
||||
for (i in 0...n) a[i] = i
|
||||
var t = a.toList
|
||||
perms[0] = t
|
||||
n = n - 1
|
||||
for (c in 1...fact) {
|
||||
var i = n - 1
|
||||
var j = n
|
||||
while (a[i] > a[i+1]) i = i - 1
|
||||
while (a[j] < a[i]) j = j - 1
|
||||
a.swap(i, j)
|
||||
j = n
|
||||
i = i + 1
|
||||
while (i < j) {
|
||||
a.swap(i, j)
|
||||
i = i + 1
|
||||
j = j - 1
|
||||
}
|
||||
var t = a.toList
|
||||
t.add(0)
|
||||
perms[c] = t
|
||||
}
|
||||
return perms
|
||||
}
|
||||
|
||||
var generateLatinSquares = Fn.new { |n, tests, echo|
|
||||
var rls = reducedLatinSquares.call(n)
|
||||
var perms = pList.call(n)
|
||||
var perms2 = pList.call(n - 1)
|
||||
for (test in 0...tests) {
|
||||
var rn = rand.int(rls.count)
|
||||
var rl = rls[rn] // select reduced random square at random
|
||||
rn = rand.int(perms.count)
|
||||
var rp = perms[rn] // select a random permuation of 'rl's columns
|
||||
// permute columns
|
||||
var t = List.filled(n, null)
|
||||
for (i in 0...n) {
|
||||
t[i] = List.filled(n, 0)
|
||||
for (j in 0...n) t[i][j] = rl[i][rp[j]]
|
||||
}
|
||||
rn = rand.int(perms2.count)
|
||||
rp = perms2[rn] // select a random permutation of 't's rows 2 to n
|
||||
// permute rows 2 to n
|
||||
var u = List.filled(n, null)
|
||||
for (i in 0...n) {
|
||||
u[i] = List.filled(n, 0)
|
||||
for (j in 0...n) {
|
||||
if (i == 0) {
|
||||
u[i][j] = t[i][j]
|
||||
} else {
|
||||
u[i][j] = t[rp[i-1]+1][j]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (test < echo) printSquare.call(u, n)
|
||||
if (n == 4) {
|
||||
for (i in 0..3) {
|
||||
for (j in 0..3) u[i][j] = u[i][j] - 1
|
||||
}
|
||||
for (i in 0..3) {
|
||||
for (j in 4*i...4*i+4) {
|
||||
aa[j] = u[i][j - 4*i]
|
||||
}
|
||||
}
|
||||
for (i in 0..3) {
|
||||
if (areSame.call(testSquares[i], aa)) {
|
||||
counts[i] = counts[i] + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.print("Two randomly generated latin squares of order 5 are:\n")
|
||||
generateLatinSquares.call(5, 2, 2)
|
||||
|
||||
System.print("Out of 1,000,000 randomly generated latin squares of order 4, ")
|
||||
System.print("of which there are 576 instances ( => expected 1736 per instance),")
|
||||
System.print("the following squares occurred the number of times shown:\n")
|
||||
generateLatinSquares.call(4, 1e6, 0)
|
||||
for (i in 0..3) System.print("%(testSquares[i]) : %(counts[i])")
|
||||
System.print("\nA randomly generated latin square of order 6 is:\n")
|
||||
generateLatinSquares.call(6, 1, 1)
|
||||
8
Task/Random-Latin-squares/Zkl/random-latin-squares-1.zkl
Normal file
8
Task/Random-Latin-squares/Zkl/random-latin-squares-1.zkl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fcn randomLatinSquare(n,symbols=[1..]){ //--> list of lists
|
||||
if(n<=0) return(T);
|
||||
square,syms := List(), symbols.walker().walk(n);
|
||||
do(n){ syms=syms.copy(); square.append(syms.append(syms.pop(0))) }
|
||||
// shuffle rows, transpose & shuffle columns
|
||||
T.zip(square.shuffle().xplode()).shuffle();
|
||||
}
|
||||
fcn rls2String(square){ square.apply("concat"," ").concat("\n") }
|
||||
3
Task/Random-Latin-squares/Zkl/random-latin-squares-2.zkl
Normal file
3
Task/Random-Latin-squares/Zkl/random-latin-squares-2.zkl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
foreach n in (T(1,2,5)){ randomLatinSquare(n) : rls2String(_).println("\n") }
|
||||
randomLatinSquare(5, ["A".."Z"]) : rls2String(_).println("\n");
|
||||
randomLatinSquare(10,"!@#$%^&*()") : rls2String(_).println("\n");
|
||||
Loading…
Add table
Add a link
Reference in a new issue